Ask the user to locate imported files if they cannot be loaded.

pull/4/head
whitequark 2016-01-11 12:18:18 +00:00
parent 54d8957bfe
commit 28a6e04f33
6 changed files with 165 additions and 45 deletions

View File

@ -791,7 +791,7 @@ bool SolveSpace::GetSaveFile(std::string &file, const std::string &defExtension,
}
}
int SolveSpace::SaveFileYesNoCancel(void) {
SolveSpace::DialogChoice SolveSpace::SaveFileYesNoCancel(void) {
NSAlert *alert = [[NSAlert alloc] init];
if(!std::string(SolveSpace::SS.saveFile).empty()) {
[alert setMessageText:
@ -809,16 +809,16 @@ int SolveSpace::SaveFileYesNoCancel(void) {
[alert addButtonWithTitle:@"Don't Save"];
switch([alert runModal]) {
case NSAlertFirstButtonReturn:
return SAVE_YES;
return DIALOG_YES;
case NSAlertSecondButtonReturn:
return SAVE_CANCEL;
default:
return DIALOG_CANCEL;
case NSAlertThirdButtonReturn:
return SAVE_NO;
return DIALOG_NO;
}
abort(); /* unreachable */
}
int SolveSpace::LoadAutosaveYesNo(void) {
SolveSpace::DialogChoice SolveSpace::LoadAutosaveYesNo(void) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:
@"An autosave file is availible for this project."];
@ -828,11 +828,37 @@ int SolveSpace::LoadAutosaveYesNo(void) {
[alert addButtonWithTitle:@"Don't Load"];
switch([alert runModal]) {
case NSAlertFirstButtonReturn:
return SAVE_YES;
return DIALOG_YES;
case NSAlertSecondButtonReturn:
return SAVE_NO;
default:
return DIALOG_NO;
}
}
SolveSpace::DialogChoice SolveSpace::LocateImportedFileYesNoCancel(
const std::string &filename, bool canCancel) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:[NSString stringWithUTF8String:
("The imported file " + filename + " is not present.").c_str()]];
[alert setInformativeText:
@"Do you want to locate it manually?\n"
"If you select \"No\", any geometry that depends on "
"the missing file will be removed."];
[alert addButtonWithTitle:@"Yes"];
if(canCancel)
[alert addButtonWithTitle:@"Cancel"];
[alert addButtonWithTitle:@"No"];
switch([alert runModal]) {
case NSAlertFirstButtonReturn:
return DIALOG_YES;
case NSAlertSecondButtonReturn:
default:
if(canCancel)
return DIALOG_CANCEL;
/* fallthrough */
case NSAlertThirdButtonReturn:
return DIALOG_NO;
}
abort(); /* unreachable */
}
/* Text window */

View File

@ -765,8 +765,9 @@ static std::string PathSepUNIXToPlatform(const std::string &filename)
#endif
}
void SolveSpaceUI::ReloadAllImported(void)
bool SolveSpaceUI::ReloadAllImported(bool canCancel)
{
std::map<std::string, std::string> importMap;
allConsistent = false;
int i;
@ -785,6 +786,12 @@ void SolveSpaceUI::ReloadAllImported(void)
g->impMesh.Clear();
g->impShell.Clear();
if(importMap.count(g->impFile)) {
std::string newPath = importMap[g->impFile];
if(!newPath.empty())
g->impFile = newPath;
}
FILE *test = ssfopen(g->impFile, "rb");
if(test) {
fclose(test); // okay, exists
@ -803,6 +810,7 @@ void SolveSpaceUI::ReloadAllImported(void)
}
}
try_load_file:
if(LoadEntitiesFromFile(g->impFile, &(g->impEntity), &(g->impMesh), &(g->impShell)))
{
if(!SS.saveFile.empty()) {
@ -816,9 +824,34 @@ void SolveSpaceUI::ReloadAllImported(void)
// is always nonempty when we are actually writing anything.
g->impFileRel = g->impFile;
}
} else if(!importMap.count(g->impFile)) {
switch(LocateImportedFileYesNoCancel(g->impFileRel, canCancel)) {
case DIALOG_YES: {
std::string oldImpFile = g->impFile;
if(!GetOpenFile(g->impFile, "", SLVS_PATTERN)) {
if(canCancel)
return false;
break;
} else {
Error("Failed to load imported file '%s'", g->impFile.c_str());
importMap[oldImpFile] = g->impFile;
goto try_load_file;
}
}
case DIALOG_NO:
importMap[g->impFile] = "";
/* Geometry will be pruned by GenerateAll(). */
break;
case DIALOG_CANCEL:
return false;
}
} else {
// User was already asked to and refused to locate a missing
// imported file.
}
}
return true;
}

View File

@ -1165,7 +1165,7 @@ bool GetSaveFile(std::string &file, const std::string &activeOrEmpty,
}
}
int SaveFileYesNoCancel(void) {
DialogChoice SaveFileYesNoCancel(void) {
Glib::ustring message =
"The file has changed since it was last saved.\n"
"Do you want to save the changes?";
@ -1178,18 +1178,18 @@ int SaveFileYesNoCancel(void) {
switch(dialog.run()) {
case Gtk::RESPONSE_YES:
return SAVE_YES;
return DIALOG_YES;
case Gtk::RESPONSE_NO:
return SAVE_NO;
return DIALOG_NO;
case Gtk::RESPONSE_CANCEL:
default:
return SAVE_CANCEL;
return DIALOG_CANCEL;
}
}
int LoadAutosaveYesNo(void) {
DialogChoice LoadAutosaveYesNo(void) {
Glib::ustring message =
"An autosave file is availible for this project.\n"
"Do you want to load the autosave file instead?";
@ -1201,11 +1201,39 @@ int LoadAutosaveYesNo(void) {
switch(dialog.run()) {
case Gtk::RESPONSE_YES:
return SAVE_YES;
return DIALOG_YES;
case Gtk::RESPONSE_NO:
default:
return SAVE_NO;
return DIALOG_NO;
}
}
DialogChoice LocateImportedFileYesNoCancel(const std::string &filename,
bool canCancel) {
Glib::ustring message =
"The imported file " + filename + " is not present.\n"
"Do you want to locate it manually?\n"
"If you select \"No\", any geometry that depends on "
"the missing file will be removed.";
Gtk::MessageDialog dialog(*GW, message, /*use_markup*/ true, Gtk::MESSAGE_QUESTION,
Gtk::BUTTONS_NONE, /*is_modal*/ true);
dialog.set_title("SolveSpace - Missing File");
dialog.add_button("_Yes", Gtk::RESPONSE_YES);
dialog.add_button("_No", Gtk::RESPONSE_NO);
if(canCancel)
dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
switch(dialog.run()) {
case Gtk::RESPONSE_YES:
return DIALOG_YES;
case Gtk::RESPONSE_NO:
return DIALOG_NO;
case Gtk::RESPONSE_CANCEL:
default:
return DIALOG_CANCEL;
}
}

View File

@ -110,7 +110,7 @@ bool SolveSpaceUI::LoadAutosaveFor(const std::string &filename) {
return false;
fclose(f);
if(LoadAutosaveYesNo() == SAVE_YES) {
if(LoadAutosaveYesNo() == DIALOG_YES) {
unsaved = true;
return LoadFromFile(autosaveFile);
}
@ -120,12 +120,15 @@ bool SolveSpaceUI::LoadAutosaveFor(const std::string &filename) {
bool SolveSpaceUI::OpenFile(const std::string &filename) {
bool autosaveLoaded = LoadAutosaveFor(filename);
bool success = autosaveLoaded || LoadFromFile(filename);
bool fileLoaded = autosaveLoaded || LoadFromFile(filename);
if(fileLoaded)
saveFile = filename;
bool success = fileLoaded && ReloadAllImported(/*canCancel=*/true);
if(success) {
RemoveAutosave();
AddToRecentList(filename);
saveFile = filename;
} else {
saveFile = "";
NewFile();
}
AfterNewFile();
@ -291,7 +294,6 @@ void SolveSpaceUI::AfterNewFile(void) {
SS.GW.projRight = Vector::From(1, 0, 0);
SS.GW.projUp = Vector::From(0, 1, 0);
ReloadAllImported();
GenerateAll(-1, -1);
TW.Init();
@ -386,13 +388,13 @@ bool SolveSpaceUI::OkayToStartNewFile(void) {
if(!unsaved) return true;
switch(SaveFileYesNoCancel()) {
case SAVE_YES:
case DIALOG_YES:
return GetFilenameAndSave(false);
case SAVE_NO:
case DIALOG_NO:
return true;
case SAVE_CANCEL:
case DIALOG_CANCEL:
return false;
default: oops(); break;
@ -415,7 +417,6 @@ void SolveSpaceUI::MenuFile(int id) {
if(!SS.OkayToStartNewFile()) return;
std::string newFile = RecentFile[id - RECENT_OPEN];
RemoveFromRecentList(newFile);
SS.OpenFile(newFile);
return;
}

View File

@ -19,6 +19,7 @@
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
@ -146,11 +147,11 @@ void ssremove(const std::string &filename);
extern std::string RecentFile[MAX_RECENT];
void RefreshRecentMenus(void);
#define SAVE_YES (1)
#define SAVE_NO (-1)
#define SAVE_CANCEL (0)
int SaveFileYesNoCancel(void);
int LoadAutosaveYesNo(void);
enum DialogChoice { DIALOG_YES = 1, DIALOG_NO = -1, DIALOG_CANCEL = 0 };
DialogChoice SaveFileYesNoCancel(void);
DialogChoice LoadAutosaveYesNo(void);
DialogChoice LocateImportedFileYesNoCancel(const std::string &filename,
bool canCancel);
#define AUTOSAVE_SUFFIX "~"
@ -851,7 +852,7 @@ public:
bool LoadFromFile(const std::string &filename);
bool LoadEntitiesFromFile(const std::string &filename, EntityList *le,
SMesh *m, SShell *sh);
void ReloadAllImported(void);
bool ReloadAllImported(bool canCancel=false);
// And the various export options
void ExportAsPngTo(const std::string &filename);
void ExportMeshTo(const std::string &filename);

View File

@ -1024,13 +1024,13 @@ bool SolveSpace::GetSaveFile(std::string &filename,
return OpenSaveFile(false, filename, defExtension, selPattern);
}
int SolveSpace::SaveFileYesNoCancel(void)
DialogChoice SolveSpace::SaveFileYesNoCancel(void)
{
EnableWindow(GraphicsWnd, false);
EnableWindow(TextWnd, false);
int r = MessageBoxW(GraphicsWnd,
L"The program has changed since it was last saved.\r\n\r\n"
L"The file has changed since it was last saved.\n\n"
L"Do you want to save the changes?", L"SolveSpace",
MB_YESNOCANCEL | MB_ICONWARNING);
@ -1039,22 +1039,23 @@ int SolveSpace::SaveFileYesNoCancel(void)
SetForegroundWindow(GraphicsWnd);
switch(r) {
case IDYES: return SAVE_YES;
case IDNO: return SAVE_NO;
case IDCANCEL: return SAVE_CANCEL;
case IDYES:
return DIALOG_YES;
case IDNO:
return DIALOG_NO;
case IDCANCEL:
default:
return DIALOG_CANCEL;
}
oops();
return SAVE_CANCEL;
}
int SolveSpace::LoadAutosaveYesNo(void)
DialogChoice SolveSpace::LoadAutosaveYesNo(void)
{
EnableWindow(GraphicsWnd, false);
EnableWindow(TextWnd, false);
int r = MessageBoxW(GraphicsWnd,
L"An autosave file is availible for this project.\r\n\r\n"
L"An autosave file is availible for this project.\n\n"
L"Do you want to load the autosave file instead?", L"SolveSpace",
MB_YESNO | MB_ICONWARNING);
@ -1063,11 +1064,41 @@ int SolveSpace::LoadAutosaveYesNo(void)
SetForegroundWindow(GraphicsWnd);
switch (r) {
case IDYES: return SAVE_YES;
case IDNO: return SAVE_NO;
case IDYES:
return DIALOG_YES;
case IDNO:
default:
return DIALOG_NO;
}
}
oops();
DialogChoice SolveSpace::LocateImportedFileYesNoCancel(const std::string &filename,
bool canCancel) {
EnableWindow(GraphicsWnd, false);
EnableWindow(TextWnd, false);
std::string message =
"The imported file " + filename + " is not present.\n\n"
"Do you want to locate it manually?\n\n"
"If you select \"No\", any geometry that depends on "
"the missing file will be removed.";
int r = MessageBoxW(GraphicsWnd, Widen(message).c_str(), L"SolveSpace",
(canCancel ? MB_YESNOCANCEL : MB_YESNO) | MB_ICONWARNING);
EnableWindow(TextWnd, true);
EnableWindow(GraphicsWnd, true);
SetForegroundWindow(GraphicsWnd);
switch(r) {
case IDYES:
return DIALOG_YES;
case IDNO:
return DIALOG_NO;
case IDCANCEL:
default:
return DIALOG_CANCEL;
}
}
void SolveSpace::LoadAllFontFiles(void)