The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

288 lines
9.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. BEGIN_JUCE_NAMESPACE
  19. //==============================================================================
  20. FileBasedDocument::FileBasedDocument (const String& fileExtension_,
  21. const String& fileWildcard_,
  22. const String& openFileDialogTitle_,
  23. const String& saveFileDialogTitle_)
  24. : changedSinceSave (false),
  25. fileExtension (fileExtension_),
  26. fileWildcard (fileWildcard_),
  27. openFileDialogTitle (openFileDialogTitle_),
  28. saveFileDialogTitle (saveFileDialogTitle_)
  29. {
  30. }
  31. FileBasedDocument::~FileBasedDocument()
  32. {
  33. }
  34. //==============================================================================
  35. void FileBasedDocument::setChangedFlag (const bool hasChanged)
  36. {
  37. if (changedSinceSave != hasChanged)
  38. {
  39. changedSinceSave = hasChanged;
  40. sendChangeMessage();
  41. }
  42. }
  43. void FileBasedDocument::changed()
  44. {
  45. changedSinceSave = true;
  46. sendChangeMessage();
  47. }
  48. //==============================================================================
  49. void FileBasedDocument::setFile (const File& newFile)
  50. {
  51. if (documentFile != newFile)
  52. {
  53. documentFile = newFile;
  54. changed();
  55. }
  56. }
  57. //==============================================================================
  58. #if JUCE_MODAL_LOOPS_PERMITTED
  59. bool FileBasedDocument::loadFrom (const File& newFile,
  60. const bool showMessageOnFailure)
  61. {
  62. MouseCursor::showWaitCursor();
  63. const File oldFile (documentFile);
  64. documentFile = newFile;
  65. String error;
  66. if (newFile.existsAsFile())
  67. {
  68. error = loadDocument (newFile);
  69. if (error.isEmpty())
  70. {
  71. setChangedFlag (false);
  72. MouseCursor::hideWaitCursor();
  73. setLastDocumentOpened (newFile);
  74. return true;
  75. }
  76. }
  77. else
  78. {
  79. error = "The file doesn't exist";
  80. }
  81. documentFile = oldFile;
  82. MouseCursor::hideWaitCursor();
  83. if (showMessageOnFailure)
  84. {
  85. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  86. TRANS("Failed to open file..."),
  87. TRANS("There was an error while trying to load the file:\n\n")
  88. + newFile.getFullPathName()
  89. + "\n\n"
  90. + error);
  91. }
  92. return false;
  93. }
  94. bool FileBasedDocument::loadFromUserSpecifiedFile (const bool showMessageOnFailure)
  95. {
  96. FileChooser fc (openFileDialogTitle,
  97. getLastDocumentOpened(),
  98. fileWildcard);
  99. if (fc.browseForFileToOpen())
  100. return loadFrom (fc.getResult(), showMessageOnFailure);
  101. return false;
  102. }
  103. //==============================================================================
  104. FileBasedDocument::SaveResult FileBasedDocument::save (const bool askUserForFileIfNotSpecified,
  105. const bool showMessageOnFailure)
  106. {
  107. return saveAs (documentFile,
  108. false,
  109. askUserForFileIfNotSpecified,
  110. showMessageOnFailure);
  111. }
  112. FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile,
  113. const bool warnAboutOverwritingExistingFiles,
  114. const bool askUserForFileIfNotSpecified,
  115. const bool showMessageOnFailure)
  116. {
  117. if (newFile == File::nonexistent)
  118. {
  119. if (askUserForFileIfNotSpecified)
  120. {
  121. return saveAsInteractive (true);
  122. }
  123. else
  124. {
  125. // can't save to an unspecified file
  126. jassertfalse;
  127. return failedToWriteToFile;
  128. }
  129. }
  130. if (warnAboutOverwritingExistingFiles && newFile.exists())
  131. {
  132. if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon,
  133. TRANS("File already exists"),
  134. TRANS("There's already a file called:\n\n")
  135. + newFile.getFullPathName()
  136. + TRANS("\n\nAre you sure you want to overwrite it?"),
  137. TRANS("overwrite"),
  138. TRANS("cancel")))
  139. {
  140. return userCancelledSave;
  141. }
  142. }
  143. MouseCursor::showWaitCursor();
  144. const File oldFile (documentFile);
  145. documentFile = newFile;
  146. String error (saveDocument (newFile));
  147. if (error.isEmpty())
  148. {
  149. setChangedFlag (false);
  150. MouseCursor::hideWaitCursor();
  151. return savedOk;
  152. }
  153. documentFile = oldFile;
  154. MouseCursor::hideWaitCursor();
  155. if (showMessageOnFailure)
  156. {
  157. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  158. TRANS("Error writing to file..."),
  159. TRANS("An error occurred while trying to save \"")
  160. + getDocumentTitle()
  161. + TRANS("\" to the file:\n\n")
  162. + newFile.getFullPathName()
  163. + "\n\n"
  164. + error);
  165. }
  166. return failedToWriteToFile;
  167. }
  168. FileBasedDocument::SaveResult FileBasedDocument::saveIfNeededAndUserAgrees()
  169. {
  170. if (! hasChangedSinceSaved())
  171. return savedOk;
  172. const int r = AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon,
  173. TRANS("Closing document..."),
  174. TRANS("Do you want to save the changes to \"")
  175. + getDocumentTitle() + "\"?",
  176. TRANS("save"),
  177. TRANS("discard changes"),
  178. TRANS("cancel"));
  179. if (r == 1)
  180. {
  181. // save changes
  182. return save (true, true);
  183. }
  184. else if (r == 2)
  185. {
  186. // discard changes
  187. return savedOk;
  188. }
  189. return userCancelledSave;
  190. }
  191. FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool warnAboutOverwritingExistingFiles)
  192. {
  193. File f;
  194. if (documentFile.existsAsFile())
  195. f = documentFile;
  196. else
  197. f = getLastDocumentOpened();
  198. String legalFilename (File::createLegalFileName (getDocumentTitle()));
  199. if (legalFilename.isEmpty())
  200. legalFilename = "unnamed";
  201. if (f.existsAsFile() || f.getParentDirectory().isDirectory())
  202. f = f.getSiblingFile (legalFilename);
  203. else
  204. f = File::getSpecialLocation (File::userDocumentsDirectory).getChildFile (legalFilename);
  205. f = f.withFileExtension (fileExtension)
  206. .getNonexistentSibling (true);
  207. FileChooser fc (saveFileDialogTitle, f, fileWildcard);
  208. if (fc.browseForFileToSave (warnAboutOverwritingExistingFiles))
  209. {
  210. File chosen (fc.getResult());
  211. if (chosen.getFileExtension().isEmpty())
  212. {
  213. chosen = chosen.withFileExtension (fileExtension);
  214. if (chosen.exists())
  215. {
  216. if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon,
  217. TRANS("File already exists"),
  218. TRANS("There's already a file called:")
  219. + "\n\n" + chosen.getFullPathName()
  220. + "\n\n" + TRANS("Are you sure you want to overwrite it?"),
  221. TRANS("overwrite"),
  222. TRANS("cancel")))
  223. {
  224. return userCancelledSave;
  225. }
  226. }
  227. }
  228. setLastDocumentOpened (chosen);
  229. return saveAs (chosen, false, false, true);
  230. }
  231. return userCancelledSave;
  232. }
  233. #endif
  234. END_JUCE_NAMESPACE