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.

287 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. FileBasedDocument::FileBasedDocument (const String& fileExtension_,
  19. const String& fileWildcard_,
  20. const String& openFileDialogTitle_,
  21. const String& saveFileDialogTitle_)
  22. : changedSinceSave (false),
  23. fileExtension (fileExtension_),
  24. fileWildcard (fileWildcard_),
  25. openFileDialogTitle (openFileDialogTitle_),
  26. saveFileDialogTitle (saveFileDialogTitle_)
  27. {
  28. }
  29. FileBasedDocument::~FileBasedDocument()
  30. {
  31. }
  32. //==============================================================================
  33. void FileBasedDocument::setChangedFlag (const bool hasChanged)
  34. {
  35. if (changedSinceSave != hasChanged)
  36. {
  37. changedSinceSave = hasChanged;
  38. sendChangeMessage();
  39. }
  40. }
  41. void FileBasedDocument::changed()
  42. {
  43. changedSinceSave = true;
  44. sendChangeMessage();
  45. }
  46. //==============================================================================
  47. void FileBasedDocument::setFile (const File& newFile)
  48. {
  49. if (documentFile != newFile)
  50. {
  51. documentFile = newFile;
  52. changed();
  53. }
  54. }
  55. //==============================================================================
  56. #if JUCE_MODAL_LOOPS_PERMITTED
  57. bool FileBasedDocument::loadFrom (const File& newFile,
  58. const bool showMessageOnFailure)
  59. {
  60. MouseCursor::showWaitCursor();
  61. const File oldFile (documentFile);
  62. documentFile = newFile;
  63. String error;
  64. if (newFile.existsAsFile())
  65. {
  66. error = loadDocument (newFile);
  67. if (error.isEmpty())
  68. {
  69. setChangedFlag (false);
  70. MouseCursor::hideWaitCursor();
  71. setLastDocumentOpened (newFile);
  72. return true;
  73. }
  74. }
  75. else
  76. {
  77. error = "The file doesn't exist";
  78. }
  79. documentFile = oldFile;
  80. MouseCursor::hideWaitCursor();
  81. if (showMessageOnFailure)
  82. {
  83. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  84. TRANS("Failed to open file..."),
  85. TRANS("There was an error while trying to load the file:\n\n")
  86. + newFile.getFullPathName()
  87. + "\n\n"
  88. + error);
  89. }
  90. return false;
  91. }
  92. bool FileBasedDocument::loadFromUserSpecifiedFile (const bool showMessageOnFailure)
  93. {
  94. FileChooser fc (openFileDialogTitle,
  95. getLastDocumentOpened(),
  96. fileWildcard);
  97. if (fc.browseForFileToOpen())
  98. return loadFrom (fc.getResult(), showMessageOnFailure);
  99. return false;
  100. }
  101. //==============================================================================
  102. FileBasedDocument::SaveResult FileBasedDocument::save (const bool askUserForFileIfNotSpecified,
  103. const bool showMessageOnFailure)
  104. {
  105. return saveAs (documentFile,
  106. false,
  107. askUserForFileIfNotSpecified,
  108. showMessageOnFailure);
  109. }
  110. FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile,
  111. const bool warnAboutOverwritingExistingFiles,
  112. const bool askUserForFileIfNotSpecified,
  113. const bool showMessageOnFailure)
  114. {
  115. if (newFile == File::nonexistent)
  116. {
  117. if (askUserForFileIfNotSpecified)
  118. {
  119. return saveAsInteractive (true);
  120. }
  121. else
  122. {
  123. // can't save to an unspecified file
  124. jassertfalse;
  125. return failedToWriteToFile;
  126. }
  127. }
  128. if (warnAboutOverwritingExistingFiles && newFile.exists())
  129. {
  130. if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon,
  131. TRANS("File already exists"),
  132. TRANS("There's already a file called:\n\n")
  133. + newFile.getFullPathName()
  134. + TRANS("\n\nAre you sure you want to overwrite it?"),
  135. TRANS("overwrite"),
  136. TRANS("cancel")))
  137. {
  138. return userCancelledSave;
  139. }
  140. }
  141. MouseCursor::showWaitCursor();
  142. const File oldFile (documentFile);
  143. documentFile = newFile;
  144. String error (saveDocument (newFile));
  145. if (error.isEmpty())
  146. {
  147. setChangedFlag (false);
  148. MouseCursor::hideWaitCursor();
  149. return savedOk;
  150. }
  151. documentFile = oldFile;
  152. MouseCursor::hideWaitCursor();
  153. if (showMessageOnFailure)
  154. {
  155. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  156. TRANS("Error writing to file..."),
  157. TRANS("An error occurred while trying to save \"")
  158. + getDocumentTitle()
  159. + TRANS("\" to the file:\n\n")
  160. + newFile.getFullPathName()
  161. + "\n\n"
  162. + error);
  163. }
  164. return failedToWriteToFile;
  165. }
  166. FileBasedDocument::SaveResult FileBasedDocument::saveIfNeededAndUserAgrees()
  167. {
  168. if (! hasChangedSinceSaved())
  169. return savedOk;
  170. const int r = AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon,
  171. TRANS("Closing document..."),
  172. TRANS("Do you want to save the changes to \"")
  173. + getDocumentTitle() + "\"?",
  174. TRANS("save"),
  175. TRANS("discard changes"),
  176. TRANS("cancel"));
  177. if (r == 1)
  178. {
  179. // save changes
  180. return save (true, true);
  181. }
  182. else if (r == 2)
  183. {
  184. // discard changes
  185. return savedOk;
  186. }
  187. return userCancelledSave;
  188. }
  189. File FileBasedDocument::getSuggestedSaveAsFile (const File& defaultFile)
  190. {
  191. return defaultFile.withFileExtension (fileExtension).getNonexistentSibling (true);
  192. }
  193. FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool warnAboutOverwritingExistingFiles)
  194. {
  195. File f;
  196. if (documentFile.existsAsFile())
  197. f = documentFile;
  198. else
  199. f = getLastDocumentOpened();
  200. String legalFilename (File::createLegalFileName (getDocumentTitle()));
  201. if (legalFilename.isEmpty())
  202. legalFilename = "unnamed";
  203. if (f.existsAsFile() || f.getParentDirectory().isDirectory())
  204. f = f.getSiblingFile (legalFilename);
  205. else
  206. f = File::getSpecialLocation (File::userDocumentsDirectory).getChildFile (legalFilename);
  207. f = getSuggestedSaveAsFile (f);
  208. FileChooser fc (saveFileDialogTitle, f, fileWildcard);
  209. if (fc.browseForFileToSave (warnAboutOverwritingExistingFiles))
  210. {
  211. File chosen (fc.getResult());
  212. if (chosen.getFileExtension().isEmpty())
  213. {
  214. chosen = chosen.withFileExtension (fileExtension);
  215. if (chosen.exists())
  216. {
  217. if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon,
  218. TRANS("File already exists"),
  219. TRANS("There's already a file called:")
  220. + "\n\n" + chosen.getFullPathName()
  221. + "\n\n" + TRANS("Are you sure you want to overwrite it?"),
  222. TRANS("overwrite"),
  223. TRANS("cancel")))
  224. {
  225. return userCancelledSave;
  226. }
  227. }
  228. }
  229. setLastDocumentOpened (chosen);
  230. return saveAs (chosen, false, false, true);
  231. }
  232. return userCancelledSave;
  233. }
  234. #endif