@@ -250,6 +250,7 @@ public: | |||||
menu.addSeparator(); | menu.addSeparator(); | ||||
menu.addCommandItem (commandManager, CommandIDs::closeDocument); | menu.addCommandItem (commandManager, CommandIDs::closeDocument); | ||||
menu.addCommandItem (commandManager, CommandIDs::saveDocument); | menu.addCommandItem (commandManager, CommandIDs::saveDocument); | ||||
menu.addCommandItem (commandManager, CommandIDs::saveDocumentAs); | |||||
menu.addSeparator(); | menu.addSeparator(); | ||||
menu.addCommandItem (commandManager, CommandIDs::closeProject); | menu.addCommandItem (commandManager, CommandIDs::closeProject); | ||||
menu.addCommandItem (commandManager, CommandIDs::saveProject); | menu.addCommandItem (commandManager, CommandIDs::saveProject); | ||||
@@ -34,6 +34,7 @@ namespace CommandIDs | |||||
open = 0x200020, | open = 0x200020, | ||||
closeDocument = 0x200030, | closeDocument = 0x200030, | ||||
saveDocument = 0x200040, | saveDocument = 0x200040, | ||||
saveDocumentAs = 0x200041, | |||||
closeProject = 0x200051, | closeProject = 0x200051, | ||||
saveProject = 0x200060, | saveProject = 0x200060, | ||||
@@ -54,6 +54,7 @@ public: | |||||
Project* getProject() const { return project; } | Project* getProject() const { return project; } | ||||
bool needsSaving() const { return false; } | bool needsSaving() const { return false; } | ||||
bool save() { return true; } | bool save() { return true; } | ||||
bool saveAs() { return false; } | |||||
bool hasFileBeenModifiedExternally() { return fileModificationTime != file.getLastModificationTime(); } | bool hasFileBeenModifiedExternally() { return fileModificationTime != file.getLastModificationTime(); } | ||||
void reloadFromFile() { fileModificationTime = file.getLastModificationTime(); } | void reloadFromFile() { fileModificationTime = file.getLastModificationTime(); } | ||||
String getName() const { return file.getFileName(); } | String getName() const { return file.getFileName(); } | ||||
@@ -55,6 +55,7 @@ public: | |||||
virtual File getFile() const = 0; | virtual File getFile() const = 0; | ||||
virtual bool needsSaving() const = 0; | virtual bool needsSaving() const = 0; | ||||
virtual bool save() = 0; | virtual bool save() = 0; | ||||
virtual bool saveAs() = 0; | |||||
virtual bool hasFileBeenModifiedExternally() = 0; | virtual bool hasFileBeenModifiedExternally() = 0; | ||||
virtual void reloadFromFile() = 0; | virtual void reloadFromFile() = 0; | ||||
virtual Component* createEditor() = 0; | virtual Component* createEditor() = 0; | ||||
@@ -63,27 +63,44 @@ void SourceCodeDocument::reloadInternal() | |||||
{ | { | ||||
jassert (codeDoc != nullptr); | jassert (codeDoc != nullptr); | ||||
modDetector.updateHash(); | modDetector.updateHash(); | ||||
codeDoc->applyChanges (modDetector.getFile().loadFileAsString()); | |||||
codeDoc->applyChanges (getFile().loadFileAsString()); | |||||
codeDoc->setSavePoint(); | codeDoc->setSavePoint(); | ||||
} | } | ||||
bool SourceCodeDocument::save() | |||||
static bool writeCodeDocToFile (const File& file, CodeDocument& doc) | |||||
{ | { | ||||
TemporaryFile temp (modDetector.getFile()); | |||||
TemporaryFile temp (file); | |||||
{ | { | ||||
FileOutputStream fo (temp.getFile()); | FileOutputStream fo (temp.getFile()); | ||||
if (! (fo.openedOk() && getCodeDocument().writeToStream (fo))) | |||||
if (! (fo.openedOk() && doc.writeToStream (fo))) | |||||
return false; | return false; | ||||
} | } | ||||
if (! temp.overwriteTargetFileWithTemporary()) | |||||
return false; | |||||
return temp.overwriteTargetFileWithTemporary(); | |||||
} | |||||
getCodeDocument().setSavePoint(); | |||||
modDetector.updateHash(); | |||||
return true; | |||||
bool SourceCodeDocument::save() | |||||
{ | |||||
if (writeCodeDocToFile (getFile(), getCodeDocument())) | |||||
{ | |||||
getCodeDocument().setSavePoint(); | |||||
modDetector.updateHash(); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
bool SourceCodeDocument::saveAs() | |||||
{ | |||||
FileChooser fc (TRANS("Save As..."), getFile(), "*"); | |||||
if (! fc.browseForFileToSave (true)) | |||||
return true; | |||||
return writeCodeDocToFile (fc.getResult(), getCodeDocument()); | |||||
} | } | ||||
void SourceCodeDocument::updateLastState (CodeEditorComponent& editor) | void SourceCodeDocument::updateLastState (CodeEditorComponent& editor) | ||||
@@ -59,7 +59,8 @@ public: | |||||
const char* extensions[] = { "h", "hpp", nullptr }; | const char* extensions[] = { "h", "hpp", nullptr }; | ||||
return findCounterpart (file, extensions); | return findCounterpart (file, extensions); | ||||
} | } | ||||
else if (file.hasFileExtension ("h;hpp")) | |||||
if (file.hasFileExtension ("h;hpp")) | |||||
{ | { | ||||
const char* extensions[] = { "cpp", "mm", "cc", "cxx", "c", "m", nullptr }; | const char* extensions[] = { "cpp", "mm", "cc", "cxx", "c", "m", nullptr }; | ||||
return findCounterpart (file, extensions); | return findCounterpart (file, extensions); | ||||
@@ -83,6 +84,7 @@ public: | |||||
void reloadFromFile(); | void reloadFromFile(); | ||||
bool save(); | bool save(); | ||||
bool saveAs(); | |||||
Component* createEditor(); | Component* createEditor(); | ||||
Component* createViewer() { return createEditor(); } | Component* createViewer() { return createEditor(); } | ||||
@@ -419,15 +419,20 @@ void ProjectContentComponent::closeDocument() | |||||
hideEditor(); | hideEditor(); | ||||
} | } | ||||
static void showSaveWarning (OpenDocumentManager::Document* currentDocument) | |||||
{ | |||||
AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||||
TRANS("Save failed!"), | |||||
TRANS("Couldn't save the file:") | |||||
+ "\n" + currentDocument->getFile().getFullPathName()); | |||||
} | |||||
void ProjectContentComponent::saveDocument() | void ProjectContentComponent::saveDocument() | ||||
{ | { | ||||
if (currentDocument != nullptr) | if (currentDocument != nullptr) | ||||
{ | { | ||||
if (! currentDocument->save()) | if (! currentDocument->save()) | ||||
AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||||
TRANS("Save failed!"), | |||||
TRANS("Couldn't save the file:") | |||||
+ "\n" + currentDocument->getFile().getFullPathName()); | |||||
showSaveWarning (currentDocument); | |||||
} | } | ||||
else | else | ||||
saveProject(); | saveProject(); | ||||
@@ -435,6 +440,12 @@ void ProjectContentComponent::saveDocument() | |||||
updateMainWindowTitle(); | updateMainWindowTitle(); | ||||
} | } | ||||
void ProjectContentComponent::saveAs() | |||||
{ | |||||
if (currentDocument != nullptr && ! currentDocument->saveAs()) | |||||
showSaveWarning (currentDocument); | |||||
} | |||||
bool ProjectContentComponent::goToPreviousFile() | bool ProjectContentComponent::goToPreviousFile() | ||||
{ | { | ||||
OpenDocumentManager::Document* doc = recentDocumentList.getCurrentDocument(); | OpenDocumentManager::Document* doc = recentDocumentList.getCurrentDocument(); | ||||
@@ -544,6 +555,7 @@ ApplicationCommandTarget* ProjectContentComponent::getNextCommandTarget() | |||||
void ProjectContentComponent::getAllCommands (Array <CommandID>& commands) | void ProjectContentComponent::getAllCommands (Array <CommandID>& commands) | ||||
{ | { | ||||
const CommandID ids[] = { CommandIDs::saveDocument, | const CommandID ids[] = { CommandIDs::saveDocument, | ||||
CommandIDs::saveDocumentAs, | |||||
CommandIDs::closeDocument, | CommandIDs::closeDocument, | ||||
CommandIDs::saveProject, | CommandIDs::saveProject, | ||||
CommandIDs::closeProject, | CommandIDs::closeProject, | ||||
@@ -595,6 +607,14 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica | |||||
result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier, 0)); | result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier, 0)); | ||||
break; | break; | ||||
case CommandIDs::saveDocumentAs: | |||||
result.setInfo ("Save As...", | |||||
"Saves the current document to a new location", | |||||
CommandCategories::general, 0); | |||||
result.setActive (currentDocument != nullptr || project != nullptr); | |||||
result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)); | |||||
break; | |||||
case CommandIDs::closeDocument: | case CommandIDs::closeDocument: | ||||
result.setInfo ("Close" + documentName, | result.setInfo ("Close" + documentName, | ||||
"Closes the current document", | "Closes the current document", | ||||
@@ -688,6 +708,7 @@ bool ProjectContentComponent::perform (const InvocationInfo& info) | |||||
case CommandIDs::saveProject: | case CommandIDs::saveProject: | ||||
case CommandIDs::closeProject: | case CommandIDs::closeProject: | ||||
case CommandIDs::saveDocument: | case CommandIDs::saveDocument: | ||||
case CommandIDs::saveDocumentAs: | |||||
case CommandIDs::closeDocument: | case CommandIDs::closeDocument: | ||||
case CommandIDs::goToPreviousDoc: | case CommandIDs::goToPreviousDoc: | ||||
case CommandIDs::goToNextDoc: | case CommandIDs::goToNextDoc: | ||||
@@ -710,6 +731,7 @@ bool ProjectContentComponent::perform (const InvocationInfo& info) | |||||
case CommandIDs::saveProject: saveProject(); break; | case CommandIDs::saveProject: saveProject(); break; | ||||
case CommandIDs::closeProject: closeProject(); break; | case CommandIDs::closeProject: closeProject(); break; | ||||
case CommandIDs::saveDocument: saveDocument(); break; | case CommandIDs::saveDocument: saveDocument(); break; | ||||
case CommandIDs::saveDocumentAs: saveAs(); break; | |||||
case CommandIDs::closeDocument: closeDocument(); break; | case CommandIDs::closeDocument: closeDocument(); break; | ||||
case CommandIDs::goToPreviousDoc: goToPreviousFile(); break; | case CommandIDs::goToPreviousDoc: goToPreviousFile(); break; | ||||
@@ -58,6 +58,7 @@ public: | |||||
OpenDocumentManager::Document* getCurrentDocument() const { return currentDocument; } | OpenDocumentManager::Document* getCurrentDocument() const { return currentDocument; } | ||||
void closeDocument(); | void closeDocument(); | ||||
void saveDocument(); | void saveDocument(); | ||||
void saveAs(); | |||||
void hideEditor(); | void hideEditor(); | ||||
bool setEditorComponent (Component* editor, OpenDocumentManager::Document* doc); | bool setEditorComponent (Component* editor, OpenDocumentManager::Document* doc); | ||||
@@ -137,15 +137,11 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile, | |||||
if (newFile == File::nonexistent) | if (newFile == File::nonexistent) | ||||
{ | { | ||||
if (askUserForFileIfNotSpecified) | if (askUserForFileIfNotSpecified) | ||||
{ | |||||
return saveAsInteractive (true); | return saveAsInteractive (true); | ||||
} | |||||
else | |||||
{ | |||||
// can't save to an unspecified file | |||||
jassertfalse; | |||||
return failedToWriteToFile; | |||||
} | |||||
// can't save to an unspecified file | |||||
jassertfalse; | |||||
return failedToWriteToFile; | |||||
} | } | ||||
if (warnAboutOverwritingExistingFiles && newFile.exists()) | if (warnAboutOverwritingExistingFiles && newFile.exists()) | ||||
@@ -208,16 +204,11 @@ FileBasedDocument::SaveResult FileBasedDocument::saveIfNeededAndUserAgrees() | |||||
TRANS("discard changes"), | TRANS("discard changes"), | ||||
TRANS("cancel")); | TRANS("cancel")); | ||||
if (r == 1) | |||||
{ | |||||
// save changes | |||||
if (r == 1) // save changes | |||||
return save (true, true); | return save (true, true); | ||||
} | |||||
else if (r == 2) | |||||
{ | |||||
// discard changes | |||||
if (r == 2) // discard changes | |||||
return savedOk; | return savedOk; | ||||
} | |||||
return userCancelledSave; | return userCancelledSave; | ||||
} | } | ||||