ide/CodeEditor: Customizable color scheme support
[sdk] / ide / src / project / ProjectView.ec
index 3318c9e..e217a07 100644 (file)
@@ -7,7 +7,7 @@ class ImportFolderFSI : NormalFileSystemIterator
    ProjectView projectView;
    Array<ProjectNode> stack { };
 
-   bool OnFolder(char * folderPath)
+   bool OnFolder(const char * folderPath)
    {
       char name[MAX_LOCATION];
       ProjectNode parentNode = stack.lastIterator.data;
@@ -20,15 +20,21 @@ class ImportFolderFSI : NormalFileSystemIterator
       return true;
    }
 
-   void OutFolder(char * folderPath, bool isRoot)
+   void OutFolder(const char * folderPath, bool isRoot)
    {
       stack.lastIterator.Remove(); //stack.Remove();
    }
 
-   bool OnFile(char * filePath)
+   bool OnFile(const char * filePath)
    {
       ProjectNode parentNode = stack.lastIterator.data;
-      projectView.AddFile(parentNode, filePath, parentNode.isInResources, false);
+      if(!projectView.AddFile(parentNode, filePath, parentNode.isInResources, false))
+      {
+         char * msg = PrintString($"This file can't be imported due to a conflict.\n\n", filePath,
+               "\n\nThis occurs with identical file paths and with conflicting file names.\n");
+         MessageBox { master = ide, type = ok, text = "Import File Conflict", contents = msg }.Modal();
+         delete msg;
+      }
       return true;
    }
 }
@@ -43,7 +49,7 @@ static Array<FileFilter> fileFilters
 
 static Array<FileFilter> resourceFilters
 { [
-   { $"Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png,*.gif)", "jpg, jpeg, bmp, pcx, png, gif" },
+   { $"Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)", "jpg, jpeg, bmp, pcx, png, gif" },
    { $"3D Studio Model Files (*.3ds)", "3ds" },
    { $"Translations (*.mo)", "mo" },
    { $"All files", null }
@@ -61,7 +67,7 @@ static Array<FileType> projectTypes
    { $"Ecere IDE Workspace", WorkspaceExtension }
 ] };
 
-static char * iconNames[] = 
+static const char * iconNames[] =
 {
    "<:ecere>mimeTypes/file.png",                   /*genFile*/
    "<:ecere>mimeTypes/textEcereWorkspace.png",     /*ewsFile*/
@@ -70,6 +76,7 @@ static char * iconNames[] =
    "<:ecere>status/folderOpen.png",                /*openFolder*/
    "<:ecere>mimeTypes/textEcereSource.png",        /*ecFile*/
    "<:ecere>mimeTypes/textEcereHeader.png",        /*ehFile*/
+   "<:ecere>mimeTypes/textCSource.png",            /*sFile*/ // TODO: change sFile icon to differentiate from cFile icon
    "<:ecere>mimeTypes/textCSource.png",            /*cFile*/
    "<:ecere>mimeTypes/textCHeader.png",            /*hFile*/
    "<:ecere>mimeTypes/textC++Source.png",          /*cppFile*/
@@ -81,12 +88,14 @@ static char * iconNames[] =
    "<:ecere>mimeTypes/package.png",                /*archiveFile*/
    "<:ecere>mimeTypes/packageSoftware.png",        /*packageFile*/
    "<:ecere>mimeTypes/packageOpticalDisc.png",     /*opticalMediaImageFile*/
-   "<:ecere>mimeTypes/file.png"                    /*mFile*/ //TODO: create icon for mfile
+   "<:ecere>mimeTypes/file.png",                   /*mFile*/ //TODO: create icon for .m file
+   "<:ecere>mimeTypes/file.png"                    /*mmFile*/ //TODO: create icon for .mm file
 };
 
 enum PrepareMakefileMethod { normal, force, forceExists };
 
-enum BuildType { build, rebuild, relink, run, start, restart, clean };
+enum CleanType { clean, realClean, cleanTarget };
+enum BuildType { build, rebuild, relink, run, start, restart, clean, install };
 enum BuildState
 {
    none, buildingMainProject, buildingSecondaryProject, compilingFile;
@@ -94,6 +103,56 @@ enum BuildState
    property bool { get { return this != none; } }
    //property bool actualBuild { get { return this == buildingMainProject || this == buildingSecondaryProject;  } }
 };
+enum BuildOutputMode { normal, raw, verbose, justPrint }; // note: verbose and justPrint both imply raw output
+Array<const String> bldMnuStrBuild
+{[
+   $"Build",
+   $"Build (Raw Output)",
+   $"Build (Verbose)",
+   $"Build (Just Print Commands)"
+]};
+Array<const String> bldMnuStrRelink
+{[
+   $"Relink",
+   $"Relink (Raw Output)",
+   $"Relink (Verbose)",
+   $"Relink (Just Print Commands)"
+]};
+Array<const String> bldMnuStrRebuild
+{[
+   $"Rebuild",
+   $"Rebuild (Raw Output)",
+   $"Rebuild (Verbose)",
+   $"Rebuild (Just Print Commands)"
+]};
+Array<const String> bldMnuStrCleanTarget
+{[
+   $"Clean Target",
+   $"Clean Target (Raw Output)",
+   $"Clean Target (Verbose)",
+   $"Clean Target (Just Print Commands)"
+]};
+Array<const String> bldMnuStrClean
+{[
+   $"Clean",
+   $"Clean (Raw Output)",
+   $"Clean (Verbose)",
+   $"Clean (Just Print Commands)"
+]};
+Array<const String> bldMnuStrRealClean
+{[
+   $"Real Clean",
+   $"Real Clean (Raw Output)",
+   $"Real Clean (Verbose)",
+   $"Real Clean (Just Print Commands)"
+]};
+Array<const String> bldMnuStrCompile
+{[
+   $"Compile",
+   $"Compile (Raw Output)",
+   $"Compile (Verbose)",
+   $"Compile (Just Print Commands)"
+]};
 
 class ProjectView : Window
 {
@@ -107,10 +166,10 @@ class ProjectView : Window
    size = { 300 };
    anchor = Anchor { left = 0, top = 0, bottom = 0 };
    menu = Menu { };
-   
+
    //hasMinimize = true;
    saveDialog = projectFileDialog;
-   
+
    DataRow resourceRow;
    BuildState buildInProgress;
    BitmapResource icons[NodeIcons];
@@ -147,7 +206,7 @@ class ProjectView : Window
       }
       get { return workspace; }
    }
-   
+
    bool drawingInProjectSettingsDialog;
    bool drawingInProjectSettingsDialogHeader;
    ProjectSettings projectSettingsDialog;
@@ -183,9 +242,9 @@ class ProjectView : Window
       borderStyle = deep, parent = this, collapseControl = true, treeBranches = true;
       anchor = Anchor { left = 0, right = 0, top = 0 , bottom = 0 };
 
-      background = projectViewBackground;
-      foreground = projectViewText;
-      selectionColor = selectionColor, selectionText = selectionText;
+      background = colorScheme.projectViewBackground;
+      foreground = colorScheme.projectViewText;
+      selectionColor = colorScheme.selectionColor, selectionText = colorScheme.selectionText;
       stippleColor = skyBlue;
 
       bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
@@ -193,11 +252,11 @@ class ProjectView : Window
          if(!active) Update(null);
          return ListBox::OnActivate(active, previous, goOnWithActivation, direct);
       }
-      
+
       bool NotifyDoubleClick(ListBox listBox, int x, int y, Modifiers mods)
       {
          // Prevent the double click from reactivating the project view (returns false if we opened something)
-         return !OpenSelectedNodes();
+         return !OpenSelectedNodes(mods.ctrl && mods.shift);
       }
 
       bool NotifyRightClick(ListBox listBox, int x, int y, Modifiers mods)
@@ -205,113 +264,137 @@ class ProjectView : Window
          DataRow row = listBox.currentRow;
          if(row)
          {
-            ProjectNode node = (ProjectNode)row.tag;
+            bool showDebuggingMenuItems = mods.ctrl && mods.shift;
+            bool showInstallMenuItem = mods.ctrl && mods.shift;
+            BuildOutputMode outputMode = (mods.ctrl && mods.shift) ? justPrint : mods.ctrl ? verbose : mods.shift ? raw : normal;
+            ProjectNode node = (ProjectNode)(intptr)row.tag;
+#ifdef IDE_SHOW_INSTALL_MENU_BUTTON
+            showInstallMenuItem = true;
+#endif
             if(node.type == NodeTypes::project || node.type == resources || node.type == file || node.type == folder)
             {
-               bool buildMenuUnavailable = buildInProgress;
-               Menu popupContent { };
-               
+               bool na = buildInProgress; // N/A - buildMenuUnavailable
+               Menu pop { };
+
                if(node.type == NodeTypes::project)
                {
-                  //if(node == ((Project)workspace.projects.first).topNode)
+                  MenuItem mi;
+                                                                                                                                                                        mi = ide.projectBuildItem;
+                  MenuItem { pop, bldMnuStrBuild[outputMode]      , b, f7     , id = outputMode, NotifySelect = ProjectBuild      , bitmap = mi.bitmap }.disabled = na; mi = ide.projectLinkItem;
+                  MenuItem { pop, bldMnuStrRelink[outputMode]     , l         , id = outputMode, NotifySelect = ProjectLink       , bitmap = mi.bitmap }.disabled = na; mi = ide.projectRebuildItem;
+                  MenuItem { pop, bldMnuStrRebuild[outputMode]    , r, shiftF7, id = outputMode, NotifySelect = ProjectRebuild    , bitmap = mi.bitmap }.disabled = na; mi = ide.projectCleanTargetItem;
+                  MenuItem { pop, bldMnuStrCleanTarget[outputMode], g         , id = outputMode, NotifySelect = ProjectCleanTarget, bitmap = mi.bitmap }.disabled = na; mi = ide.projectCleanItem;
+                  MenuItem { pop, bldMnuStrClean[outputMode]      , c         , id = outputMode, NotifySelect = ProjectClean      , bitmap = mi.bitmap }.disabled = na; mi = ide.projectRealCleanItem;
+                  MenuItem { pop, bldMnuStrRealClean[outputMode]              , id = outputMode, NotifySelect = ProjectRealClean  , bitmap = mi.bitmap }.disabled = na; mi = ide.projectRegenerateItem;
+                  MenuItem { pop, $"Regenerate Makefile"          , m                          , NotifySelect = ProjectRegenerate , bitmap = mi.bitmap }.disabled = na;
+                  if(showInstallMenuItem)
                   {
-                     MenuItem { popupContent, $"Build", b, NotifySelect = ProjectBuild }.disabled = buildMenuUnavailable;
-                     MenuItem { popupContent, $"Relink", l, NotifySelect = ProjectLink }.disabled = buildMenuUnavailable;
-                     MenuItem { popupContent, $"Rebuild", r, NotifySelect = ProjectRebuild }.disabled = buildMenuUnavailable;
-                     MenuItem { popupContent, $"Clean", c, NotifySelect = ProjectClean }.disabled = buildMenuUnavailable;
-                     MenuItem { popupContent, $"Real Clean", d, NotifySelect = ProjectRealClean }.disabled = buildMenuUnavailable;
-                     MenuItem { popupContent, $"Regenerate Makefile", m, NotifySelect = ProjectRegenerate }.disabled = buildMenuUnavailable;
-                     MenuDivider { popupContent };
+                     mi = ide.projectInstallItem;
+                     MenuItem { pop, $"Install"            , t         , NotifySelect = ProjectInstall    , bitmap = mi.bitmap }.disabled = na;
                   }
-                  MenuItem { popupContent, $"Debug Generate Symbols", l, NotifySelect = FileDebugGenerateSymbols }.disabled = buildMenuUnavailable;
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"New File...", l, Key { l, ctrl = true }, NotifySelect = ProjectNewFile };
-                  MenuItem { popupContent, $"New Folder...", n, Key { f, ctrl = true }, NotifySelect = ProjectNewFolder };
-                  MenuItem { popupContent, $"Import Folder...", i, NotifySelect = ProjectImportFolder };
-                  MenuItem { popupContent, $"Add Files to Project...", f, NotifySelect = ProjectAddFiles };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Add New Form...", o, NotifySelect = ProjectAddNewForm };
-                  // MenuItem { popupContent, "Add New Behavior Graph...", g, NotifySelect = ProjectAddNewGraph };
-                  MenuDivider { popupContent };
+                  if(showDebuggingMenuItems && node.ContainsFilesWithExtension("ec", node.project.config))
+                  {
+                     MenuDivider { pop };
+                     MenuItem { pop, $"Debug Generate Symbols", l, NotifySelect = FileDebugGenerateSymbols }.disabled = na;
+                     MenuItem { pop, $"Debug Precompile", l, NotifySelect = FileDebugPrecompile }.disabled = na;
+                     MenuItem { pop, $"Debug Compile", l, NotifySelect = FileDebugCompile }.disabled = na;
+                  }
+                  MenuDivider { pop };
+                  MenuItem { pop, $"New File...", l, Key { l, ctrl = true }, NotifySelect = ProjectNewFile };
+                  MenuItem { pop, $"New Folder...", n, Key { f, ctrl = true }, NotifySelect = ProjectNewFolder };
+                  MenuItem { pop, $"Import Folder...", i, NotifySelect = ProjectImportFolder };
+                  MenuItem { pop, $"Add Files to Project...", f, NotifySelect = ProjectAddFiles };
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Add New Form...", o, NotifySelect = ProjectAddNewForm };
+                  // MenuItem { pop, "Add New Behavior Graph...", g, NotifySelect = ProjectAddNewGraph };
+                  MenuDivider { pop };
                   if(node != ((Project)workspace.projects.first).topNode)
                   {
-                     MenuItem { popupContent, $"Remove project from workspace", r, NotifySelect = ProjectRemove }.disabled = buildMenuUnavailable;
-                     MenuDivider { popupContent };
+                     MenuItem { pop, $"Remove project from workspace", r, NotifySelect = ProjectRemove }.disabled = na;
+                     MenuDivider { pop };
                   }
-                  MenuItem { popupContent, $"Settings...", s, Key { f7, alt = true } , NotifySelect = MenuSettings };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Browse Folder", w, NotifySelect = MenuBrowseFolder };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Save", v, Key { s, ctrl = true }, NotifySelect = ProjectSave }.disabled = !node.modified;
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Properties...", p, Key { enter, alt = true }, NotifySelect = FileProperties };
+                  MenuItem { pop, $"Settings...", s, Key { f7, alt = true } , NotifySelect = MenuSettings };
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Browse Folder", w, NotifySelect = MenuBrowseFolder };
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Save", v, Key { s, ctrl = true }, NotifySelect = ProjectSave }.disabled = !node.modified;
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Properties...", p, Key { enter, alt = true }, NotifySelect = FileProperties };
                }
                else if(node.type == resources)
                {
-                  MenuItem { popupContent, $"New File...", l, Key { l, ctrl = true }, NotifySelect = ProjectNewFile };
-                  MenuItem { popupContent, $"New Folder...", n, Key { f, ctrl = true }, NotifySelect = ProjectNewFolder };
-                  MenuItem { popupContent, $"Import Folder...", i, NotifySelect = ProjectImportFolder };
-                  MenuItem { popupContent, $"Add Resources to Project...", f, NotifySelect = ResourcesAddFiles };
-                  MenuItem { popupContent, $"Browse Folder", w, NotifySelect = MenuBrowseFolder };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Settings...", s, Key { f7, alt = true } , NotifySelect = MenuSettings };
-                  MenuItem { popupContent, $"Properties...", p, Key { enter, alt = true }, NotifySelect = FileProperties };
+                  MenuItem { pop, $"New File...", l, Key { l, ctrl = true }, NotifySelect = ProjectNewFile };
+                  MenuItem { pop, $"New Folder...", n, Key { f, ctrl = true }, NotifySelect = ProjectNewFolder };
+                  MenuItem { pop, $"Import Folder...", i, NotifySelect = ProjectImportFolder };
+                  MenuItem { pop, $"Add Resources to Project...", f, NotifySelect = ResourcesAddFiles };
+                  MenuItem { pop, $"Browse Folder", w, NotifySelect = MenuBrowseFolder };
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Settings...", s, Key { f7, alt = true } , NotifySelect = MenuSettings };
+                  MenuItem { pop, $"Properties...", p, Key { enter, alt = true }, NotifySelect = FileProperties };
                }
                else if(node.type == file)
                {
-                  MenuItem { popupContent, $"Open", o, NotifySelect = FileOpenFile };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Clean", l, NotifySelect = FileClean }.disabled = buildMenuUnavailable;
-                  MenuItem { popupContent, $"Compile", c, Key { f7, ctrl = true}, NotifySelect = FileCompile }.disabled = buildMenuUnavailable;
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Debug Precompile", l, NotifySelect = FileDebugPrecompile }.disabled = buildMenuUnavailable;
-                  MenuItem { popupContent, $"Debug Compile", l, NotifySelect = FileDebugCompile }.disabled = buildMenuUnavailable;
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Remove", r, NotifySelect = FileRemoveFile };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Browse Folder", w, NotifySelect = MenuBrowseFolder };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Settings...", s, Key { f7, alt = true } , NotifySelect = MenuSettings };
-                  MenuItem { popupContent, $"Properties..", p, Key { enter, alt = true }, NotifySelect = FileProperties };
+                  MenuItem { pop, $"Open", o, NotifySelect = FileOpenFile };
+                  MenuDivider { pop };
+                  MenuItem { pop, bldMnuStrClean[outputMode], l, id = outputMode, NotifySelect = FileClean, bitmap = ide.projectCleanItem.bitmap }.disabled = na;
+                  MenuItem { pop, bldMnuStrCompile[outputMode], c, Key { f7, ctrl = true}, id = outputMode, NotifySelect = FileCompile, bitmap = ide.projectBuildItem.bitmap }.disabled = na;
+                  if(showDebuggingMenuItems)
+                  {
+                     char extension[MAX_EXTENSION];
+                     GetExtension(node.name, extension);
+                     if(!strcmpi(extension, "ec"))
+                     {
+                        MenuDivider { pop };
+                        MenuItem { pop, $"Debug Precompile", l, NotifySelect = FileDebugPrecompile }.disabled = na;
+                        MenuItem { pop, $"Debug Compile", l, NotifySelect = FileDebugCompile }.disabled = na;
+                     }
+                  }
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Remove", r, NotifySelect = FileRemoveFile };
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Browse Folder", w, NotifySelect = MenuBrowseFolder };
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Settings...", s, Key { f7, alt = true } , NotifySelect = MenuSettings };
+                  MenuItem { pop, $"Properties..", p, Key { enter, alt = true }, NotifySelect = FileProperties };
                }
                else if(node.type == folder)
                {
                   bool isInResources = node.isInResources;
 
-                  MenuItem { popupContent, $"New File...", l, Key { l, ctrl = true }, NotifySelect = ProjectNewFile };
-                  MenuItem { popupContent, $"New Folder...", n, Key { f, ctrl = true }, NotifySelect = ProjectNewFolder };
-                  MenuItem { popupContent, $"Import Folder...", i, NotifySelect = ProjectImportFolder };
+                  MenuItem { pop, $"New File...", l, Key { l, ctrl = true }, NotifySelect = ProjectNewFile };
+                  MenuItem { pop, $"New Folder...", n, Key { f, ctrl = true }, NotifySelect = ProjectNewFolder };
+                  MenuItem { pop, $"Import Folder...", i, NotifySelect = ProjectImportFolder };
                   if(isInResources)
                   {
-                     MenuItem { popupContent, $"Add Resources to Folder...", f, NotifySelect = ResourcesAddFiles };
+                     MenuItem { pop, $"Add Resources to Folder...", f, NotifySelect = ResourcesAddFiles };
                   }
                   else
                   {
-                     MenuItem { popupContent, $"Add Files to Folder...", f, NotifySelect = ProjectAddFiles };
+                     MenuItem { pop, $"Add Files to Folder...", f, NotifySelect = ProjectAddFiles };
                   }
                   if(!isInResources)
                   {
-                     MenuDivider { popupContent };
-                     MenuItem { popupContent, $"Add New Form...", o, NotifySelect = ProjectAddNewForm };
-                     MenuItem { popupContent, $"Add New Behavior Graph...", g, NotifySelect = ProjectAddNewGraph };
+                     MenuDivider { pop };
+                     MenuItem { pop, $"Add New Form...", o, NotifySelect = ProjectAddNewForm };
+                     // MenuItem { pop, $"Add New Behavior Graph...", g, NotifySelect = ProjectAddNewGraph };
                   }
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Clean", l, NotifySelect = FileClean }.disabled = buildMenuUnavailable;
-                  MenuItem { popupContent, $"Compile", c, Key { f7, ctrl = true}, NotifySelect = FileCompile }.disabled = buildMenuUnavailable;
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Remove", r, NotifySelect = FileRemoveFile };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Browse Folder", w, NotifySelect = MenuBrowseFolder };
-                  MenuDivider { popupContent };
-                  MenuItem { popupContent, $"Settings...", s, Key { f7, alt = true } , NotifySelect = MenuSettings };
-                  MenuItem { popupContent, $"Properties...", p, Key { enter, alt = true }, NotifySelect = FileProperties };
+                  MenuDivider { pop };
+                  MenuItem { pop, bldMnuStrClean[outputMode], l, id = outputMode, NotifySelect = FileClean, bitmap = ide.projectCleanItem.bitmap }.disabled = na;
+                  MenuItem { pop, bldMnuStrCompile[outputMode], c, Key { f7, ctrl = true}, id = outputMode, NotifySelect = FileCompile, bitmap = ide.projectBuildItem.bitmap }.disabled = na;
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Remove", r, NotifySelect = FileRemoveFile };
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Browse Folder", w, NotifySelect = MenuBrowseFolder };
+                  MenuDivider { pop };
+                  MenuItem { pop, $"Settings...", s, Key { f7, alt = true } , NotifySelect = MenuSettings };
+                  MenuItem { pop, $"Properties...", p, Key { enter, alt = true }, NotifySelect = FileProperties };
                }
 
-               popupMenu = 
+               popupMenu =
                {
-                  master = this, menu = popupContent;
+                  master = this, menu = pop;
                   position = {
-                     x + clientStart.x + absPosition.x - app.desktop.position.x, 
+                     x + clientStart.x + absPosition.x - app.desktop.position.x,
                      y + clientStart.y + absPosition.y - app.desktop.position.y };
 
                   void NotifyDestroyed(Window window, DialogResult result)
@@ -320,6 +403,8 @@ class ProjectView : Window
                   }
                };
                popupMenu.Create();
+               ide.rightClickMenuBuildOutputMode = outputMode;
+               ide.AdjustPopupBuildMenus();
             }
          }
          return true;
@@ -339,12 +424,12 @@ class ProjectView : Window
       {
          if(row)
          {
-            ProjectNode node = (ProjectNode)row.tag;
+            ProjectNode node = (ProjectNode)(intptr)row.tag;
             switch(key)
             {
                case altEnter: case Key { keyPadEnter, alt = true }:
                {
-                  NodeProperties { parent = parent, master = this, 
+                  NodeProperties { parent = parent, master = this,
                      position = { position.x + 100, position.y + 100 }, node = node }.Create();
                   return false;
                }
@@ -393,7 +478,9 @@ class ProjectView : Window
                   }
                   break;
                }
-               case Key { space, shift = true }:
+               case Key { space, false, true }:
+               case Key { space, true, true }:
+               case Key { space, true }:
                case space:
                {
                   if(node.type == NodeTypes::project)
@@ -407,7 +494,7 @@ class ProjectView : Window
                            break;
                         }
                      }
-                     prj.RotateActiveConfig(!key.shift);
+                     prj.RotateActiveConfig(!key.shift, key.ctrl);
                      if(prj == project)
                         ide.AdjustMenus();
                      return false;
@@ -418,9 +505,11 @@ class ProjectView : Window
          }
          switch(key)
          {
-            case enter: case keyPadEnter:  OpenSelectedNodes();   break;
-            case del:                      RemoveSelectedNodes(); break;
-            case escape:                      
+            case Key { enter, true, true }:        OpenSelectedNodes(true);   break;
+            case Key { keyPadEnter, true, true }:  OpenSelectedNodes(true);   break;
+            case enter: case keyPadEnter:          OpenSelectedNodes(false);  break;
+            case del:                              RemoveSelectedNodes();     break;
+            case escape:
             {
                Window activeClient = ide.activeClient;
                if(activeClient)
@@ -435,7 +524,7 @@ class ProjectView : Window
 
       bool NotifyCollapse(ListBox listBox, DataRow row, bool collapsed)
       {
-         ProjectNode node = (ProjectNode)row.tag;
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
          if(node.type == folder)
             node.icon = collapsed ? folder : openFolder;
          return true;
@@ -514,10 +603,10 @@ class ProjectView : Window
       ide.watchesView.Clear();
       ide.threadsView.Clear();
       ide.breakpointsView.Clear();
-      ide.outputView.ShowClearSelectTab(find); // why this? 
+      ide.outputView.ShowClearSelectTab(find); // why this?
    }
 
-   bool OnSaveFile(char * fileName)
+   bool OnSaveFile(const char * fileName)
    {
       for(prj : ide.workspace.projects)
       {
@@ -534,34 +623,82 @@ class ProjectView : Window
       return true;
    }
 
-   bool IsModuleInProject(char * filePath)
+   bool IsModuleInProject(const char * filePath)
    {
       char moduleName[MAX_FILENAME]; //, modulePath[MAX_LOCATION];
       GetLastDirectory(filePath, moduleName);
       return project.topNode.Find(moduleName, false) != null;
    }
 
-   bool GetRelativePath(char * filePath, char * relativePath)
+   ProjectNode GetNodeForCompilationFromWindow(Window document, bool nonExcludedFirst, bool * isExcluded, bool * isCObject)
    {
-      return project.GetRelativePath(filePath, relativePath);
+      ProjectNode node = null;
+      if(nonExcludedFirst)
+         node = GetNodeFromWindow(document, null, false, false, isExcluded);
+      if(!node)
+         node = GetNodeFromWindow(document, null, true, false, isExcluded);
+      if(!node && nonExcludedFirst)
+      {
+         node = GetNodeFromWindow(document, null, false, true, isExcluded);
+         if(isCObject && node) *isCObject = true;
+      }
+      if(!node)
+      {
+         node = GetNodeFromWindow(document, null, true, true, isExcluded);
+         if(isCObject && node) *isCObject = true;
+      }
+      return node;
    }
 
-   ProjectNode GetNodeFromWindow(Window document, Project project)
+   ProjectNode GetNodeFromWindow(Window document, Project project, bool allNodes, bool isCObject, bool * isNodeExcluded)
    {
+      ProjectNode node = null;
       if(document.fileName)
       {
+         bool excluded = false;
          char winFileName[MAX_LOCATION];
          char * documentFileName = GetSlashPathBuffer(winFileName, document.fileName);
-         for(p : ide.workspace.projects)
+         Project prj;
+         ProjectNode n;
+         if(isCObject)
+         {
+            char name[MAX_FILENAME];
+            GetLastDirectory(documentFileName, name);
+            ChangeExtension(name, "ec", name);
+            for(p : ide.workspace.projects)
+            {
+               prj = project ? project : p;
+               if((n = prj.topNode.Find(name, false)))
+               {
+                  if(allNodes || !(excluded = n.GetIsExcluded(prj.config)))
+                  {
+                     node = n;
+                     break;
+                  }
+               }
+               if(project) break;
+            }
+         }
+         else
          {
-            Project prj = project ? project : p;
-            ProjectNode node;
-            if((node = prj.topNode.FindByFullPath(documentFileName, false)))
-               return node;
-            if(project) break;
+            for(p : ide.workspace.projects)
+            {
+               prj = project ? project : p;
+               if((n = prj.topNode.FindByFullPath(documentFileName, false)))
+               {
+                  if(allNodes || !(excluded = n.GetIsExcluded(prj.config)))
+                  {
+                     node = n;
+                     break;
+                  }
+               }
+               if(project) break;
+            }
          }
+         if(node && isNodeExcluded)
+            *isNodeExcluded = excluded;
       }
-      return null;
+      return node;
    }
 
    //                          ((( UTILITY FUNCTIONS )))
@@ -579,23 +716,20 @@ class ProjectView : Window
    bool ProjectPrepareForToolchain(Project project, PrepareMakefileMethod method, bool cleanLog, bool displayCompiler,
       CompilerConfig compiler, ProjectConfig config)
    {
-      bool isReady = true;
-      char message[MAX_F_STRING];
-      LogBox logBox = ide.outputView.buildBox;
-
       ShowOutputBuildLog(cleanLog);
 
       if(displayCompiler)
          DisplayCompiler(compiler, false);
 
-      ProjectPrepareCompiler(project, compiler);
+      ProjectPrepareCompiler(project, compiler, false);
       ProjectPrepareMakefile(project, method, compiler, config);
       return true;
    }
 
-   bool ProjectPrepareCompiler(Project project, CompilerConfig compiler)
+   bool ProjectPrepareCompiler(Project project, CompilerConfig compiler, bool silent)
    {
-      if(!project.GenerateCrossPlatformMk() || !project.GenerateCompilerCf(compiler))
+      if((!project.GenerateCrossPlatformMk(app.includeFile) ||
+            !project.GenerateCompilerCf(compiler, project.topNode.ContainsFilesWithExtension("ec", project.config))) && !silent)
          ide.outputView.buildBox.Logf($"Error generating compiler configuration (Is the project/config directory writable?)\n");
       return true;
    }
@@ -611,7 +745,7 @@ class ProjectView : Window
          //GenerateVSSolutionFile(project, compiler);
          ide.statusBar.text = $"Generating Visual Studio Project...";
          app.UpdateDisplay();
-         //GenerateVCProjectFile(project, compiler);
+         //GenerateVCProjectFile(project, compiler, bitDepth);
          ide.statusBar.text = null;
          app.UpdateDisplay();
          return true;
@@ -622,7 +756,7 @@ class ProjectView : Window
          char makefileName[MAX_LOCATION];
          bool exists;
          LogBox logBox = ide.outputView.buildBox;
-         
+
          strcpy(makefilePath, project.topNode.path);
          project.CatMakeFileName(makefileName, config);
          PathCatSlash(makefilePath, makefileName);
@@ -632,8 +766,8 @@ class ProjectView : Window
            (method == forceExists && exists) ||
            (method == normal && (!exists || (config && config.makingModified))))
          {
-            char * reason;
-            char * action;
+            const char * reason;
+            const char * action;
             ide.statusBar.text = $"Generating Makefile & Dependencies..."; // Dependencies?
             app.UpdateDisplay();
 
@@ -665,13 +799,13 @@ class ProjectView : Window
       }
       return false;
    }
-   
-   bool BuildInterrim(Project prj, BuildType buildType, CompilerConfig compiler, ProjectConfig config, bool justPrint)
+
+   bool BuildInterrim(Project prj, BuildType buildType, CompilerConfig compiler, ProjectConfig config, int bitDepth, BuildOutputMode outputMode)
    {
       if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
       {
          ide.outputView.buildBox.Logf($"Building project %s using the %s configuration...\n", prj.name, GetConfigName(config));
-         return Build(prj, buildType, compiler, config, justPrint);
+         return Build(prj, buildType, compiler, config, bitDepth, outputMode);
       }
       return false;
    }
@@ -698,10 +832,12 @@ class ProjectView : Window
                result = DebugStop();
          }
       }
+      app.ProcessInput(true);
+      ShowOutputBuildLog(false);
       return result;
    }
 
-   bool Build(Project prj, BuildType buildType, CompilerConfig compiler, ProjectConfig config, bool justPrint)
+   bool Build(Project prj, BuildType buildType, CompilerConfig compiler, ProjectConfig config, int bitDepth, BuildOutputMode outputMode)
    {
       bool result = true;
       Window document;
@@ -711,7 +847,7 @@ class ProjectView : Window
       {
          if(document.modifiedDocument)
          {
-            ProjectNode node = GetNodeFromWindow(document, prj);
+            ProjectNode node = GetNodeFromWindow(document, prj, true, false, null);
             if(node && !document.MenuFileSave(null, 0))
             {
                result = false;
@@ -721,33 +857,25 @@ class ProjectView : Window
       }
       if(result)
       {
-         DirExpression targetDir = prj.GetTargetDir(compiler, config);
+         DirExpression targetDir = prj.GetTargetDir(compiler, config, bitDepth);
 
          DebugStopForMake(prj, buildType, compiler, config);
 
          // TODO: Disabled until problems fixed... is it fixed?
          if(buildType == rebuild || (config && config.compilingModified))
-            prj.Clean(compiler, config, false, justPrint);
+            prj.Clean(compiler, config, bitDepth, clean, outputMode);
          else
          {
             if(buildType == relink || (config && config.linkingModified))
-            {
-               char target[MAX_LOCATION];
-
-               strcpy(target, prj.topNode.path);
-               PathCat(target, targetDir.dir);
-               prj.CatTargetFileName(target, compiler, config);
-               if(FileExists(target))
-                  DeleteFile(target);
-            }
+               prj.Clean(compiler, config, bitDepth, cleanTarget, outputMode);
             if(config && config.symbolGenModified)
             {
-               DirExpression objDir = prj.GetObjDir(compiler, config);
+               DirExpression objDir = prj.GetObjDir(compiler, config, bitDepth);
                char fileName[MAX_LOCATION];
                char moduleName[MAX_FILENAME];
                strcpy(fileName, prj.topNode.path);
                PathCatSlash(fileName, objDir.dir);
-               strcpy(moduleName, prj.moduleName);
+               ReplaceSpaces(moduleName, prj.moduleName);
                strcat(moduleName, ".main.ec");
                PathCatSlash(fileName, moduleName);
                if(FileExists(fileName))
@@ -766,12 +894,12 @@ class ProjectView : Window
          ide.AdjustBuildMenus();
          ide.AdjustDebugMenus();
 
-         result = prj.Build(buildType == run, null, compiler, config, justPrint, normal);
+         result = prj.Build(buildType, null, compiler, config, bitDepth, outputMode, normal);
 
          if(config)
          {
             config.compilingModified = false;
-            if(!ide.ShouldStopBuild())
+            if(!stopBuild)
                config.linkingModified = false;
 
             config.symbolGenModified = false;
@@ -797,25 +925,66 @@ class ProjectView : Window
 
    bool ProjectBuild(MenuItem selection, Modifiers mods)
    {
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
+      if(buildInProgress == none)
+      {
+         Project prj = project;
+         CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+         int bitDepth = ide.workspace.bitDepth;
+         ProjectConfig config;
+         if(selection || !ide.activeClient)
+         {
+            DataRow row = fileList.currentRow;
+            ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
+            if(node) prj = node.project;
+         }
+         else
+         {
+            ProjectNode node = GetNodeForCompilationFromWindow(ide.activeClient, true, null, null);
+            if(node)
+               prj = node.project;
+         }
+         config = prj.config;
+         if(/*prj != project || */!prj.GetConfigIsInDebugSession(config) || !ide.DontTerminateDebugSession($"Project Build"))
+         {
+            BuildInterrim(prj, build, compiler, config, bitDepth, mode);
+         }
+         delete compiler;
+      }
+      else
+         stopBuild = true;
+      return true;
+   }
+
+   bool ProjectInstall(MenuItem selection, Modifiers mods)
+   {
       Project prj = project;
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+      int bitDepth = ide.workspace.bitDepth;
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
       ProjectConfig config;
       if(selection || !ide.activeClient)
       {
          DataRow row = fileList.currentRow;
-         ProjectNode node = row ? (ProjectNode)row.tag : null;
+         ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
          if(node) prj = node.project;
       }
       else
       {
-         ProjectNode node = GetNodeFromWindow(ide.activeClient, null);
+         ProjectNode node = GetNodeFromWindow(ide.activeClient, null, true, false, null);
          if(node)
             prj = node.project;
       }
       config = prj.config;
-      if(/*prj != project || */!prj.GetConfigIsInDebugSession(config) || !ide.DontTerminateDebugSession($"Project Build"))
+      if(!prj.GetConfigIsInDebugSession(config) ||
+            (!ide.DontTerminateDebugSession($"Project Install") && DebugStopForMake(prj, relink, compiler, config)))
       {
-         BuildInterrim(prj, build, compiler, config, mods.ctrl && mods.shift);
+         BuildInterrim(prj, build, compiler, config, bitDepth, mode);
+         if(ProjectPrepareForToolchain(prj, normal, false, false, compiler, config))
+         {
+            ide.outputView.buildBox.Logf($"\nInstalling project %s using the %s configuration...\n", prj.name, GetConfigName(config));
+            Build(prj, install, compiler, config, bitDepth, mode);
+         }
       }
       delete compiler;
       return true;
@@ -824,17 +993,19 @@ class ProjectView : Window
    bool ProjectLink(MenuItem selection, Modifiers mods)
    {
       Project prj = project;
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+      int bitDepth = ide.workspace.bitDepth;
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
       ProjectConfig config;
       if(selection || !ide.activeClient)
       {
          DataRow row = fileList.currentRow;
-         ProjectNode node = row ? (ProjectNode)row.tag : null;
+         ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
          if(node) prj = node.project;
       }
       else
       {
-         ProjectNode node = GetNodeFromWindow(ide.activeClient, null);
+         ProjectNode node = GetNodeFromWindow(ide.activeClient, null, true, false, null);
          if(node)
             prj = node.project;
       }
@@ -847,7 +1018,7 @@ class ProjectView : Window
             ide.outputView.buildBox.Logf($"Relinking project %s using the %s configuration...\n", prj.name, GetConfigName(config));
             if(config)
                config.linkingModified = true;
-            Build(prj, relink, compiler, config, mods.ctrl && mods.shift);
+            Build(prj, relink, compiler, config, bitDepth, mode);
          }
       }
       delete compiler;
@@ -856,18 +1027,20 @@ class ProjectView : Window
 
    bool ProjectRebuild(MenuItem selection, Modifiers mods)
    {
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+      int bitDepth = ide.workspace.bitDepth;
       Project prj = project;
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
       ProjectConfig config;
       if(selection || !ide.activeClient)
       {
          DataRow row = fileList.currentRow;
-         ProjectNode node = row ? (ProjectNode)row.tag : null;
+         ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
          if(node) prj = node.project;
       }
       else
       {
-         ProjectNode node = GetNodeFromWindow(ide.activeClient, null);
+         ProjectNode node = GetNodeFromWindow(ide.activeClient, null, true, false, null);
          if(node)
             prj = node.project;
       }
@@ -883,121 +1056,124 @@ class ProjectView : Window
                config.compilingModified = true;
                config.makingModified = true;
             }*/ // -- should this still be used depite the new solution of BuildType?
-            Build(prj, rebuild, compiler, config, mods.ctrl && mods.shift);
+            Build(prj, rebuild, compiler, config, bitDepth, mode);
          }
       }
       delete compiler;
       return true;
    }
 
-   bool ProjectClean(MenuItem selection, Modifiers mods)
+   bool ProjectCleanTarget(MenuItem selection, Modifiers mods)
    {
-      Project prj = project;
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
-      ProjectConfig config;
-      if(selection || !ide.activeClient)
-      {
-         DataRow row = fileList.currentRow;
-         ProjectNode node = row ? (ProjectNode)row.tag : null;
-         if(node) prj = node.project;
-      }
-      else
-      {
-         ProjectNode node = GetNodeFromWindow(ide.activeClient, null);
-         if(node)
-            prj = node.project;
-      }
-      config = prj.config;
-      if(!prj.GetConfigIsInDebugSession(config) ||
-            (!ide.DontTerminateDebugSession($"Project Clean") && DebugStopForMake(prj, clean, compiler, config)))
-      {
-         if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
-         {
-            ide.outputView.buildBox.Logf($"Cleaning project %s using the %s configuration...\n", prj.name, GetConfigName(config));
-
-            buildInProgress = prj == project ? buildingMainProject : buildingSecondaryProject;
-            ide.AdjustBuildMenus();
-            ide.AdjustDebugMenus();
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
+      CleanProject($"Project Clean Target", $"Cleaning project %s target using the %s configuration...\n", selection, cleanTarget, mode);
+      return true;
+   }
 
-            prj.Clean(compiler, config, false, mods.ctrl && mods.shift);
-            buildInProgress = none;
-            ide.AdjustBuildMenus();
-            ide.AdjustDebugMenus();
-         }
-      }
-      delete compiler;
+   bool ProjectClean(MenuItem selection, Modifiers mods)
+   {
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
+      CleanProject($"Project Clean", $"Cleaning project %s using the %s configuration...\n", selection, clean, mode);
       return true;
    }
 
    bool ProjectRealClean(MenuItem selection, Modifiers mods)
    {
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
+      CleanProject($"Project Real Clean", $"Removing intermediate objects directory for project %s using the %s configuration...\n", selection, realClean, mode);
+      return true;
+   }
+
+   void CleanProject(const char * terminateDebugSessionMessage, const char * cleaningMessageLogFormat, MenuItem selection, CleanType cleanType, BuildOutputMode outputMode)
+   {
       Project prj = project;
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
-      ProjectConfig config;
+      Array<Project> projects { };
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+      int bitDepth = ide.workspace.bitDepth;
+      if(selection)
+      {
+         OldLink item;
+         OldList selectedRows;
+         fileList.GetMultiSelection(selectedRows);
+         for(item = selectedRows.first; item; item = item.next)
+         {
+            DataRow row = item.data;
+            ProjectNode node = (ProjectNode)(intptr)row.tag;
+            if(node.type == project)
+               projects.Add(node.project);
+         }
+         selectedRows.Free(null);
+      }
       if(selection || !ide.activeClient)
       {
          DataRow row = fileList.currentRow;
-         ProjectNode node = row ? (ProjectNode)row.tag : null;
+         ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
          if(node) prj = node.project;
+         if(projects.count == 0)
+            projects.Add(prj);
       }
       else
       {
-         ProjectNode node = GetNodeFromWindow(ide.activeClient, null);
-         if(node)
-            prj = node.project;
+         // TODO: a file can belong to more than one project, ask which one to clean
+         ProjectNode node = GetNodeFromWindow(ide.activeClient, null, true, false, null);
+         if(node) prj = node.project;
+         if(projects.count == 0)
+            projects.Add(prj);
       }
-      config = prj.config;
-      if(!prj.GetConfigIsInDebugSession(config) ||
-            (!ide.DontTerminateDebugSession($"Project Real Clean") && DebugStopForMake(prj, clean, compiler, config)))
+      for(prj : projects)
       {
-         if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
+         ProjectConfig config = prj.config;
+         if(!prj.GetConfigIsInDebugSession(config) ||
+               (!ide.DontTerminateDebugSession(terminateDebugSessionMessage) && DebugStopForMake(prj, clean, compiler, config)))
          {
-            ide.outputView.buildBox.Logf($"Removing intermediate objects directory for project %s using the %s configuration...\n", prj.name, GetConfigName(config));
+            if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
+            {
+               ide.outputView.buildBox.Logf(cleaningMessageLogFormat, prj.name, GetConfigName(config));
 
-            buildInProgress = prj == project ? buildingMainProject : buildingSecondaryProject;
-            ide.AdjustBuildMenus();
-            ide.AdjustDebugMenus();
+               buildInProgress = prj == project ? buildingMainProject : buildingSecondaryProject;
+               ide.AdjustBuildMenus();
+               ide.AdjustDebugMenus();
 
-            prj.Clean(compiler, config, true, mods.ctrl && mods.shift);
-            buildInProgress = none;
-            ide.AdjustBuildMenus();
-            ide.AdjustDebugMenus();
+               prj.Clean(compiler, config, bitDepth, cleanType, outputMode);
+               buildInProgress = none;
+               ide.AdjustBuildMenus();
+               ide.AdjustDebugMenus();
+            }
          }
       }
       delete compiler;
-      return true;
+      delete projects;
    }
 
    bool ProjectRegenerate(MenuItem selection, Modifiers mods)
    {
       Project prj = project;
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
       ShowOutputBuildLog(true);
       if(selection || !ide.activeClient)
       {
          DataRow row = fileList.currentRow;
-         ProjectNode node = row ? (ProjectNode)row.tag : null;
+         ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
          if(node)
             prj = node.project;
       }
       else
       {
-         ProjectNode node = GetNodeFromWindow(ide.activeClient, null);
+         ProjectNode node = GetNodeFromWindow(ide.activeClient, null, true, false, null);
          if(node)
             prj = node.project;
       }
 
       DisplayCompiler(compiler, false);
-      ProjectPrepareCompiler(project, compiler);
+      ProjectPrepareCompiler(project, compiler, false);
       ProjectPrepareMakefile(prj, force, compiler, prj.config);
       delete compiler;
       return true;
    }
 
-   bool Compile(Project project, List<ProjectNode> nodes, bool justPrint, SingleFileCompileMode mode)
+   bool Compile(Project project, List<ProjectNode> nodes, BuildOutputMode outputMode, SingleFileCompileMode mode)
    {
       bool result = true;
-      char fileName[MAX_LOCATION];
       Window document;
       ProjectConfig config = project.config;
 
@@ -1007,7 +1183,7 @@ class ProjectView : Window
       {
          if(document.modifiedDocument)
          {
-            ProjectNode n = GetNodeFromWindow(document, project);
+            ProjectNode n = GetNodeFromWindow(document, project, true, mode == cObject ? true : false, null);
             for(node : nodes)
             {
                if(n && n.IsInNode(node) && !document.MenuFileSave(null, 0))
@@ -1022,34 +1198,32 @@ class ProjectView : Window
 
       if(result)
       {
-         CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+         CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+         int bitDepth = ide.workspace.bitDepth;
          result = false;
          if(ProjectPrepareForToolchain(project, normal, true, true, compiler, config))
          {
             if(config)
                ide.outputView.buildBox.Logf($"%s specific file(s) in project %s using the %s configuration...\n",
-                     mode == normal ? $"Compiling" : $"Debug compiling", project.name, config.name);
+                     (mode == normal || mode == cObject) ? $"Compiling" : $"Debug compiling", project.name, config.name);
             else
                ide.outputView.buildBox.Logf($"%s specific file(s) in project %s...\n",
-                     mode == normal ? $"Compiling" : $"Debug compiling", project.name);
+                     (mode == normal || mode == cObject) ? $"Compiling" : $"Debug compiling", project.name);
 
             buildInProgress = compilingFile;
             ide.AdjustBuildMenus();
-            project.Compile(nodes, compiler, config, justPrint, mode);
+            result = project.Compile(nodes, compiler, config, bitDepth, outputMode, mode);
             buildInProgress = none;
             ide.AdjustBuildMenus();
-
-            result = true;
          }
          delete compiler;
       }
       return result;
    }
 
-   bool Clean(Project project, List<ProjectNode> nodes, bool justPrint)
+   bool Clean(Project project, List<ProjectNode> nodes)
    {
       bool result = true;
-      char fileName[MAX_LOCATION];
       Window document;
       ProjectConfig config = project.config;
 
@@ -1059,7 +1233,7 @@ class ProjectView : Window
       {
          if(document.modifiedDocument)
          {
-            ProjectNode n = GetNodeFromWindow(document, project);
+            ProjectNode n = GetNodeFromWindow(document, project, true, false, null);
             for(node : nodes)
             {
                if(n && n.IsInNode(node) && !document.MenuFileSave(null, 0))
@@ -1074,10 +1248,13 @@ class ProjectView : Window
 
       if(result)
       {
-         CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+         CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+         int bitDepth = ide.workspace.bitDepth;
          result = false;
          if(ProjectPrepareForToolchain(project, normal, true, true, compiler, config))
          {
+            Map<String, NameCollisionInfo> namesInfo { };
+            project.topNode.GenMakefileGetNameCollisionInfo(namesInfo, config);
             for(node : nodes)
             {
                if(node.GetIsExcluded(config))
@@ -1085,16 +1262,18 @@ class ProjectView : Window
                else
                {
                   if(config)
-                     ide.outputView.buildBox.Logf($"Deleteing intermediate objects for %s %s in project %s using the %s configuration...\n",
+                     ide.outputView.buildBox.Logf($"Deleting intermediate objects for %s %s in project %s using the %s configuration...\n",
                            node.type == file ? $"single file" : $"folder", node.name, project.name, config.name);
                   else
-                     ide.outputView.buildBox.Logf($"Deleteing intermediate objects for %s %s in project %s...\n",
+                     ide.outputView.buildBox.Logf($"Deleting intermediate objects for %s %s in project %s...\n",
                            node.type == file ? $"single file" : $"folder", node.name, project.name);
 
-                  node.DeleteIntermediateFiles(compiler, config);
+                  node.DeleteIntermediateFiles(compiler, config, bitDepth, namesInfo, false);
                   result = true;
                }
             }
+            namesInfo.Free();
+            delete namesInfo;
          }
          delete compiler;
       }
@@ -1108,13 +1287,13 @@ class ProjectView : Window
       {
          char fileName[1024];
          char filePath[MAX_LOCATION];
-         ProjectNode parentNode = (ProjectNode)row.tag;
+         ProjectNode parentNode = (ProjectNode)(intptr)row.tag;
          ProjectNode n, fileNode;
          parentNode.GetFileSysMatchingPath(filePath);
          MakePathRelative(filePath, parentNode.project.topNode.path, filePath);
          for(n = parentNode; n && n != parentNode.project.resNode; n = n.parent);
          sprintf(fileName, $"Untitled %d", documentID);
-         fileNode = AddFile(parentNode, fileName, (bool)n, true);
+         fileNode = AddFile(parentNode, fileName, n != null, true);
          fileNode.path = CopyUnixPath(filePath);
          if(fileNode)
          {
@@ -1136,7 +1315,7 @@ class ProjectView : Window
       DataRow row = fileList.currentRow;
       if(row)
       {
-         ProjectNode parentNode = (ProjectNode)row.tag;
+         ProjectNode parentNode = (ProjectNode)(intptr)row.tag;
          NewFolder(parentNode, null, true);
       }
       return true;
@@ -1159,7 +1338,7 @@ class ProjectView : Window
       DataRow row = fileList.currentRow;
       if(row)
       {
-         ProjectNode toNode = (ProjectNode)row.tag;
+         ProjectNode toNode = (ProjectNode)(intptr)row.tag;
          ImportFolder(toNode);
       }
       return true;
@@ -1169,6 +1348,7 @@ class ProjectView : Window
    {
       CodeEditor codeEditor = CreateNew("Form", "form", "Window", null);
       codeEditor.EnsureUpToDate();
+      ide.RepositionWindows(false);
       return true;
    }
 
@@ -1185,7 +1365,7 @@ class ProjectView : Window
       DataRow row = fileList.currentRow;
       if(row)
       {
-         ProjectNode node = (ProjectNode)row.tag;
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
          if(node.type == project)
             RemoveSelectedNodes();
       }
@@ -1194,8 +1374,9 @@ class ProjectView : Window
 
    bool ProjectUpdateMakefileForAllConfigs(Project project)
    {
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
 
+      // This call really does not belong here:
       ide.UpdateToolBarActiveConfigs(false);
       for(config : project.configurations)
          ProjectPrepareMakefile(project, forceExists, compiler, config);
@@ -1210,8 +1391,10 @@ class ProjectView : Window
       ProjectNode node = GetSelectedNode(true);
       Project prj = node ? node.project : project;
       projectSettingsDialog = ProjectSettings { master = parent, project = prj, projectNode = node };
+      incref projectSettingsDialog;
       projectSettingsDialog.Modal();
-
+      delete projectSettingsDialog;
+      ide.UpdateToolBarActiveConfigs(false);
       Update(null);
       ide.AdjustMenus();
       return true;
@@ -1222,8 +1405,8 @@ class ProjectView : Window
       DataRow row = fileList.currentRow;
       if(row)
       {
-         ProjectNode node = (ProjectNode)row.tag;
-         NodeProperties { parent = parent, master = this, node = node, 
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
+         NodeProperties { parent = parent, master = this, node = node,
                position = { position.x + 100, position.y + 100 } }.Create();
       }
       return true;
@@ -1231,7 +1414,7 @@ class ProjectView : Window
 
    bool FileOpenFile(MenuItem selection, Modifiers mods)
    {
-      OpenSelectedNodes();
+      OpenSelectedNodes(mods.ctrl && mods.shift);
       return true;
    }
 
@@ -1246,13 +1429,13 @@ class ProjectView : Window
       OldLink item;
       OldList selectedRows;
       Project project = null;
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
       List<ProjectNode> nodes { };
       fileList.GetMultiSelection(selectedRows);
       for(item = selectedRows.first; item; item = item.next)
       {
-         OldLink i;
          DataRow row = item.data;
-         ProjectNode node = (ProjectNode)row.tag;
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
          if(!project)
             project = node.project;
          else if(node.project != project)
@@ -1264,7 +1447,7 @@ class ProjectView : Window
       }
       selectedRows.Free(null);
       if(project)
-         Compile(project, nodes, mods.ctrl && mods.shift, normal);
+         Compile(project, nodes, mode, normal);
       else
          ide.outputView.buildBox.Logf($"Please select files from a single project.\n");
       delete nodes;
@@ -1280,9 +1463,8 @@ class ProjectView : Window
       fileList.GetMultiSelection(selectedRows);
       for(item = selectedRows.first; item; item = item.next)
       {
-         OldLink i;
          DataRow row = item.data;
-         ProjectNode node = (ProjectNode)row.tag;
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
          if(!project)
             project = node.project;
          else if(node.project != project)
@@ -1294,7 +1476,7 @@ class ProjectView : Window
       }
       selectedRows.Free(null);
       if(project)
-         Clean(project, nodes, mods.ctrl && mods.shift);
+         Clean(project, nodes);
       else
          ide.outputView.buildBox.Logf($"Please select files from a single project.\n");
       delete nodes;
@@ -1304,40 +1486,60 @@ class ProjectView : Window
    bool FileDebugPrecompile(MenuItem selection, Modifiers mods)
    {
       DataRow row = fileList.currentRow;
-      ProjectNode node = row ? (ProjectNode)row.tag : null;
+      ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
       if(node)
       {
          List<ProjectNode> nodes { };
          nodes.Add(node);
-         Compile(node.project, nodes, mods.ctrl && mods.shift, debugPrecompile);
+         if(node.type == project)
+            ProjectBuild(selection, mods);
+         ide.Update(null);
+         if(!stopBuild)
+            Compile(node.project, nodes, mode, debugPrecompile);
          delete nodes;
       }
+      return true;
    }
 
    bool FileDebugCompile(MenuItem selection, Modifiers mods)
    {
       DataRow row = fileList.currentRow;
-      ProjectNode node = row ? (ProjectNode)row.tag : null;
+      ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
       if(node)
       {
          List<ProjectNode> nodes { };
          nodes.Add(node);
-         Compile(node.project, nodes, mods.ctrl && mods.shift, debugCompile);
+         if(node.type == project)
+            ProjectBuild(selection, mods);
+         else
+            Compile(node.project, nodes, mode, normal);
+         if(!stopBuild)
+            Compile(node.project, nodes, mode, debugCompile);
          delete nodes;
       }
+      return true;
    }
 
    bool FileDebugGenerateSymbols(MenuItem selection, Modifiers mods)
    {
       DataRow row = fileList.currentRow;
-      ProjectNode node = row ? (ProjectNode)row.tag : null;
+      ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
+      BuildOutputMode mode = selection ? (BuildOutputMode)selection.id : normal;
       if(node)
       {
          List<ProjectNode> nodes { };
          nodes.Add(node);
-         Compile(node.project, nodes, mods.ctrl && mods.shift, debugGenerateSymbols);
+         if(node.type == project)
+            ProjectBuild(selection, mods);
+         else
+            Compile(node.project, nodes, mode, normal);
+         if(!stopBuild)
+            Compile(node.project, nodes, mode, debugGenerateSymbols);
          delete nodes;
       }
+      return true;
    }
 
    Project GetSelectedProject(bool useSelection)
@@ -1346,28 +1548,34 @@ class ProjectView : Window
       if(useSelection)
       {
          DataRow row = fileList.currentRow;
-         ProjectNode node = row ? (ProjectNode)row.tag : null;
+         ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
          if(node)
             prj = node.project;
       }
       return prj;
    }
-   
+
    void SelectNextProject(bool backwards)
    {
       DataRow row = fileList.currentRow;
-      DataRow currentRow = row;
-      ProjectNode node = (ProjectNode)row.tag;
-      if(node.type != project)
-         row = node.project.topNode.row;
-      else if(backwards)
-         row = row.previous ? row.previous : fileList.lastRow;
-      if(!backwards)
-         row = row.next ? row.next : fileList.firstRow;
-      if(row && row != currentRow)
+      if(!row)
+         row = backwards ? fileList.lastRow : fileList.firstRow;
+
+      if(row)
       {
-         fileList.SelectRow(row);
-         fileList.currentRow = row;
+         DataRow currentRow = row;
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
+         if(node.type != project)
+            row = node.project.topNode.row;
+         else if(backwards)
+            row = row.previous ? row.previous : fileList.lastRow;
+         if(!backwards)
+            row = row.next ? row.next : fileList.firstRow;
+         if(row && row != currentRow)
+         {
+            fileList.SelectRow(row);
+            fileList.currentRow = row;
+         }
       }
    }
 
@@ -1378,7 +1586,7 @@ class ProjectView : Window
       {
          DataRow row = fileList.currentRow;
          if(row)
-            node = (ProjectNode)row.tag;
+            node = (ProjectNode)(intptr)row.tag;
       }
       return node;
    }
@@ -1401,19 +1609,21 @@ class ProjectView : Window
 
    bool Run(MenuItem selection, Modifiers mods)
    {
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
       ProjectConfig config = project.config;
+      int bitDepth = ide.workspace.bitDepth;
+      bool shellOpen = compiler.hasDocumentOutput;
       String args = new char[maxPathLen];
       args[0] = '\0';
       if(ide.workspace.commandLineArgs)
          //ide.debugger.GetCommandLineArgs(args);
          strcpy(args, ide.workspace.commandLineArgs);
       if(ide.debugger.isActive)
-         project.Run(args, compiler, config);
+         project.Run(args, compiler, config, bitDepth, shellOpen);
       /*else if(config.targetType == sharedLibrary || config.targetType == staticLibrary)
          MessageBox { master = ide, type = ok, text = "Run", contents = "Shared and static libraries cannot be run like executables." }.Modal();*/
-      else if(BuildInterrim(project, run, compiler, config, false))
-         project.Run(args, compiler, config);
+      else if(BuildInterrim(project, run, compiler, config, bitDepth, normal))
+         project.Run(args, compiler, config, bitDepth, shellOpen);
       delete args;
       delete compiler;
       return true;
@@ -1422,8 +1632,10 @@ class ProjectView : Window
    bool DebugStart()
    {
       bool result = false;
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
       ProjectConfig config = project.config;
+      int bitDepth = ide.workspace.bitDepth;
+      bool useValgrind = ide.workspace.useValgrind;
       TargetTypes targetType = project.GetTargetType(config);
       if(targetType == sharedLibrary || targetType == staticLibrary)
          MessageBox { master = ide, type = ok, text = $"Run", contents = $"Shared and static libraries cannot be run like executables." }.Modal();
@@ -1432,7 +1644,7 @@ class ProjectView : Window
       else if(project.GetDebug(config) ||
          MessageBox { master = ide, type = okCancel, text = $"Starting Debug", contents = $"Attempting to debug non-debug configuration\nProceed anyways?" }.Modal() == ok)
       {
-         if(/*!IsProjectModified() ||*/ BuildInterrim(project, start, compiler, config, false))
+         if(/*!IsProjectModified() ||*/ BuildInterrim(project, start, compiler, config, bitDepth, normal))
          {
             if(compiler.type.isVC)
             {
@@ -1441,8 +1653,8 @@ class ProjectView : Window
                PathBackup pathBackup { };
                char command[MAX_LOCATION];
 
-               ide.SetPath(false, compiler, config);
-               
+               ide.SetPath(false, compiler, config, bitDepth);
+
                GetWorkingDir(oldwd, sizeof(oldwd));
                ChangeWorkingDir(project.topNode.path);
 
@@ -1452,21 +1664,25 @@ class ProjectView : Window
 
                delete pathBackup;
             }
+            else if(compiler.hasDocumentOutput)
+            {
+               project.Run("", compiler, config, bitDepth, true);
+            }
             else
             {
-               ide.debugger.Start(compiler, config);
+               ide.debugger.Start(compiler, config, bitDepth, useValgrind);
                result = true;
             }
          }
       }
       delete compiler;
-      return result;      
+      return result;
    }
 
-   void GoToError(const char * line)
+   void GoToError(const char * line, const bool noParsing, const char * objectFileExt)
    {
       char * colon;
-      
+
       while(isspace(*line)) line++;
       colon = strstr(line, ":");
 
@@ -1496,7 +1712,7 @@ class ProjectView : Window
          if(colon && lookForLineNumber)
          {
             char * comma;
-            // MSVS Errors
+#if 0 // MSVS Errors -- todo fix this later
             char * par = RSearchString(line, "(", colon - line, true, false);
             if(par && strstr(par, ")"))
                colon = par;
@@ -1507,6 +1723,7 @@ class ProjectView : Window
                   /*if(*colon == '(')
                      break*/;
             }
+#endif
             lineNumber = atoi(colon + 1);
             /*
             comma = strchr(colon, ',');
@@ -1517,16 +1734,20 @@ class ProjectView : Window
             if(comma)
                col = atoi(comma+1);
          }
-         
+
          {
-            char moduleName[MAX_LOCATION], filePath[MAX_LOCATION];
-            char * bracket;
+            char moduleName[MAX_LOCATION], filePath[MAX_LOCATION] = "";
+            char ext[MAX_EXTENSION] = "";
+            ProjectNode node = null;
             if(colon)
             {
-               char * inFileIncludedFrom = strstr(line, stringInFileIncludedFrom);
-               char * start = inFileIncludedFrom ? line + strlen(stringInFileIncludedFrom) : line;
-               int len = (int)(colon - start);
-               len = Min(len, MAX_LOCATION-1);
+               const char * inFileIncludedFrom = strstr(line, stringInFileIncludedFrom);
+               const char * from = strstr(line, "from ");
+               const char * start = inFileIncludedFrom ? inFileIncludedFrom + strlen(stringInFileIncludedFrom) : from ? from + strlen("from ") : line;
+               int len;
+               if(colon < start)
+                  start = line;
+               len = Min((int)(colon - start), MAX_LOCATION-1);
                // Cut module name
                strncpy(moduleName, start, len);
                moduleName[len] = '\0';
@@ -1534,47 +1755,191 @@ class ProjectView : Window
             else
                strcpy(moduleName, line);
 
+            if(!colon)
+            {
+               char * msg;
+               if((msg = strstr(moduleName, " - ")))
+               {
+                  bool found = false;
+                  msg[0] = '\0';
+                  for(prj : ide.workspace.projects)
+                  {
+                     strcpy(filePath, prj.topNode.path);
+                     PathCatSlash(filePath, moduleName);
+                     if(FileExists(filePath).isFile)
+                     {
+                        found = true;
+                        break;
+                     }
+                  }
+                  if(!found)
+                  {
+                     msg[0] = ' ';
+                     filePath[0] = '\0';
+                  }
+               }
+               else if((msg = strstr(moduleName, "...")) && (colon = strchr(moduleName, ' ')) && (++colon)[0])
+               {
+                  bool found = false;
+                  msg[0] = '\0';
+                  for(prj : ide.workspace.projects)
+                  {
+                     if((node = prj.resNode.Find(colon, true)))
+                     {
+                        strcpy(filePath, prj.topNode.path);
+                        PathCatSlash(filePath, node.path);
+                        PathCatSlash(filePath, node.name);
+
+                        found = true;
+                        break;
+                     }
+                  }
+                  if(!found)
+                  {
+                     msg[0] = '.';
+                     filePath[0] = '\0';
+                  }
+               }
+               colon = null;
+            }
             // Remove stuff in brackets
             /*
             bracket = strstr(moduleName, "(");
             if(bracket) *bracket = '\0';
             */
             MakeSlashPath(moduleName);
+            GetExtension(moduleName, ext);
 
-            if(!colon)
+            if(!colon && !filePath[0])
             {
                // Check if it's one of our modules
-               ProjectNode node = project.topNode.Find(moduleName, false);
+               node = project.topNode.Find(moduleName, false);
                if(node)
                {
-                  strcpy(moduleName, node.path);
-                  PathCatSlash(moduleName, node.name);
+                  strcpy(filePath, node.path);
+                  PathCatSlash(filePath, node.name);
                }
                else
-                  moduleName[0] = '\0';
+               {
+                  char ext[MAX_EXTENSION];
+                  GetExtension(moduleName, ext);
+                  {
+                     DotMain dotMain = DotMain::FromFileName(moduleName);
+                     IntermediateFileType type = IntermediateFileType::FromExtension(ext);
+                     ProjectConfig config = null;
+                     if(type)
+                     {
+                        for(prj : ide.workspace.projects; prj.lastBuildConfigName)
+                        {
+                           if((config = prj.GetConfig(prj.lastBuildConfigName)))
+                              node = prj.FindNodeByObjectFileName(moduleName, type, dotMain, config, objectFileExt);
+                           if(node)
+                              break;
+                        }
+                     }
+                     if(node)
+                     {
+                        char name[MAX_FILENAME];
+                        Project project = node.project;
+                        CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(project.lastBuildCompilerName);
+                        if(compiler)
+                        {
+                           int bitDepth = ide.workspace.bitDepth;
+                           const char * objectFileExt = compiler ? compiler.objectFileExt : objectDefaultFileExt;
+                           DirExpression objDir = project.GetObjDir(compiler, config, bitDepth);
+                           strcpy(filePath, project.topNode.path);
+                           PathCatSlash(filePath, objDir.dir);
+                           node.GetObjectFileName(name, project.configsNameCollisions[config ? config.name : ""], type, dotMain, objectFileExt);
+                           PathCatSlash(filePath, name);
+                           delete objDir;
+                        }
+                        delete compiler;
+                     }
+                  }
+               }
+               if(!node)
+                  filePath[0] = '\0';
             }
+            if(!strcmp(ext, "a") || !strcmp(ext, "o") || !strcmp(ext, "lib") ||
+                  !strcmp(ext, "dll") || !strcmp(ext, "exe") || !strcmp(ext, "mo"))
+               moduleName[0] = 0;    // Avoid opening binary files
             if(moduleName[0])
             {
-               CodeEditor codeEditor;
-               strcpy(filePath, project.topNode.path);
-               PathCatSlash(filePath, moduleName);
-      
-               codeEditor = (CodeEditor)ide.OpenFile(filePath, normal, true, null, no, normal);
+               CodeEditor codeEditor = null;
+
+               if(ide.GoToCodeSelectFile(moduleName, null, project, null, filePath, objectFileExt))
+               {
+                  codeEditor = (CodeEditor)ide.OpenFile(filePath, false, true, null, no, normal, noParsing);
+               }
+
                if(!codeEditor)
                {
-                  char name[MAX_LOCATION];
-                  // TOFIX: Improve on this, don't use only filename, make a function
-                  if(ide && ide.workspace)
+                  if(!filePath[0])
+                  {
+                     strcpy(filePath, project.topNode.path);
+                     PathCatSlash(filePath, moduleName);
+                  }
+
+                  codeEditor = (CodeEditor)ide.OpenFile(filePath, false, true, null, no, normal, noParsing);
+                  if(!codeEditor && !strcmp(ext, "c"))
                   {
-                     for(prj : ide.workspace.projects)
+                     char ecName[MAX_LOCATION];
+                     ChangeExtension(filePath, "ec", ecName);
+                     codeEditor = (CodeEditor)ide.OpenFile(ecName, false, true, null, no, normal, noParsing);
+                  }
+                  if(!codeEditor)
+                  {
+                     char path[MAX_LOCATION];
+                     // TOFIX: Improve on this, don't use only filename, make a function
+                     if(ide && ide.workspace)
                      {
-                        if(prj.topNode.FindWithPath(moduleName, false))
+                        for(prj : ide.workspace.projects)
                         {
-                           strcpy(filePath, prj.topNode.path);
-                           PathCatSlash(filePath, moduleName);
-                           codeEditor = (CodeEditor)ide.OpenFile(filePath, normal, true, null, no, normal);
-                           if(codeEditor)
-                              break;
+                           ProjectNode node;
+                           MakePathRelative(filePath, prj.topNode.path, path);
+
+                           if((node = prj.topNode.FindWithPath(path, false)))
+                           {
+                              strcpy(filePath, prj.topNode.path);
+                              PathCatSlash(filePath, node.path);
+                              PathCatSlash(filePath, node.name);
+                              codeEditor = (CodeEditor)ide.OpenFile(filePath, false, true, null, no, normal, noParsing);
+                              if(codeEditor)
+                                 break;
+                           }
+                        }
+                        if(!codeEditor && (strchr(moduleName, '/') || strchr(moduleName, '\\')))
+                        {
+                           for(prj : ide.workspace.projects)
+                           {
+                              ProjectNode node;
+                              if((node = prj.topNode.FindWithPath(moduleName, false)))
+                              {
+                                 strcpy(filePath, prj.topNode.path);
+                                 PathCatSlash(filePath, node.path);
+                                 PathCatSlash(filePath, node.name);
+                                 codeEditor = (CodeEditor)ide.OpenFile(filePath, false, true, null, no, normal, noParsing);
+                                 if(codeEditor)
+                                    break;
+                              }
+                           }
+                        }
+                        if(!codeEditor)
+                        {
+                           GetLastDirectory(moduleName, moduleName);
+                           for(prj : ide.workspace.projects)
+                           {
+                              ProjectNode node;
+                              if((node = prj.topNode.Find(moduleName, false)))
+                              {
+                                 strcpy(filePath, prj.topNode.path);
+                                 PathCatSlash(filePath, node.path);
+                                 PathCatSlash(filePath, node.name);
+                                 codeEditor = (CodeEditor)ide.OpenFile(filePath, false, true, null, no, normal, noParsing);
+                                 if(codeEditor)
+                                    break;
+                              }
+                           }
                         }
                      }
                   }
@@ -1582,26 +1947,35 @@ class ProjectView : Window
                if(codeEditor && lineNumber)
                {
                   EditBox editBox = codeEditor.editBox;
-                  editBox.GoToLineNum(lineNumber - 1);
-                  editBox.GoToPosition(editBox.line, lineNumber - 1, col ? (col - 1) : 0);
+                  if(editBox.GoToLineNum(lineNumber - 1))
+                     editBox.GoToPosition(editBox.line, lineNumber - 1, col ? (col - 1) : 0);
                }
             }
          }
       }
    }
 
-   bool OpenNode(ProjectNode node)
+   bool OpenNode(ProjectNode node, bool noParsing)
    {
       char filePath[MAX_LOCATION];
-      node.GetFullFilePath(filePath);
-      return ide.OpenFile(filePath, normal, true/*false Why was it opening hidden?*/, null, something, normal) ? true : false;
+      char ext[MAX_EXTENSION];
+      node.GetFullFilePath(filePath, true);
+
+      GetExtension(filePath, ext);
+      if(binaryDocExt.Find(ext))
+      {
+         ShellOpen(filePath);
+         return true;
+      }
+      else
+         return ide.OpenFile(filePath, false, true/*false Why was it opening hidden?*/, null, something, normal, noParsing) ? true : false;
    }
 
    void AddNode(ProjectNode node, DataRow addTo)
    {
       DataRow row = addTo ? addTo.AddRow() : fileList.AddRow();
 
-      row.tag = (int)node;
+      row.tag = (int64)(intptr)node;
       node.row = row;
 
       if(node.type == resources)
@@ -1609,9 +1983,9 @@ class ProjectView : Window
 
       row.SetData(null, node);
 
-      if(node.files && node.files.first && node.parent && 
-            !(!node.parent.parent && 
-               (!strcmpi(node.name, "notes") || !strcmpi(node.name, "sources") || 
+      if(node.files && node.files.first && node.parent &&
+            !(!node.parent.parent &&
+               (!strcmpi(node.name, "notes") || !strcmpi(node.name, "sources") ||
                   !strcmpi(node.name, "src") || !strcmpi(node.name, "tools"))))
          row.collapsed = true;
       else if(node.type == folder)
@@ -1629,7 +2003,7 @@ class ProjectView : Window
       if(projectNode.files)
       {
          ProjectNode child;
-         while(child = projectNode.files.first)
+         while((child = projectNode.files.first))
             DeleteNode(child);
       }
       fileList.DeleteRow(projectNode.row);
@@ -1639,7 +2013,7 @@ class ProjectView : Window
    bool ProjectSave(MenuItem selection, Modifiers mods)
    {
       DataRow row = fileList.currentRow;
-      ProjectNode node = row ? (ProjectNode)row.tag : null;
+      ProjectNode node = row ? (ProjectNode)(intptr)row.tag : null;
       Project prj = node ? node.project : null;
       if(prj)
       {
@@ -1651,7 +2025,7 @@ class ProjectView : Window
             for(p : ide.workspace.projects)
             {
                if(p.topNode.modified)
-               { 
+               {
                   modPrj = p;
                   break;
                }
@@ -1680,16 +2054,18 @@ class ProjectView : Window
 
    bool DebugRestart()
    {
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
       ProjectConfig config = project.config;
+      int bitDepth = ide.workspace.bitDepth;
+      bool useValgrind = ide.workspace.useValgrind;
 
       bool result = false;
-      if(/*!IsProjectModified() ||*/ BuildInterrim(project, restart, compiler, config, false))
+      if(/*!IsProjectModified() ||*/ BuildInterrim(project, restart, compiler, config, bitDepth, normal))
       {
          // For Restart, compiler and config will only be used if for
          // whatever reason (if at all possible) the Debugger is in a
          // 'terminated' or 'none' state
-         ide.debugger.Restart(compiler, config);
+         ide.debugger.Restart(compiler, config, bitDepth, useValgrind);
          result = true;
       }
 
@@ -1717,22 +2093,40 @@ class ProjectView : Window
 
    bool DebugStepInto()
    {
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
       ProjectConfig config = project.config;
+      int bitDepth = ide.workspace.bitDepth;
+      bool useValgrind = ide.workspace.useValgrind;
 
-      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config, false)))
-         ide.debugger.StepInto(compiler, config);
+      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config, bitDepth, normal)))
+         ide.debugger.StepInto(compiler, config, bitDepth, useValgrind);
       delete compiler;
       return true;
    }
 
    bool DebugStepOver(bool skip)
    {
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+      ProjectConfig config = project.config;
+      int bitDepth = ide.workspace.bitDepth;
+      bool useValgrind = ide.workspace.useValgrind;
+
+      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config, bitDepth, normal)))
+         ide.debugger.StepOver(compiler, config, bitDepth, useValgrind, skip);
+
+      delete compiler;
+      return true;
+   }
+
+   bool DebugStepUntil(bool skip)
+   {
+      CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
       ProjectConfig config = project.config;
+      int bitDepth = ide.workspace.bitDepth;
+      bool useValgrind = ide.workspace.useValgrind;
 
-      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config, false)))
-         ide.debugger.StepOver(compiler, config, skip);
+      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config, bitDepth, normal)))
+         ide.debugger.StepUntil(compiler, config, bitDepth, useValgrind, skip);
 
       delete compiler;
       return true;
@@ -1748,11 +2142,28 @@ class ProjectView : Window
    {
       if(toNode)
       {
-         //bool isFolder = toNode.type == folder;
-         //bool isRes = toNode.isInResources;
-         
+         char path[MAX_LOCATION];
+         char currentDir[MAX_LOCATION];
+         ProjectNode node = toNode;
          FileDialog fileDialog = importFileDialog;
          fileDialog.master = parent;
+         while(node)
+         {
+            node.GetFullFilePath(path, true);
+            while(path[0])
+            {
+               StripLastDirectory(path, path);
+               if(FileExists(path).isDirectory) break;
+            }
+            if(path[0] || node == toNode.project.topNode)
+               node = null;
+            else
+               node = toNode.project.topNode;
+         }
+         MakeSystemPath(path);
+         StripLastDirectory(path, currentDir);
+         fileDialog.currentDirectory = currentDir[0] ? currentDir : path;
+         fileDialog.filePath = path;
          if(fileDialog.Modal() == ok)
          {
             ImportFolderFSI fsi { projectView = this };
@@ -1777,7 +2188,7 @@ class ProjectView : Window
                break;
             after = node;
          }
-         
+
          if(name && name[0])
             folderNode = parentNode.Add(prj, name, after, folder, folder, true);
          else
@@ -1801,11 +2212,11 @@ class ProjectView : Window
             }
             Update(null);
             folderNode.row = parentNode.row.AddRowAfter(after ? after.row : null);
-            folderNode.row.tag = (int)folderNode;
-               
+            folderNode.row.tag = (int64)(intptr)folderNode;
+
             folderNode.row.SetData(null, folderNode);
             fileList.currentRow = folderNode.row;
-            
+
             if(showProperties)
             {
                nodeProperties = NodeProperties
@@ -1832,16 +2243,16 @@ class ProjectView : Window
       {
          int c;
          DataRow row = fileList.currentRow;
-         ProjectNode parentNode = (ProjectNode)row.tag;
+         ProjectNode parentNode = (ProjectNode)(intptr)row.tag;
          bool addFailed = false;
          int numSelections = fileDialog.numSelections;
-         char ** multiFilePaths = fileDialog.multiFilePaths;
+         const char * const * multiFilePaths = fileDialog.multiFilePaths;
 
          Array<String> nameConflictFiles { };
 
          for(c = 0; c < numSelections; c++)
          {
-            char * filePath = multiFilePaths[c];
+            const char * filePath = multiFilePaths[c];
             FileAttribs exists = FileExists(filePath);
             bool addThisFile = true;
 
@@ -1849,7 +2260,7 @@ class ProjectView : Window
                addThisFile = false;
             else if(!exists)
             {
-               if(MessageBox { master = ide, type = yesNo, text = filePath, 
+               if(MessageBox { master = ide, type = yesNo, text = filePath,
                      contents = $"File doesn't exist. Create?" }.Modal() == yes)
                {
                   File f = FileOpen(filePath, write);
@@ -1860,7 +2271,7 @@ class ProjectView : Window
                   }
                   else
                   {
-                     MessageBox { master = ide, type = ok, text = filePath, 
+                     MessageBox { master = ide, type = ok, text = filePath,
                            contents = $"Couldn't create file."}.Modal();
                      addThisFile = false;
                   }
@@ -1879,10 +2290,10 @@ class ProjectView : Window
          if(addFailed)
          {
             int len = 0;
-            char * part1 = $"The following file";
-            char * opt1 = $" was ";
-            char * opt2 = $"s were ";
-            char * part2 = $"not added because of identical file name conflict within the project.\n\n";
+            const char * part1 = $"The following file";
+            const char * opt1 = $" was ";
+            const char * opt2 = $"s were ";
+            const char * part2 = $"not added because of identical file name conflict within the project.\n\n";
             char * message;
             len += strlen(part1);
             len += strlen(part2);
@@ -1898,7 +2309,7 @@ class ProjectView : Window
                strcat(message, s);
                strcat(message, "\n");
             }
-            MessageBox { master = ide, type = ok, text = $"Name Conflict", 
+            MessageBox { master = ide, type = ok, text = $"Name Conflict",
                   contents = message }.Modal();
             delete message;
          }
@@ -1907,7 +2318,7 @@ class ProjectView : Window
       }
    }
 
-   ProjectNode AddFile(ProjectNode parentNode, char * filePath, bool resources, bool isTemporary)
+   ProjectNode AddFile(ProjectNode parentNode, const char * filePath, bool resources, bool isTemporary)
    {
       ProjectNode result = null;
       ProjectNode after = null;
@@ -1930,13 +2341,13 @@ class ProjectView : Window
          }
          Update(null);
          result.row = parentNode.row.AddRowAfter(after ? after.row : null);
-         result.row.tag = (int)result;
+         result.row.tag = (int64)(intptr)result;
          result.row.SetData(null, result);
       }
       return result;
    }
 
-   CodeEditor CreateNew(char * upper, char * lower, char * base, char * className)
+   CodeEditor CreateNew(const char * upper, const char * lower, const char * base, char * className)
    {
       CodeEditor codeEditor = null;
       ProjectNode projectNode;
@@ -1947,7 +2358,7 @@ class ProjectView : Window
 
       if(!row) row = project.topNode.row;
 
-      parentNode = (ProjectNode)row.tag;
+      parentNode = (ProjectNode)(intptr)row.tag;
 
       for(node : parentNode.files)
       {
@@ -1958,7 +2369,7 @@ class ProjectView : Window
       for(c = 1; c < 100; c++)
       {
          char string[16];
-         sprintf(string, c ? "%s%d.ec" : "%s.ec", lower, c);
+         sprintf(string, "%s%d.ec", lower, c);
          if((projectNode = parentNode.Add(project, string, after, file, genFile, true)))
             break;
       }
@@ -1972,8 +2383,8 @@ class ProjectView : Window
          Update(null);
          project.ModifiedAllConfigs(true, false, false, true);
          projectNode.row = parentNode.row.AddRowAfter(after ? after.row : null);
-         projectNode.row.tag =(int)projectNode;
-            
+         projectNode.row.tag = (int64)(intptr)projectNode;
+
          projectNode.row.SetData(null, projectNode);
          fileList.currentRow = projectNode.row;
 
@@ -1988,7 +2399,7 @@ class ProjectView : Window
             subclass(ClassDesignerBase) designerClass = eClass_GetDesigner(baseClass);
             if(designerClass)
             {
-               codeEditor = (CodeEditor)ide.OpenFile(filePath, normal, false, null, whatever, normal);
+               codeEditor = (CodeEditor)ide.OpenFile(filePath, false, false, null, whatever, normal, false);
                strcpy(name, projectNode.name);
                sprintf(name, "%s%d", upper, c);
                if(className)
@@ -2004,20 +2415,22 @@ class ProjectView : Window
          }
          else // TODO: fix no symbols generated when ommiting {} for following else
          {
-            codeEditor = (CodeEditor)ide.OpenFile(filePath, normal, false, null, whatever, normal);
+            codeEditor = (CodeEditor)ide.OpenFile(filePath, false, false, null, whatever, normal, false);
          }
+         ide.sheet.visible = true;
+         ide.sheet.Activate();
          if(codeEditor)
          {
             codeEditor.ViewDesigner();
             codeEditor.codeModified = true;
          }
       }
-      visible = false;
-      return codeEditor;   
+      //visible = false;
+      return codeEditor;
    }
 
    // Returns true if we opened something
-   bool OpenSelectedNodes()
+   bool OpenSelectedNodes(bool noParsing)
    {
       bool result = false;
       OldList selection;
@@ -2027,15 +2440,15 @@ class ProjectView : Window
       for(item = selection.first; item; item = item.next)
       {
          DataRow row = item.data;
-         ProjectNode node = (ProjectNode)row.tag;
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
          if(node.type == file)
          {
-            OpenNode(node);
+            OpenNode(node, noParsing);
             result = true;
-            break;
          }
       }
       selection.Free(null);
+      ide.RepositionWindows(false);
       return result;
    }
 
@@ -2043,7 +2456,7 @@ class ProjectView : Window
    {
       OldList selection;
       OldLink item, next;
-      
+
       fileList.GetMultiSelection(selection);
 
       // Remove children of parents we're deleting
@@ -2051,13 +2464,13 @@ class ProjectView : Window
       {
          OldLink i;
          DataRow row = item.data;
-         ProjectNode n, node = (ProjectNode)row.tag;
+         ProjectNode n, node = (ProjectNode)(intptr)row.tag;
          bool remove = false;
 
          next = item.next;
          for(i = selection.first; i && !remove; i = i.next)
          {
-            ProjectNode iNode = (ProjectNode)((DataRow)i.data).tag;
+            ProjectNode iNode = (ProjectNode)(intptr)((DataRow)i.data).tag;
             for(n = node.parent; n; n = n.parent)
             {
                if(iNode == n)
@@ -2074,7 +2487,7 @@ class ProjectView : Window
       for(item = selection.first; item; item = item.next)
       {
          DataRow row = item.data;
-         ProjectNode node = (ProjectNode)row.tag;
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
          ProjectNode resNode;
          for(resNode = node.parent; resNode; resNode = resNode.parent)
             if(resNode.type == resources)