Add TAL-Reverb-II plugin to test
[juce-lv2.git] / juce / source / extras / Introjucer / Source / Application / jucer_OpenDocumentManager.cpp
blob18469a0d858ac6bc83c0534a405c2383e0b56a8e
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-10 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "jucer_OpenDocumentManager.h"
27 #include "jucer_FilePreviewComponent.h"
28 #include "../Code Editor/jucer_SourceCodeEditor.h"
31 //==============================================================================
32 class SourceCodeDocument : public OpenDocumentManager::Document
34 public:
35 //==============================================================================
36 SourceCodeDocument (const File& file_)
37 : modDetector (file_)
39 codeDoc = new CodeDocument();
40 reloadFromFile();
43 ~SourceCodeDocument()
47 //==============================================================================
48 class Type : public OpenDocumentManager::DocumentType
50 public:
51 Type() {}
52 ~Type() {}
54 bool canOpenFile (const File& file) { return SourceCodeEditor::isTextFile (file); }
55 Document* openFile (Project*, const File& file) { return new SourceCodeDocument (file); }
58 //==============================================================================
59 bool loadedOk() const { return true; }
60 bool isForFile (const File& file) const { return modDetector.getFile() == file; }
61 bool isForNode (const ValueTree& node) const { return false; }
62 bool refersToProject (Project& project) const { return false; }
63 const String getName() const { return modDetector.getFile().getFileName(); }
64 const String getType() const { return modDetector.getFile().getFileExtension() + " file"; }
65 bool needsSaving() const { return codeDoc != nullptr && codeDoc->hasChangedSinceSavePoint(); }
66 bool hasFileBeenModifiedExternally() { return modDetector.hasBeenModified(); }
67 void fileHasBeenRenamed (const File& newFile) { modDetector.fileHasBeenRenamed (newFile); }
69 void reloadFromFile()
71 modDetector.updateHash();
73 ScopedPointer <InputStream> in (modDetector.getFile().createInputStream());
75 if (in != nullptr)
76 codeDoc->loadFromStream (*in);
79 bool save()
81 TemporaryFile temp (modDetector.getFile());
82 ScopedPointer <FileOutputStream> out (temp.getFile().createOutputStream());
84 if (out == nullptr || ! codeDoc->writeToStream (*out))
85 return false;
87 out = nullptr;
88 if (! temp.overwriteTargetFileWithTemporary())
89 return false;
91 modDetector.updateHash();
92 return true;
95 Component* createEditor()
97 CodeTokeniser* tokeniser = nullptr;
99 if (SourceCodeEditor::isCppFile (modDetector.getFile()))
100 tokeniser = &cppTokeniser;
102 return new SourceCodeEditor (this, *codeDoc, tokeniser);
105 Component* createViewer() { return createEditor(); }
107 private:
108 FileModificationDetector modDetector;
109 ScopedPointer <CodeDocument> codeDoc;
110 CPlusPlusCodeTokeniser cppTokeniser;
113 //==============================================================================
114 class UnknownDocument : public OpenDocumentManager::Document
116 public:
117 UnknownDocument (Project* project_, const File& file_)
118 : project (project_), file (file_)
120 reloadFromFile();
123 ~UnknownDocument() {}
125 //==============================================================================
126 class Type : public OpenDocumentManager::DocumentType
128 public:
129 Type() {}
130 ~Type() {}
132 bool canOpenFile (const File& file) { return true; }
133 Document* openFile (Project* project, const File& file) { return new UnknownDocument (project, file); }
136 //==============================================================================
137 bool loadedOk() const { return true; }
138 bool isForFile (const File& file_) const { return file == file_; }
139 bool isForNode (const ValueTree& node_) const { return false; }
140 bool refersToProject (Project& p) const { return project == &p; }
141 bool needsSaving() const { return false; }
142 bool save() { return true; }
143 bool hasFileBeenModifiedExternally() { return fileModificationTime != file.getLastModificationTime(); }
144 void reloadFromFile() { fileModificationTime = file.getLastModificationTime(); }
145 const String getName() const { return file.getFileName(); }
146 Component* createEditor() { return new ItemPreviewComponent (file); }
147 Component* createViewer() { return createEditor(); }
148 void fileHasBeenRenamed (const File& newFile) { file = newFile; }
150 const String getType() const
152 if (file.getFileExtension().isNotEmpty())
153 return file.getFileExtension() + " file";
155 jassertfalse
156 return "Unknown";
159 private:
160 Project* const project;
161 File file;
162 Time fileModificationTime;
164 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnknownDocument);
168 //==============================================================================
169 OpenDocumentManager::OpenDocumentManager()
171 registerType (new UnknownDocument::Type());
172 registerType (new SourceCodeDocument::Type());
175 OpenDocumentManager::~OpenDocumentManager()
177 clearSingletonInstance();
180 juce_ImplementSingleton_SingleThreaded (OpenDocumentManager);
182 //==============================================================================
183 void OpenDocumentManager::registerType (DocumentType* type)
185 types.add (type);
188 //==============================================================================
189 void OpenDocumentManager::addListener (DocumentCloseListener* listener)
191 listeners.addIfNotAlreadyThere (listener);
194 void OpenDocumentManager::removeListener (DocumentCloseListener* listener)
196 listeners.removeValue (listener);
199 //==============================================================================
200 bool OpenDocumentManager::canOpenFile (const File& file)
202 for (int i = types.size(); --i >= 0;)
203 if (types.getUnchecked(i)->canOpenFile (file))
204 return true;
206 return false;
209 OpenDocumentManager::Document* OpenDocumentManager::getDocumentForFile (Project* project, const File& file)
211 for (int i = documents.size(); --i >= 0;)
212 if (documents.getUnchecked(i)->isForFile (file))
213 return documents.getUnchecked(i);
215 Document* d = nullptr;
217 for (int i = types.size(); --i >= 0 && d == nullptr;)
219 if (types.getUnchecked(i)->canOpenFile (file))
221 d = types.getUnchecked(i)->openFile (project, file);
222 jassert (d != nullptr);
226 jassert (d != nullptr);
228 if (d != nullptr)
229 documents.add (d);
231 commandManager->commandStatusChanged();
232 return d;
235 int OpenDocumentManager::getNumOpenDocuments() const
237 return documents.size();
240 OpenDocumentManager::Document* OpenDocumentManager::getOpenDocument (int index) const
242 return documents.getUnchecked (index);
245 void OpenDocumentManager::moveDocumentToTopOfStack (Document* doc)
247 for (int i = documents.size(); --i >= 0;)
249 if (doc == documents.getUnchecked(i))
251 documents.move (i, 0);
252 commandManager->commandStatusChanged();
253 break;
258 FileBasedDocument::SaveResult OpenDocumentManager::saveIfNeededAndUserAgrees (OpenDocumentManager::Document* doc)
260 if (! doc->needsSaving())
261 return FileBasedDocument::savedOk;
263 const int r = AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon,
264 TRANS("Closing document..."),
265 TRANS("Do you want to save the changes to \"")
266 + doc->getName() + "\"?",
267 TRANS("save"),
268 TRANS("discard changes"),
269 TRANS("cancel"));
271 if (r == 1)
273 // save changes
274 return doc->save() ? FileBasedDocument::savedOk
275 : FileBasedDocument::failedToWriteToFile;
277 else if (r == 2)
279 // discard changes
280 return FileBasedDocument::savedOk;
283 return FileBasedDocument::userCancelledSave;
287 bool OpenDocumentManager::closeDocument (int index, bool saveIfNeeded)
289 Document* doc = documents [index];
291 if (doc != nullptr)
293 if (saveIfNeeded)
295 if (saveIfNeededAndUserAgrees (doc) != FileBasedDocument::savedOk)
296 return false;
299 for (int i = listeners.size(); --i >= 0;)
300 listeners.getUnchecked(i)->documentAboutToClose (doc);
302 documents.remove (index);
303 commandManager->commandStatusChanged();
306 return true;
309 bool OpenDocumentManager::closeDocument (Document* document, bool saveIfNeeded)
311 return closeDocument (documents.indexOf (document), saveIfNeeded);
314 void OpenDocumentManager::closeFile (const File& f, bool saveIfNeeded)
316 for (int i = documents.size(); --i >= 0;)
318 Document* d = documents.getUnchecked (i);
320 if (d->isForFile (f))
321 closeDocument (i, saveIfNeeded);
325 bool OpenDocumentManager::closeAllDocumentsUsingProject (Project& project, bool saveIfNeeded)
327 for (int i = documents.size(); --i >= 0;)
329 Document* d = documents.getUnchecked (i);
331 if (d->refersToProject (project))
333 if (! closeDocument (i, saveIfNeeded))
334 return false;
338 return true;
341 bool OpenDocumentManager::anyFilesNeedSaving() const
343 for (int i = documents.size(); --i >= 0;)
345 Document* d = documents.getUnchecked (i);
347 if (d->needsSaving())
348 return true;
351 return false;
354 bool OpenDocumentManager::saveAll()
356 for (int i = documents.size(); --i >= 0;)
358 Document* d = documents.getUnchecked (i);
360 if (! d->save())
361 return false;
364 return true;
367 void OpenDocumentManager::reloadModifiedFiles()
369 for (int i = documents.size(); --i >= 0;)
371 Document* d = documents.getUnchecked (i);
373 if (d->hasFileBeenModifiedExternally())
374 d->reloadFromFile();
378 void OpenDocumentManager::fileHasBeenRenamed (const File& oldFile, const File& newFile)
380 for (int i = documents.size(); --i >= 0;)
382 Document* d = documents.getUnchecked (i);
384 if (d->isForFile (oldFile))
385 d->fileHasBeenRenamed (newFile);