+ File f;
+ Workspace workspace = null;
+
+ f = FileOpen(filePath, read);
+ if(f)
+ {
+ Array<String> openedFilesNotFound { };
+ WorkspaceFile wf = null;
+ JSONParser parser { f = f };
+ /*JSONResult result = */parser.GetObject(class(WorkspaceFile), &wf);
+ if(!wf)
+ workspace = LoadLegacyWorkspace(filePath, openedFilesNotFound);
+ else
+ {
+ workspace = wf.workspace;
+ //incref workspace;
+ workspace.workspaceFile = filePath;
+ {
+ char absolutePath[MAX_LOCATION];
+ bool done = false;
+ bool ahead = false;
+ Iterator<AddedProjectInfo> it { workspace.addedProjects };
+ while(!done && (ahead || !(done = !it.Next())))
+ {
+ // TODO: implement some type of time based pruning of "dea" added projects instead of just dropping them on the spot
+ // TimeStamp modified; modified = GetLocalTimeStamp();
+ // TimeStamp stamp = modified; if(stamp > GetLocalTimeStamp() - 60*60*24*20) // Days { 20 });
+ AddedProjectInfo addedPrj = it.data;
+ strcpy(absolutePath, workspace.workspaceDir);
+ PathCatSlash(absolutePath, addedPrj.path);
+ if(FileExists(absolutePath))
+ {
+ Project loadedProject = LoadProject(absolutePath, null);
+ if(loadedProject)
+ {
+ workspace.AddProject(loadedProject, addedPrj);
+ loadedProject.StartMonitoring();
+ }
+ else if(workspace.projects.count == 0)
+ {
+ delete workspace;
+ break;
+ }
+ else
+ {
+ // TODO: (#524) show message or something when added project fails to load;
+ }
+ ahead = false;
+ }
+ else
+ {
+ IteratorPointer notFound = it.pointer;
+ done = !it.Next();
+ workspace.addedProjects.Delete(notFound);
+ ahead = true;
+ }
+ }
+ if(workspace)
+ {
+ for(bp : workspace.breakpoints)
+ {
+ char * path = workspace.CopyAbsolutePathFromRelative(bp.relativeFilePath);
+ bp.type = user;
+ if(path)
+ {
+ bp.absoluteFilePath = path;
+ delete path;
+ }
+ else
+ bp.absoluteFilePath = "";
+ }
+ if(workspace.openedFiles && workspace.openedFiles.count)
+ {
+ List<OpenedFileInfo> openedFiles = workspace.openedFiles;
+ workspace.openedFiles = { };
+ for(of : openedFiles)
+ {
+ workspace.LoadOpenedFileInfo(of.path, of.state, of.lineNumber, of.position, of.scroll, of.modified, openedFilesNotFound);
+ }
+ openedFiles.Free();
+ delete openedFiles;
+ }
+ }
+ }
+ }
+
+ if(workspace)
+ {
+ workspace.Init();
+ if(!workspace.projects.first)
+ {
+ Project project;
+ if(fromProjectFile)
+ project = LoadProject(fromProjectFile /*projectFilePath*/, null);
+ else
+ {
+ char projectFilePath[MAX_LOCATION];
+ strcpy(projectFilePath, workspace.workspaceFile);
+ ChangeExtension(projectFilePath, ProjectExtension, projectFilePath);
+ project = LoadProject(projectFilePath, null);
+ }
+ if(project)
+ {
+ project.StartMonitoring();
+ workspace.AddProject(project, null);
+ workspace.name = CopyString(project.name);
+ }
+ else
+ {
+ MessageBox { type = ok, master = ide, contents = $"Workspace load file failed", text = $"Workspace Load File Error" }.Modal();
+ delete workspace;
+ return null;
+ }
+ }
+
+ if(openedFilesNotFound.count)
+ {
+ int c = 0;
+ char s[2] = "";
+ String files = new char[MAX_LOCATION * 16];
+ char title[512];
+ String msg = new char[MAX_LOCATION * 16 + 2048];
+ strcpy(files,"\n");
+
+ if(openedFilesNotFound.count > 1)
+ strcpy(s, "s");
+
+ for(item : openedFilesNotFound)
+ {
+ c++;
+ if(c == 16)
+ {
+ strcat(files, "\n...");
+ break;
+ }
+ strcat(files, "\n");
+ strcat(files, item);
+ }
+
+ sprintf(title, $"File%s not found", s);
+ sprintf(msg, $"The following file%s could not be re-opened.%s", s, files);
+
+ MessageBox { type = ok, master = ide, contents = msg, text = title }.Modal();
+
+ delete files;
+ delete msg;
+ }
+ }
+ openedFilesNotFound.Free();
+ delete openedFilesNotFound;
+ delete parser;
+ delete wf;
+ delete f;
+ }
+ else if(fromProjectFile)
+ {
+ //MessageBox { type = Ok, master = ide, contents = "Worspace load file failed", text = "Worspace Load File Error" }.Modal();
+
+ //char projectFile[MAX_LOCATION];
+ Project newProject;
+
+ //strcpy(projectFile, filePath);
+ //ChangeExtension(projectFile, ProjectExtension, projectFile);
+ newProject = LoadProject(fromProjectFile /*projectFile*/, null);
+
+ if(newProject)
+ {
+ newProject.StartMonitoring();
+ workspace = Workspace { property::workspaceFile = filePath };
+
+ workspace.Init();
+ workspace.AddProject(newProject, null);
+ workspace.Save();
+ }
+ }
+
+ if(workspace)
+ {
+ ide.ChangeFileDialogsDirectory(workspace.workspaceDir, false);
+
+ if(!workspace.activeCompiler || !workspace.activeCompiler[0])
+ workspace.activeCompiler = defaultCompilerName;
+ }
+
+ return workspace;
+}
+
+Workspace LoadLegacyWorkspace(const char * filePath, Array<String> openedFilesNotFound)
+{