ide: workspace: (#882) save workspace file (.ews) in json format.
[sdk] / ide / src / dialogs / NewProjectDialog.ec
index 88b0a77..0918314 100644 (file)
@@ -15,6 +15,12 @@ class NewProjectDialog : Window
    char path[MAX_LOCATION];
    char name[MAX_FILENAME];
 
+   Project project;
+   Workspace workspace;
+
+   char projectLocation[MAX_LOCATION];
+   bool createFormOption;
+
    PathBox locationEditBox
    {
       this, position = { 10, 80 }, size = { 120, 22 }, anchor = { left = 10, top = 80, right = 10 };
@@ -34,54 +40,25 @@ class NewProjectDialog : Window
       parent = this, isDefault = true, disabled = true, position = { 170, 130 }, size = { 60 }, text = $"OK";
       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
-         char * location = locationEditBox.slashPath;
-         char * prjName = projectName.contents;
+         const char * prjName = projectName.contents;
          char filePath[MAX_LOCATION];
-         char fileName[MAX_LOCATION];  // Windows Friendly path
          char extension[MAX_EXTENSION];
-         FileAttribs exists;
-         Project project;
-         Workspace workspace;
-         ProjectView projectWindow;
          ProjectConfig debug, release;
-         
-         if(!FileExists(location).isDirectory)
-         {
-            if(MessageBox { type = yesNo, master = this, 
-                  text = $"Directory doesn't exist", contents = $"Create directory?" }.Modal() == yes)
-            {
-               if(!MakeDir(location))
-               {
-                  MessageBox { type = ok, master = this, text = location, contents = $"Error creating directory" }.Modal();
-                  return true;
-               }
-            }
-            else
-               return true;
-         }
 
-         strcpy(filePath, location);
+         strcpy(projectLocation, locationEditBox.slashPath);
+         strcpy(filePath, projectLocation);
          PathCatSlash(filePath, prjName);
          GetExtension(filePath, extension);
          //if(!extension[0])
             ChangeExtension(filePath, ProjectExtension, filePath);
 
-         GetSystemPathBuffer(fileName, filePath);
-         exists = FileExists(filePath);
-
-         if(exists)
-         {
-            if(MessageBox { type = yesNo, master = this, 
-                  text = $"Project Already Exists", contents = $"Replace existing project?" }.Modal() == no)
-               return true;
-         }
-
          debug = ProjectConfig
          {
             name = CopyString("Debug");
-            options = 
+            options =
             {
                optimization = none;
+               fastMath = false;
                debug = true;
                preprocessorDefinitions = { [ CopyString("_DEBUG") ] };
             };
@@ -96,6 +73,7 @@ class NewProjectDialog : Window
             options =
             {
                optimization = speed;
+               fastMath = true;
                debug = false;
             };
             makingModified = true;
@@ -103,11 +81,11 @@ class NewProjectDialog : Window
             linkingModified = true;
          };
 
-         /* error: too few arguments to function ‘__ecereProp_DirExpression_Set_char__PTR_’ -- debug.objDir = "debug";*/ 
+         /* error: too few arguments to function ‘__ecereProp_DirExpression_Set_char__PTR_’ -- debug.objDir = "debug";*/
 
          project = Project
          {
-            filePath = filePath;
+            property::filePath = filePath;
             moduleName = CopyString(name);
             topNode.type = NodeTypes::project;
             config = debug;
@@ -124,85 +102,127 @@ class NewProjectDialog : Window
             project.options.libraries = { [ CopyString("ecere") ] };
          }
 
-         {
-            char workspaceFile[MAX_LOCATION];
-            strcpy(workspaceFile, filePath);
-            ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
-            workspace = Workspace { compiler = ideSettings.defaultCompiler, workspaceFile = workspaceFile };
-         } 
-         workspace.projects.Add(project);
-
          project.topNode.configurations = /*project.configurations = */{ [ debug, release ] };
          project.resNode = project.topNode.Add(project, "Resources", null, resources, archiveFile, false);
 
-         if(!project.Save(filePath))
-         {
-            MessageBox { type = ok, master = this, text = filePath, contents = $"Error writing project file" }.Modal();
-            delete project;
-            return true;
-         }
+         createFormOption = createForm.checked;
 
-         projectWindow = ide.CreateProjectView(workspace, fileName);
-         
-         {
-            char newWorkingDir[MAX_LOCATION];
-            StripLastDirectory(filePath, newWorkingDir);
+         Destroy(DialogResult::ok);
+         return true;
+      }
+   };
 
-            ide.ChangeFileDialogsDirectory(newWorkingDir, false);
-            
-            StripLastDirectory(newWorkingDir, newWorkingDir);
-            ide.ChangeProjectFileDialogDirectory(newWorkingDir);
-         }
+   void CreateNewProject()
+   {
+      char fileName[MAX_LOCATION];  // Windows Friendly path
+      ProjectView projectWindow;
+      Project prj = project;
 
-         if(createForm.checked)
+      if(!FileExists(projectLocation).isDirectory)
+      {
+         if(MessageBox { type = yesNo, master = ide,
+               text = $"Directory doesn't exist", contents = $"Create directory?" }.Modal() == yes)
          {
-            char className[256];
-            char varName[256];
-            CodeEditor codeEditor = projectWindow.CreateNew("Form", "form", "Window", className);
-            EditBox editBox = codeEditor.editBox;
-            strcpy(varName, className);
-            if(islower(varName[0]))
+            if(!MakeDir(projectLocation))
             {
-               memmove(varName+1, varName, strlen(varName)+1);
-               varName[0] = '_';
+               MessageBox { type = ok, master = ide, text = projectLocation, contents = $"Error creating directory" }.Modal();
+               return;
             }
-            else
-               varName[0] = (char)tolower(varName[0]);
+         }
+         else
+            return;
+      }
 
-            editBox.End();
-            editBox.Printf("\n%s %s {};\n", className, varName);
+      GetSystemPathBuffer(fileName, prj.filePath);
 
-            codeEditor.EnsureUpToDate();
+      if(FileExists(prj.filePath))
+      {
+         if(MessageBox { type = yesNo, master = ide,
+               text = $"Project Already Exists", contents = $"Replace existing project?" }.Modal() == no)
+            return;
+      }
 
-            project.Save(filePath);
+      {
+         char workspaceFile[MAX_LOCATION];
+         strcpy(workspaceFile, prj.filePath);
+         ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
+         workspace = Workspace { activeCompiler = ideSettings.defaultCompiler, workspaceFile = workspaceFile };
+         workspace.Init();
+      }
+      workspace.AddProject(prj, null);
+      ide.findInFilesDialog.AddProjectItem(prj);
+      ide.findInFilesDialog.mode = FindInFilesMode::project;
+      ide.findInFilesDialog.currentDirectory = prj.topNode.path;
 
-            projectWindow.modifiedDocument = false;
-            project.topNode.modified = false;
+      if(!prj.Save(prj.filePath))
+      {
+         MessageBox { type = ok, master = this, text = prj.filePath, contents = $"Error writing project file" }.Modal();
+         delete prj;
+         return;
+      }
 
-            /*
-            editBox.Printf("class FormApplication : GuiApplication\n");
-            editBox.Printf("{\n");
-            editBox.Printf("   %s %s {};\n", className, varName);
-            editBox.Printf("}\n");
-            editBox.Home();
-            */
-         }
-         project.StartMonitoring();
+      projectWindow = ide.CreateProjectView(workspace, fileName);
 
-         if(project && projectWindow)
+      {
+         char newWorkingDir[MAX_LOCATION];
+         StripLastDirectory(prj.filePath, newWorkingDir);
+
+         ide.ChangeFileDialogsDirectory(newWorkingDir, false);
+
+         StripLastDirectory(newWorkingDir, newWorkingDir);
+         ide.ChangeProjectFileDialogDirectory(newWorkingDir);
+      }
+      ide.toolBox.visible = true;
+
+      if(createFormOption)
+      {
+         char className[256];
+         char varName[256];
+         CodeEditor codeEditor = projectWindow.CreateNew("Form", "form", "Window", className);
+         EditBox editBox = codeEditor.editBox;
+         strcpy(varName, className);
+         if(islower(varName[0]))
          {
-            CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
-            ProjectConfig config = project.config;
-            projectWindow.ShowOutputBuildLog(true);
-            projectWindow.ProjectPrepareMakefile(project, force, true, true, compiler, config);
-            delete compiler;
+            memmove(varName+1, varName, strlen(varName)+1);
+            varName[0] = '_';
          }
+         else
+            varName[0] = (char)tolower(varName[0]);
 
-         Destroy(0);
-         return true;
+         editBox.End();
+         editBox.Printf("\n%s %s {};\n", className, varName);
+
+         codeEditor.EnsureUpToDate();
+
+         prj.Save(prj.filePath);
+
+         projectWindow.modifiedDocument = false;
+         prj.topNode.modified = false;
+
+         /*
+         editBox.Printf("class FormApplication : GuiApplication\n");
+         editBox.Printf("{\n");
+         editBox.Printf("   %s %s {};\n", className, varName);
+         editBox.Printf("}\n");
+         editBox.Home();
+         */
       }
-   };
-   
+      prj.StartMonitoring();
+
+      if(prj && projectWindow)
+      {
+         CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.activeCompiler);
+         ProjectConfig config = prj.config;
+         projectWindow.ShowOutputBuildLog(true);
+         projectWindow.DisplayCompiler(compiler, false);
+         projectWindow.ProjectPrepareCompiler(prj, compiler, false);
+         projectWindow.ProjectPrepareMakefile(prj, force, compiler, config);
+         delete compiler;
+
+         ide.UpdateToolBarActiveConfigs(false);
+      }
+   }
+
    Button
    {
       parent = this, position = { 240, 130 }, size = { 60 }, hotKey = escape, text = $"Cancel";
@@ -213,7 +233,7 @@ class NewProjectDialog : Window
       parent = this, text = $"Create Form", hotKey = altF, position = { 200, 30 };
       isCheckbox = true, checked = true;
    };
-   
+
    EditBox projectName
    {
       parent = this, textHorzScroll = true, position = { 10, 30 }, size = { 160 };
@@ -223,11 +243,13 @@ class NewProjectDialog : Window
       bool NotifyModified(EditBox editBox)
       {
          char name[MAX_FILENAME];
+         char tmp[MAX_FILENAME];
          char lastPart[MAX_LOCATION];
-         char * text = editBox.contents;
+         const char * text = editBox.contents;
 
          // drop leading path stuff that has no business here
-         GetLastDirectory(text, name);
+         GetLastDirectory(text, tmp);
+         ValidProjectNameBufCopy(name, tmp);
 
          GetLastDirectory(path, lastPart);
          if(name[0] && (!strcmp(path, lastPart) || !path[0] || !strcmp(this.name, lastPart)))
@@ -264,12 +286,16 @@ class NewProjectDialog : Window
    {
       char location[MAX_LOCATION];
       char lastPart[MAX_FILENAME];
-      char * text = pathBox.slashPath;
+      char * text;
+
+      BasicValidatePathBoxPath(pathBox);
+
+      text = pathBox.slashPath;
 
       //replacing this: NotifyUpdate = EditBoxUpdate;
       okBtn.disabled = !(text[0] && projectName.contents[0]);
 
-      GetWorkingDir(location, sizeof(location) - 1);
+      strcpy(location, ideSettings.ideProjectFileDialogLocation);
       PathCatSlash(location, text);
 
       GetLastDirectory(path, lastPart);
@@ -292,10 +318,7 @@ class NewProjectDialog : Window
    {
       char location[MAX_LOCATION];
 
-      if(ideSettings.ideProjectFileDialogLocation)
-         strcpy(location, ideSettings.ideProjectFileDialogLocation);
-      else
-         GetWorkingDir(location, sizeof(location) - 1);
+      strcpy(location, ideSettings.ideProjectFileDialogLocation);
 
       locationEditBox.path = location;
       strcpy(path, location);
@@ -371,7 +394,7 @@ class QuickProjectDialog : Window
             MessageBox { type = ok, master = this, text = tempDir, contents = $"Temporary directory does not exist." }.Modal();
             return true;
          }
-         
+
          ide.tmpPrjDir = tempDir;
 
          strcpy(filePath, tempDir);
@@ -384,9 +407,10 @@ class QuickProjectDialog : Window
          debug = ProjectConfig
          {
             name = CopyString("Debug");
-            options = 
+            options =
             {
                optimization = none;
+               fastMath = false;
                debug = true;
                preprocessorDefinitions = { [ CopyString("_DEBUG") ] };
             };
@@ -401,6 +425,7 @@ class QuickProjectDialog : Window
             options =
             {
                optimization = speed;
+               fastMath = true;
                debug = false;
             };
             makingModified = true;
@@ -432,10 +457,13 @@ class QuickProjectDialog : Window
             char workspaceFile[MAX_LOCATION];
             strcpy(workspaceFile, filePath);
             ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
-            workspace = Workspace { compiler = ideSettings.defaultCompiler, workspaceFile = workspaceFile };
-         } 
+            workspace = Workspace { activeCompiler = ideSettings.defaultCompiler, workspaceFile = workspaceFile };
+         }
 
-         workspace.projects.Add(project);
+         workspace.AddProject(project, null);
+         ide.findInFilesDialog.AddProjectItem(project);
+         ide.findInFilesDialog.mode = FindInFilesMode::project;
+         ide.findInFilesDialog.currentDirectory = project.topNode.path;
 
          // *** Don't set this directly on project, it must be set on top ProjectNode ***
          project.topNode.configurations = { [ debug, release ] };
@@ -454,20 +482,45 @@ class QuickProjectDialog : Window
          projectWindow = ide.CreateProjectView(workspace, filePath);
 
          {
-            char extension[MAX_EXTENSION];
             Window document = null;
             for(document = ide.firstChild; document; document = document.next)
             {
-               char * fileName = document.fileName;
-               if(document.isDocument && document._class == class(CodeEditor) && document.created && fileName)
+               if(document.created && document.isDocument && document._class == class(CodeEditor))
                {
-                  CodeEditor codeEditor = (CodeEditor)document;
-                  ide.projectView.AddFile(project.topNode, fileName, false, false);
-                  codeEditor.DebugMenusDisabled();
+                  const char * fileName = document.fileName;
+                  if(strstr(fileName, "http://") == fileName)
+                  {
+                     char name[MAX_LOCATION];
+                     char newFileName[MAX_LOCATION];
+                     GetLastDirectory(fileName, name);
+                     strcpy(newFileName, tempDir);
+                     PathCat(newFileName, name);
+
+                     // TODO: this should be in Windows::SaveAs(char* asFileName)
+                     // start
+                     //document.saving = true;
+                     if(document.OnSaveFile(newFileName))
+                     {
+                        document.fileName = newFileName;
+                        document.NotifySaved(document.master, /*this*/document, newFileName);
+                     }
+                     //document.saving = false;
+                     // end
+                     // TODO else MessageBox unable to save and cancel the whole project creation thing
+                     fileName = document.fileName;
+                  }
+                  if(fileName)
+                  {
+                     CodeEditor codeEditor = (CodeEditor)document;
+                     ide.projectView.AddFile(project.topNode, fileName, false, false);
+                     codeEditor.AdjustDebugMenus();
+                  }
                }
             }
          }
 
+         ide.toolBox.visible = true;
+
          if(project.topNode.modified)
          {
             project.Save(filePath);
@@ -507,10 +560,12 @@ class QuickProjectDialog : Window
 
          if(project && projectWindow)
          {
-            CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+            CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.activeCompiler);
             ProjectConfig config = project.config;
             projectWindow.ShowOutputBuildLog(true);
-            projectWindow.ProjectPrepareMakefile(project, force, true, true, compiler, config);
+            projectWindow.DisplayCompiler(compiler, false);
+            projectWindow.ProjectPrepareCompiler(project, compiler, false);
+            projectWindow.ProjectPrepareMakefile(project, force, compiler, config);
             delete compiler;
          }
 
@@ -520,13 +575,13 @@ class QuickProjectDialog : Window
          return true;
       }
    };
-   
+
    Button
    {
       parent = this, position = { 240, 70 }, size = { 60 }, hotKey = escape, text = $"Cancel";
       NotifyClicked = ButtonCloseDialog;
    };
-   
+
    QuickProjectDialog()
    {
       DataRow row;
@@ -545,4 +600,24 @@ class QuickProjectDialog : Window
 
       targetType.currentRow = targetType.FindRow(TargetTypes::executable);
    }
+
+   bool OnPostCreate()
+   {
+      okBtn.Activate();
+      return true;
+   }
+}
+
+void ValidProjectNameBufCopy(char *output, const char *input)
+{
+   strcpy(output, input);
+   TrimLSpaces(output, output);
+   TrimRSpaces(output, output);
+   {
+      // todo: support '&', '.' and ' ' in project name on windows so that it may be used by all platforms.
+      const char * chars = "*|:\",<>?\\/&. ";
+      char ch, * s = output, * o = output;
+      while((ch = *s++)) { if(!strchr(chars, ch)) *o++ = ch; }
+      *o = '\0';
+   }
 }