Pārlūkot izejas kodu

Rewrote and refactored file/project saving and closing in PolycodeIDEApp. Rewrote removeEditor() due to undesirable behavior regarding modal dialogs.

I took a more general approach to closing and saving an arbitrary list of files/editors
Ethan M 12 gadi atpakaļ
vecāks
revīzija
f4f3ab3d41

+ 12 - 3
IDE/Contents/Include/PolycodeIDEApp.h

@@ -90,7 +90,7 @@ public:
 	void exportProject();
 	void toggleConsole();
 	
-	bool removeEditor(PolycodeEditor *editor);
+	void removeEditor(PolycodeEditor *editor);
 	
 	// system callbacks
 	
@@ -103,7 +103,12 @@ public:
 	
 	const static int EVENT_SHOW_MENU = 1;
 	
-	Core *core;	
+	Core *core;
+	
+	void saveFiles(std::vector<PolycodeEditor*> editors);
+	void closeFiles(std::vector<PolycodeEditor*> editors, String saveMsg="");
+	bool filesHaveChanges(std::vector<PolycodeEditor*> editors);
+	
 protected:
 
 	bool runNextFrame;
@@ -119,5 +124,9 @@ protected:
 	UIMenuBar *menuBar;
 	
 private:
-	void cleanupProjectOnClose(bool save);
+	void doCloseProject();
+	void doCloseFiles(std::vector<PolycodeEditor*> editors);
+	
+	// used in saving/closing files via popup dialog prompts
+	std::vector<PolycodeEditor*> tempEditorStore;
 };

+ 89 - 43
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -238,64 +238,78 @@ void PolycodeIDEApp::refreshProject() {
 	}
 }
 
-bool PolycodeIDEApp::removeEditor(PolycodeEditor *editor) {
-	if(!editor)
-		return false;
-		
-	if(editor->hasChanges()) {
-		OSFileEntry entry(editor->getFilePath(), OSFileEntry::TYPE_FILE);	
-		frame->yesNoCancelPopup->setCaption("The file \""+entry.name+"\" has unsaved changes. Save before closing?");
-		frame->yesNoCancelPopup->action = "closeFile";
-		frame->showModal(frame->yesNoCancelPopup);
-		return true;
-	} else {	
-		frame->removeEditor(editor);
-		editorManager->destroyEditor(editor);
-		if(editorManager->openEditors.size() > 0) {
-			editorManager->setCurrentEditor(editorManager->openEditors[0]);
-			frame->showEditor(editorManager->openEditors[0]);
-		}
+// check if associated file has changes before invoking this
+void PolycodeIDEApp::removeEditor(PolycodeEditor *editor) {
+	if (!editor)
+		return;
+	
+	frame->removeEditor(editor);
+	editorManager->destroyEditor(editor);
+	if(editorManager->openEditors.size() > 0) {
+		editorManager->setCurrentEditor(editorManager->openEditors[0]);
+		frame->showEditor(editorManager->openEditors[0]);
+	} else {
+		editorManager->setCurrentEditor(NULL);
 	}
-	return false;
 }
 
 void PolycodeIDEApp::closeFile() {
+	// this will save the file if it has changes and/or close it (in closeFiles())
 	PolycodeEditor *editor = editorManager->getCurrentEditor();
-	if(editor) {
-		removeEditor(editor);
+	if (editor) {
+		std::vector<PolycodeEditor*> editorToSave;
+		editorToSave.push_back(editor);
+		OSFileEntry entry(editor->getFilePath(), OSFileEntry::TYPE_FILE);
+		closeFiles(editorToSave, "'"+entry.name+"' has unsaved changes. Save?");
+	}
+}
+
+void PolycodeIDEApp::closeFiles(std::vector<PolycodeEditor*> editors, String saveMsg) {
+	if (filesHaveChanges(editors)) {
+		if (saveMsg == "")
+			saveMsg = "File(s) have unsaved changes. Save all?";
+		tempEditorStore = editors;
+		frame->yesNoCancelPopup->setCaption(saveMsg);
+		frame->yesNoCancelPopup->action = "closeFiles";
+		frame->showModal(frame->yesNoCancelPopup);
+	} else
+		doCloseFiles(editors);
+}
+
+void PolycodeIDEApp::doCloseFiles(std::vector<PolycodeEditor*> editors) {
+	for (int i=0; i < editors.size(); i++) {
+		if (editors[i])
+			removeEditor(editors[i]);
 	}
 }
 
 void PolycodeIDEApp::closeProject() {
 	if(projectManager->getActiveProject()) {
-		if (editorManager->hasUnsavedFilesForProject(projectManager->getActiveProject())) {
+		std::vector<PolycodeEditor*> editors;
+		PolycodeEditor *editor;
+		bool hasChanges = false;
+		for (int i=0; i < editorManager->openEditors.size(); i++) {
+			editor = editorManager->openEditors[i];
+			if (editor->hasChanges())
+				hasChanges = true;
+			if (editor->parentProject == projectManager->getActiveProject())
+				editors.push_back(editor);
+		}
+		tempEditorStore = editors; // current project files
+		if (hasChanges) {
 			String name = projectManager->getActiveProject()->getProjectName();
 			frame->yesNoCancelPopup->setCaption("Project '" + name + "' has unsaved changes. Save all?");
 			frame->yesNoCancelPopup->action = "closeProject";
 			frame->showModal(frame->yesNoCancelPopup);
 		} else
-			cleanupProjectOnClose(false);
+			doCloseProject();
 	} else
-		PolycodeConsole::print("There are no active projects to close.");
+		PolycodeConsole::print("There are no active projects to close.\n");
 }
 
-// private function that removes editors and projects on project close
-void PolycodeIDEApp::cleanupProjectOnClose(bool save) {
-	PolycodeEditor *editor;
-	int i = 0;
-	while (i < editorManager->openEditors.size()) {
-		editor = editorManager->openEditors[i];
-		if(editor->parentProject == projectManager->getActiveProject()) {
-			if (save && editor->hasChanges())
-				editor->saveFile();
-			else
-				editor->setHasChanges(false);
-			
-			removeEditor(editor);
-			i--; // adjust for reduction in openEditors.size()
-		}
-		i++;
-	}
+// private helper function that removes editors and project on project close.
+void PolycodeIDEApp::doCloseProject() {
+	doCloseFiles(tempEditorStore);
 	frame->getProjectBrowser()->removeProject(projectManager->getActiveProject());
 	projectManager->removeProject(projectManager->getActiveProject());
 }
@@ -412,6 +426,21 @@ void PolycodeIDEApp::saveFile() {
 	}
 }
 
+void PolycodeIDEApp::saveFiles(std::vector<PolycodeEditor*> editors) {
+	for (int i=0; i < editors.size(); i++) {
+		if (editors[i]->hasChanges())
+			editors[i]->saveFile();
+	}
+}
+
+bool PolycodeIDEApp::filesHaveChanges(std::vector<PolycodeEditor*> editors) {
+	for (int i=0; i < editors.size(); i++) {
+		if (editors[i]->hasChanges())
+			return true;
+	}
+	return false;
+}
+
 void PolycodeIDEApp::openProject(String projectFile) {
 	projectManager->openProject(projectFile);
 }
@@ -662,13 +691,30 @@ void PolycodeIDEApp::handleEvent(Event *event) {
 			}
 		}
 		
-		if (frame->yesNoCancelPopup->action == "closeProject") {
+		else if (frame->yesNoCancelPopup->action == "closeProject") {
+			switch (event->getEventCode()) {
+				case UIEvent::YES_EVENT:
+					saveFiles(tempEditorStore);
+					doCloseProject();
+					break;
+				case UIEvent::NO_EVENT:
+					doCloseProject();
+					break;
+				case UIEvent::CANCEL_EVENT:
+					break;
+			}
+			frame->yesNoCancelPopup->action = "";
+			frame->hideModal();
+		}
+		
+		else if (frame->yesNoCancelPopup->action == "closeFiles") {
 			switch (event->getEventCode()) {
 				case UIEvent::YES_EVENT:
-					cleanupProjectOnClose(true);
+					saveFiles(tempEditorStore);
+					doCloseFiles(tempEditorStore);
 					break;
 				case UIEvent::NO_EVENT:
-					cleanupProjectOnClose(false);
+					doCloseFiles(tempEditorStore);
 					break;
 				case UIEvent::CANCEL_EVENT:
 					break;