ecere; ide; compiler: Fixed some Clang warnings
[sdk] / ide / src / ProjectSettings.ec
index 1c4a517..36ea75b 100644 (file)
@@ -9,16 +9,32 @@ static Platform platform;
 static ProjectNode currentNode;
 static Project project;
 
-static String MakeString(char * s, int len)
+static String MakeString(const char * s, int len, const char * switchToKeep, int lenSwitchToKeep)
 {
    String string = new char[len+1];
-   memcpy(string, s, len);
-   string[len] = 0;
+   if(s[0] == '-' && switchToKeep && switchToKeep[0])
+   {
+      if(strstr(s+1, switchToKeep) == s+1)
+      {
+         memcpy(string, s+lenSwitchToKeep+1, len-lenSwitchToKeep-1);
+         string[len-lenSwitchToKeep-1] = '\0';
+      }
+      else
+         delete string;
+   }
+   else
+   {
+      memcpy(string, s, len);
+      string[len] = '\0';
+   }
    return string;
 }
 
 class StringListBox : EditBox
 {
+   const char * switchToKeep;
+   int lenSwitchToKeep;
+
    textHorzScroll = true;
 
    property Array<String> strings
@@ -31,10 +47,13 @@ class StringListBox : EditBox
             bool first = true;
             for(item : value)
             {
-               if(!first)
-                  AddS(" ");
-               AddS(item);
-               first = false;
+               if(item)
+               {
+                  if(!first)
+                     AddS(" ");
+                  AddS(item);
+                  first = false;
+               }
             }
          }
       }
@@ -42,7 +61,8 @@ class StringListBox : EditBox
       {
          Array<String> array { };
          int c, start = 0;
-         char * contents = property::contents;
+         const char * contents = property::contents;
+         char * s;
          char ch;
          bool quoted = false;
 
@@ -51,7 +71,10 @@ class StringListBox : EditBox
             if(ch == ' ' && !quoted)
             {
                if(c - start)
-                  array.Add(MakeString(contents + start, c - start));
+               {
+                  if((s = MakeString(contents + start, c - start, switchToKeep, lenSwitchToKeep)))
+                     array.Add(s);
+               }
                start = c + 1;
             }
             else if(ch == '\"')
@@ -63,7 +86,10 @@ class StringListBox : EditBox
             }
          }
          if(c - start)
-            array.Add(MakeString(contents + start, c - start));
+         {
+            if((s = MakeString(contents + start, c - start, switchToKeep, lenSwitchToKeep)))
+               array.Add(s);
+         }
          return array;
       }
    }
@@ -108,10 +134,10 @@ class ProjectSettings : Window
       //char * s = PrintString("Project Settings - ", project.topNode.fileName);
       //text = s;
       char * projectName = new char[strlen(project.topNode.name) + 1];
-      char * nodeName = currentNode && currentNode != project.topNode ? currentNode.name : "";
-      char * config = buildTab.selectedConfigName;
-      char * platform = buildTab.selectedPlatformName;
-      char * label = new char[strlen(dialogTitle) + 3 + strlen(project.topNode.name) + 3 + 
+      const char * nodeName = currentNode && currentNode != project.topNode ? currentNode.name : "";
+      const char * config = buildTab.selectedConfigName;
+      const char * platform = buildTab.selectedPlatformName;
+      char * label = new char[strlen(dialogTitle) + 3 + strlen(project.topNode.name) + 3 +
                               strlen(nodeName) + 2 + strlen(config) + 1 + strlen(platform) + 1 + 1];
       strcpy(label, dialogTitle);
       strcat(label, " - ");
@@ -235,7 +261,7 @@ class ProjectSettings : Window
    }
 }
 
-#define OPTION(x) ((uint)(&((ProjectOptions)0).x))
+#define OPTION(x) ((uint)(uintptr)(&((ProjectOptions)0).x))
 
 // TOFIX: USING T INSTEAD OF Z HERE CAUSED US SOME CONFLICTS WITH T IN Array TEMPLATES
 
@@ -266,12 +292,12 @@ class OptionBox<class Z> : CommonControl
    }
 
    property bool visible { set { editor.visible = value; } get { return editor.visible; } }
-   property Window parent { set { editor.parent = value; Window::parent = value; master = value; editor.id = (int64)this; } }
+   property Window parent { set { editor.parent = value; Window::parent = value; master = value; editor.id = (int64)(intptr)this; } }
    property Point position { set { editor.position = value; } }
    property Size size { set { editor.size = value; } }
    property Anchor anchor { set { editor.anchor = value; } }
    property Key hotKey { set { editor.hotKey = value; } }
-   property char * text { set { editor.text = value; Window::text = value; } }
+   property const char * text { set { editor.caption = value; Window::caption = value; } }
 
    uint option;
 
@@ -283,7 +309,7 @@ class OptionBox<class Z> : CommonControl
 
       bool NotifySelect(MenuItem selection, Modifiers mods)
       {
-         OptionBox ob = (OptionBox)id;
+         OptionBox ob = (OptionBox)(intptr)id;
          if(eClass_IsDerived(ob._class, class(CheckBoxForEnumOptionBox)))
          {
             Window slave;
@@ -299,10 +325,10 @@ class OptionBox<class Z> : CommonControl
          return true;
       }
    };
-   
+
    bool Window::OptionBox_OnRightButtonDown(int x, int y, Modifiers mods)
    {
-      OptionBox ob = (OptionBox)id;
+      OptionBox ob = (OptionBox)(intptr)id;
       GuiApplication app = ((GuiApplication)__thisModule.application);
       Activate();
       PopupMenu { null, this, menu = ob.clearMenu,
@@ -312,13 +338,13 @@ class OptionBox<class Z> : CommonControl
 
    bool Window::OptionBox_OnKeyDown(Key key, unichar ch)
    {
-      OptionBox ob = (OptionBox)id;
+      OptionBox ob = (OptionBox)(intptr)id;
       if(key == Key { del, ctrl = true } || key == Key { keyPadDelete, ctrl = true })
       {
          ob.Unset();
          return false;
       }
-      return (((bool(*)(Window, Key, unichar)) ob.chainKeyDown)(this, key, ch);
+      return ((bool(*)(Window, Key, unichar)) ob.chainKeyDown)(this, key, ch);
    }
 
    // code: 0 = not set anywhere, 1 = overridden here, 2 = inherited
@@ -336,7 +362,7 @@ class OptionBox<class Z> : CommonControl
                break;
          }
       }
-      
+
       if(!c)
       {
          label = null;
@@ -415,10 +441,10 @@ class OptionBox<class Z> : CommonControl
          buildTab = (BuildTab)buildTab.master;
       if(buildTab) buildTab.modifiedDocument = true;
    }
-   
+
    void Unset()
    {
-      char * platformName = platform ? platform.OnGetString(0,0,0) : null;
+      const char * platformName = platform ? platform.OnGetString(0,0,0) : null;
       MarkBuildTabModified();
 
       if(config)
@@ -523,7 +549,7 @@ class OptionBox<class Z> : CommonControl
    void FigureOutInherited()
    {
       ProjectNode node;
-      char * platformName = platform ? platform.OnGetString(0,0,0) : null;
+      const char * platformName = platform ? platform.OnGetString(0,0,0) : null;
       bool skipped = false;
       for(node = currentNode; node; node = node.parent)
       {
@@ -545,7 +571,7 @@ class OptionBox<class Z> : CommonControl
                      skipped = true;
                      break;
                   }
-               }               
+               }
 
                if(skipped && c.options && OptionSet(c.options))
                {
@@ -576,7 +602,7 @@ class OptionBox<class Z> : CommonControl
 
    void Retrieve()
    {
-      char * platformName = platform ? platform.OnGetString(0,0,0) : null;
+      const char * platformName = platform ? platform.OnGetString(0,0,0) : null;
       MarkBuildTabModified();
       if(config)
       {
@@ -626,7 +652,7 @@ class OptionBox<class Z> : CommonControl
    void Load()
    {
       ProjectNode node;
-      char * platformName = platform ? platform.OnGetString(0,0,0) : null;
+      const char * platformName = platform ? platform.OnGetString(0,0,0) : null;
       bool setAttribs = false;
       for(node = currentNode; node; node = node.parent)
       {
@@ -649,7 +675,7 @@ class OptionBox<class Z> : CommonControl
                      }
                      break;
                   }
-               }               
+               }
 
                nodeConfig = c;
                break;
@@ -706,7 +732,7 @@ class StringOptionBox : OptionBox<String>
    {
       bool NotifyModified(EditBox editBox)
       {
-         ((OptionBox)editBox.id).Retrieve();
+         ((OptionBox)(intptr)editBox.id).Retrieve();
          return true;
       }
 
@@ -756,7 +782,7 @@ class PathOptionBox : OptionBox<String>
       bool NotifyModified(PathBox pathBox)
       {
          FixPathOnPathBoxNotifyModified(pathBox);
-         ((OptionBox)pathBox.id).Retrieve();
+         ((OptionBox)(intptr)pathBox.id).Retrieve();
          return true;
       }
    };
@@ -813,12 +839,11 @@ class MultiStringOptionBox : OptionBox<Array<String>>
 
          if(tempStrings)
          {
-            Array<String> ts = tempStrings;
             while(it.Next())
             {
                String s = it.data;
                bool found = false;
-               for(i : tempStrings; !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
+               for(i : tempStrings; i && s && !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
                if(found && (!configReplaces || platform))   // ADDED || platform here...
                {
                   delete s;
@@ -844,7 +869,7 @@ class MultiStringOptionBox : OptionBox<Array<String>>
    {
       if(mergeValues)
       {
-         Array<String> strings = options ? *((Array<String>*)((byte *)options + option) : null;
+         Array<String> strings = options ? *(Array<String>*)((byte *)options + option) : null;
          if(strings)
          {
             if(!tempStrings)
@@ -852,11 +877,11 @@ class MultiStringOptionBox : OptionBox<Array<String>>
             for(s : strings)
             {
                bool found = false;
-               for(i : tempStrings; !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
+               for(i : tempStrings; i && s && !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
                if(!found) tempStrings.Add(s);
             }
          }
-      }         
+      }
       else
       {
          SetStrings(options ? *(Array<String>*)((byte *)options + option) : null);
@@ -902,7 +927,7 @@ class StringArrayOptionBox : MultiStringOptionBox
    {
       bool NotifyModified(EditBox editBox)
       {
-         ((OptionBox)editBox.id).Retrieve();
+         ((OptionBox)(intptr)editBox.id).Retrieve();
          return true;
       }
    };
@@ -910,21 +935,23 @@ class StringArrayOptionBox : MultiStringOptionBox
    // NO VIRTUAL PROPERTIES YET...
    Array<String> GetStrings() { return ((StringListBox)editor).strings; }
    void SetStrings(Array<String> value) { ((StringListBox)editor).strings = value; }
+
+   property const char * switchToKeep { set { ((StringListBox)editor).switchToKeep = value; ((StringListBox)editor).lenSwitchToKeep = strlen(value); } };
 }
 
 class StringsArrayOptionBox : MultiStringOptionBox
 {
    editor = StringsBox
    {
-      bool OnCreate()
+      /*bool OnCreate()
       {
          project = ::project;
          return true;
-      }
+      }*/
 
       bool NotifyModified(StringsBox stringsBox)
       {
-         ((OptionBox)stringsBox.id).Retrieve();
+         ((OptionBox)(intptr)stringsBox.id).Retrieve();
          return true;
       }
    };
@@ -937,7 +964,6 @@ bool eString_IsPathRelatedTo(char * path, char * to)
 {
    if(path[0] && to[0])
    {
-      char rest[MAX_FILENAME];
       char pathPart[MAX_FILENAME], pathRest[MAX_LOCATION] = "";
       char toPart[MAX_FILENAME], toRest[MAX_LOCATION] = "";
       SplitDirectory(path, pathPart, pathRest);
@@ -960,33 +986,8 @@ static void FixPathOnPathBoxNotifyModified(PathBox pathBox)
 {
    int len;
    char path[MAX_LOCATION];
-#ifdef __WIN32__
-   bool volumePath = false;
-#endif
-   strcpy(path, pathBox.path);
-   TrimLSpaces(path, path);
-   TrimRSpaces(path, path);
-   MakeSystemPath(path);
-#ifdef __WIN32__
-   if(path[0] && path[1] == ':')
-   {
-      path[1] = '_';
-      volumePath = true;
-   }
-#endif
-   {
-      char * chars = "*|:\",<>?";
-      char ch, * s = path, * o = path;
-      while((ch = *s++)) { if(!strchr(chars, ch)) *o++ = ch; }
-      *o = '\0';
-   }
+   ValidPathBufCopy(path, pathBox.path);
    len = strlen(path);
-   if(len>1 && path[len-1] == DIR_SEP)
-      path[--len] = '\0';
-#ifdef __WIN32__
-   if(volumePath && path[0])
-      path[1] = ':';
-#endif
    if(len && !(path[0] == '.' && (len == 1 || (len == 2 && path[1] == DIR_SEP) || (len > 1 && path[1] == '.'))))
    {
       char cwdBackup[MAX_LOCATION];
@@ -1002,17 +1003,63 @@ static void FixPathOnPathBoxNotifyModified(PathBox pathBox)
          MakePathRelative(path, project.topNode.path, path);
       if(!path[0])
          strcpy(path, ".");
+      len = strlen(path);
    }
+   if(len>1 && path[len-1] == DIR_SEP)
+      path[--len] = '\0';
    pathBox.path = path;
 }
 
 class DirsArrayOptionBox : MultiStringOptionBox
 {
+public:
+   property const char * switchToKeep { set { switchToKeep = value; lenSwitchToKeep = strlen(value); } };
+private:
+   const char * switchToKeep;
+   int lenSwitchToKeep;
+
    editor = DirectoriesBox
    {
+      browseDialog = { };
       bool NotifyModified(DirectoriesBox dirsBox)
       {
-         ((OptionBox)dirsBox.id).Retrieve();
+         const char * switchToKeep = ((DirsArrayOptionBox)(intptr)dirsBox.id).switchToKeep;
+         if(switchToKeep && switchToKeep[0])
+         {
+            bool change = false;
+            int lenSwitchToKeep = ((DirsArrayOptionBox)(intptr)dirsBox.id).lenSwitchToKeep;
+            Array<String> dirs { };
+            Array<String> previousDirs = dirsBox.strings;
+            for(d : previousDirs)
+            {
+               int c;
+               char * buffer = new char[strlen(d)+64];
+               char * tokens[1024];
+               uint count;
+               strcpy(buffer, d);
+               count = Tokenize(buffer, sizeof(tokens)/sizeof(tokens[0]), tokens, (BackSlashEscaping)false);
+               for(c=0; c<count; c++)
+               {
+                  if(tokens[c][0] == '-')
+                  {
+                     if(strstr(tokens[c]+1, switchToKeep) == tokens[c]+1)
+                        tokens[c] += lenSwitchToKeep+1;
+                     else
+                        tokens[c][0] = '\0';
+                     change = true;
+                  }
+                  dirs.Add(CopyString(tokens[c]));
+               }
+               delete buffer;
+            }
+            if(change)
+               dirsBox.strings = dirs;
+            dirs.Free();
+            delete dirs;
+            previousDirs.Free();
+            delete previousDirs;
+         }
+         ((OptionBox)(intptr)dirsBox.id).Retrieve();
          return true;
       }
 
@@ -1035,7 +1082,7 @@ class BoolOptionBox : OptionBox<SetBool>
 
       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
-         ((OptionBox)button.id).Retrieve();
+         ((OptionBox)(intptr)button.id).Retrieve();
          return true;
       }
    };
@@ -1048,7 +1095,7 @@ class BoolOptionBox : OptionBox<SetBool>
    void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
    {
       bool checked = ((Button)editor).checked;
-      *(SetBool*)((byte *)options + option) = checked ? true : 
+      *(SetBool*)((byte *)options + option) = checked ? true :
          ((currentNode.parent || isCfgOrPlt) ? false : unset);
    }
 
@@ -1066,14 +1113,14 @@ class CheckBoxForEnumOptionBox : OptionBox
 
       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
-         ((OptionBox)button.id).Retrieve();
+         ((OptionBox)(intptr)button.id).Retrieve();
          {
             Window slave;
             for(slave = master.firstSlave; slave; slave = slave.nextSlave)
             {
                if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
-                     slave != (Window)button.id &&
-                     ((OptionBox)slave).option == ((OptionBox)button.id).option)
+                     slave != (Window)(intptr)button.id &&
+                     ((OptionBox)slave).option == ((OptionBox)(intptr)button.id).option)
                   ((OptionBox)slave).Load();
             }
          }
@@ -1104,10 +1151,10 @@ class DropOptionBox : OptionBox
    {
       bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
       {
-         ((OptionBox)dropBox.id).Retrieve();
+         ((OptionBox)(intptr)dropBox.id).Retrieve();
          return true;
       }
-   };   
+   };
 
    void LoadOption(ProjectOptions options)
    {
@@ -1212,7 +1259,7 @@ void DrawStipple(Surface surface, Size clientSize)
 
    surface.LineStipple(0x5555);
    surface.Rectangle(x1, y1, x2, y2);
-   surface.LineStipple(0);            
+   surface.LineStipple(0);
 }
 
 class BuildTab : Tab
@@ -1226,7 +1273,7 @@ class BuildTab : Tab
 
    ProjectNode lastSelectedNode;
 
-   property char * selectedConfigName
+   property const char * selectedConfigName
    {
       get
       {
@@ -1235,7 +1282,7 @@ class BuildTab : Tab
             SelectorButton button = (SelectorButton)configSelector.selectedButton;
             if(button && button.id)
             {
-               ProjectConfig config = (ProjectConfig)button.id;
+               ProjectConfig config = (ProjectConfig)(intptr)button.id;
                return config.name;
             }
          }
@@ -1243,7 +1290,7 @@ class BuildTab : Tab
       }
    }
 
-   property char * selectedPlatformName
+   property const char * selectedPlatformName
    {
       get
       {
@@ -1253,7 +1300,7 @@ class BuildTab : Tab
             if(button && button.id)
             {
                Platform platform = (Platform)button.id;
-               char * platformName = platform ? platform.OnGetString(0,0,0) : null; // all these platformName are leaking, no? 
+               const char * platformName = platform ? platform.OnGetString(0,0,0) : null; // all these platformName are leaking, no?
                return platformName;
             }
          }
@@ -1291,7 +1338,7 @@ class BuildTab : Tab
          }
          return SelectorBar::OnKeyDown(key, ch);
       }
-      
+
       bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
       {
          ((BuildTab)master).labelConfigurations.Update(null);
@@ -1336,11 +1383,11 @@ class BuildTab : Tab
          config.options.debug = true;
          config.options.optimization = none;
          config.options.warnings = all;
-         */         
+         */
 
          button =
          {
-            configSelector, renameable = true, master = this, text = config.name, id = (int64)config;
+            configSelector, renameable = true, master = this, text = config.name, id = (int64)(intptr)config;
             NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
          };
 
@@ -1371,7 +1418,7 @@ class BuildTab : Tab
             String msg = PrintString($"Are you sure you wish to delete the ", config.name, $" configuration?");
             if(MessageBox { type = okCancel, text = title, contents = msg }.Modal() == ok)
             {
-               Iterator<Window> it { configSelector.controls };
+               //Iterator<Window> it { configSelector.controls };
                ProjectConfig configToDelete = config;
                /*
                while(it.Next())
@@ -1392,7 +1439,7 @@ class BuildTab : Tab
                   }
                }
                */
-               SelectorButton button = configSelector.FindButtonByID((int64)configToDelete);
+               SelectorButton button = configSelector.FindButtonByID((int64)(intptr)configToDelete);
                if(button)
                   configSelector.RemoveButton(button);
 
@@ -1406,7 +1453,7 @@ class BuildTab : Tab
          return true;
       }
    };
-   
+
    Label labelPlatforms
    {
       this, anchor = { left = 8, top = 44 }, labeledWindow = platformSelector;
@@ -1444,7 +1491,7 @@ class BuildTab : Tab
       text = $"(Right click or press Ctrl-Del to revert an option to inherited value)", anchor = { top = 72, right = 16 }
    };
 
-   void FindUniqueConfigName(char * baseName, bool startWithNumber, char * output)
+   void FindUniqueConfigName(const char * baseName, bool startWithNumber, char * output)
    {
       int num = 0;
       char tmp[MAX_F_STRING];
@@ -1544,7 +1591,7 @@ class BuildTab : Tab
       }
 
       project.topNode.RenameConfig(config.name, *newName);
-      
+
       modifiedDocument = true;
       return true;
    }
@@ -1553,7 +1600,7 @@ class BuildTab : Tab
    {
       if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
       {
-         config = (ProjectConfig)clickedButton.id;
+         config = (ProjectConfig)(intptr)clickedButton.id;
 
          // Load Settings Into Dialog
          compilerTab.LoadSettings();
@@ -1584,7 +1631,7 @@ class BuildTab : Tab
          if(!node) node = project.topNode;
 
          newNodeRes = node.isInResources;
-         
+
          currentNode = node;
          if(!ignoreAsLastSelection)
             lastSelectedNode = node;
@@ -1596,13 +1643,13 @@ class BuildTab : Tab
          }
          else
          {
-            compilerTab.rightPaneHeader.id = (int64)node;
+            compilerTab.rightPaneHeader.id = (int64)(intptr)node;
             compilerTab.rightPaneHeader.Update(null);
             compilerTab.rightPaneHeader.visible = true;
          }
 
          {
-            DataRow row = compilerTab.fileList.FindSubRow((int64)currentNode);
+            DataRow row = compilerTab.fileList.FindSubRow((int64)(intptr)currentNode);
             if(row)
             {
                compilerTab.fileList.currentRow = row;
@@ -1633,7 +1680,7 @@ class BuildTab : Tab
             compilerTab.labelIncludeDirs.visible = !newNodeRes;
             compilerTab.includeDirs.visible = !newNodeRes;
          }
-         
+
          if(node == project.topNode)
          {
             compilerTab.objDir.visible = true;
@@ -1670,16 +1717,14 @@ class BuildTab : Tab
 
    void CreateConfigButtons()
    {
-      SelectorButton commonButton;
-
       // Create Config Buttons
-      commonButton = SelectorButton
+      SelectorButton
       {
-         configSelector, master = this, text = $"Common", id = (int64)null; font = { font.faceName, font.size, true };
+         configSelector, master = this, text = $"Common", id = 0; font = { font.faceName, font.size, true };
          checked = true;
          NotifyClicked = ConfigClicked;
       };
-      
+
       config = null;
 
       if(project.topNode.configurations)
@@ -1688,20 +1733,20 @@ class BuildTab : Tab
          {
             EditableSelectorButton button
             {
-               configSelector, master = this, renameable = true, text = c.name, id = (int64)c;
+               configSelector, master = this, renameable = true, text = c.name, id = (int64)(intptr)c;
                NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
             };
          }
       }
    }
-   
+
    void Init()
    {
       Platform p;
       SelectorButton button;
 
       activeConfigName = project.config ? CopyString(project.config.name) : null;
-      
+
       compilerTab.AddNode(project.topNode, null);
 
       CreateConfigButtons();
@@ -1718,7 +1763,7 @@ class BuildTab : Tab
       {
          SelectorButton button
          {
-            platformSelector, master = this, text = p.OnGetString(0,0,0), id = (int64)p; 
+            platformSelector, master = this, text = p.OnGetString(0,0,0), id = (int64)p;
             NotifyClicked = PlatformClicked;
          };
       }
@@ -1737,12 +1782,12 @@ class BuildTab : Tab
          while(it.Next())
          {
             SelectorButton configButton = (SelectorButton)it.data;
-            ProjectConfig buttonConfig = (ProjectConfig)configButton.id;
+            ProjectConfig buttonConfig = (ProjectConfig)(intptr)configButton.id;
             if(buttonConfig == project.config)
             {
                configButton.Activate();
                configButton.checked = true;
-               ConfigClicked(configButton, 0, 0, (Modifiers)null);
+               ConfigClicked(configButton, 0, 0, 0);
                break;
             }
          }
@@ -1807,7 +1852,7 @@ class BuildTab : Tab
          while(it.Next())
          {
             Button button = (Button)it.data;
-            ProjectConfig c = (ProjectConfig)button.id;
+            ProjectConfig c = (ProjectConfig)(intptr)button.id;
             if(c && !strcmp(c.name, configName))
             {
                config = c;
@@ -1874,7 +1919,7 @@ class CompilerTab : Tab
       bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
       {
          BuildTab buildTab = (BuildTab)master;
-         ProjectNode node = (ProjectNode)row.tag;
+         ProjectNode node = (ProjectNode)(intptr)row.tag;
          buildTab.SelectNode(node, false);
          return true;
       }
@@ -1910,7 +1955,7 @@ class CompilerTab : Tab
       }
    };
 
-   Window rightPane 
+   Window rightPane
    {
       this, anchor = { left = 196, top = 0, right = 0, bottom = 0 }, background = formColor, tabCycle = true;
    };
@@ -1926,7 +1971,7 @@ class CompilerTab : Tab
          {
             ide.projectView.drawingInProjectSettingsDialogHeader = true;
             ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)class(ProjectNode)._vTbl[__ecereVMethodID_class_OnDisplay])(class(ProjectNode),
-               (void *)id, surface, 8, 2, clientSize.w, ide.projectView, Alignment::left, DataDisplayFlags { selected = true });
+               (void *)(intptr)id, surface, 8, 2, clientSize.w, ide.projectView, Alignment::left, DataDisplayFlags { selected = true });
             ide.projectView.drawingInProjectSettingsDialogHeader = false;
          }
       }
@@ -2025,7 +2070,7 @@ class CompilerTab : Tab
    DirsArrayOptionBox includeDirs
    {
       rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 250, right = 8, bottom = 8 };
-      text = $"Additional Include Directories", hotKey = altI, option = OPTION(includeDirs);
+      text = $"Additional Include Directories", hotKey = altI, option = OPTION(includeDirs), switchToKeep = "I";
    };
 
    CompilerTab()
@@ -2045,13 +2090,13 @@ class CompilerTab : Tab
    {
       DataRow row = addTo ? addTo.AddRow() : fileList.AddRow();
 
-      row.tag = (int64)node;
+      row.tag = (int64)(intptr)node;
 
       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)
@@ -2074,7 +2119,7 @@ class CompilerTab : Tab
       if(activeChild && activeChild.active)
       {
          Window control = activeChild;
-         control.Deactivate();         
+         control.Deactivate();
          control.Activate();
       }
    }
@@ -2097,14 +2142,14 @@ class LinkerTab : Tab
       this, position = { 8, 24 }, size = { 200, 22 };
       text = $"Target Name", hotKey = altN, option = OPTION(targetFileName);
    };
-   
+
    Label labelTargetType { this, position = { 216, 8 }, labeledWindow = targetType };
    TargetTypeDB targetType
    {
       this, position = { 216, 24 }, size = { 120, 22 };
       text = $"Target Type", hotKey = altT, option = OPTION(targetType);
    };
-   
+
    Label labelTargetDirectory { this, position = { 344, 8 }, labeledWindow = targetDirectory };
    PathOptionBox targetDirectory
    {
@@ -2116,7 +2161,7 @@ class LinkerTab : Tab
    StringArrayOptionBox libraries
    {
       this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
-      text = $"Additional Libraries", hotKey = altL, option = OPTION(libraries);
+      text = $"Additional Libraries", hotKey = altL, option = OPTION(libraries), switchToKeep = "l";
       configReplaces = true;
    };
 
@@ -2144,7 +2189,7 @@ class LinkerTab : Tab
    DirsArrayOptionBox libraryDirs
    {
       this, size = { 290, 22 }, anchor = { left = 8, top = 182, right = 8, bottom = 8 };
-      text = $"Additional Library Directories", hotKey = altY, option = OPTION(libraryDirs);
+      text = $"Additional Library Directories", hotKey = altY, option = OPTION(libraryDirs), switchToKeep = "L";
    };
 
    bool OnCreate()
@@ -2164,7 +2209,7 @@ class LinkerTab : Tab
       if(activeChild && activeChild.active)
       {
          Window control = activeChild;
-         control.Deactivate();         
+         control.Deactivate();
          control.Activate();
       }
    }
@@ -2178,20 +2223,26 @@ class BuilderTab : Tab
    Label labelPrebuildCommands { prebuildCommands.editor, labeledWindow = prebuildCommands, position = { 0, 6 }; };
    StringsArrayOptionBox prebuildCommands
    {
-      this, size = { 290, 100 }, anchor = { left = 8, top = 8, right = 8, bottom = 0.5 };
+      this, size = { 290, 92 }, anchor = { left = 8, top = 8, right = 8, bottom = 200 };
       text = $"Pre-build Commands", hotKey = altE, option = OPTION(prebuildCommands);
    };
 
    Label labelPostbuildCommands { postbuildCommands.editor, labeledWindow = postbuildCommands, position = { 0, 6 }; };
    StringsArrayOptionBox postbuildCommands
    {
-      this, size = { 290 }, anchor = { left = 8, top = 0.5, right = 8, bottom = 8 };
+      this, size = { 290, 92 }, anchor = { left = 8, top = 100, right = 8, bottom = 100 };
       text = $"Post-build Commands", hotKey = altT, option = OPTION(postbuildCommands);
    };
 
+   Label labelInstallCommands { installCommands.editor, labeledWindow = installCommands, position = { 0, 6 }; };
+   StringsArrayOptionBox installCommands
+   {
+      this, size = { 290, 92 }, anchor = { left = 8, top = 200, right = 8, bottom = 8 };
+      text = $"Install Commands", hotKey = altT, option = OPTION(installCommands);
+   };
+
    void LoadSettings()
    {
-      bool disabled = strlen(((BuildTab)master).selectedPlatformName) > 0;
       OptionBox ob;
       for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
          if(eClass_IsDerived(ob._class, class(OptionBox)))
@@ -2200,8 +2251,16 @@ class BuilderTab : Tab
       if(activeChild && activeChild.active)
       {
          Window control = activeChild;
-         control.Deactivate();         
+         control.Deactivate();
          control.Activate();
       }
    }
+
+   void OnResize(int width, int height)
+   {
+      int h = (height - 8 * 4) / 3;
+      prebuildCommands.anchor = { left = 8, top = 8, right = 8, bottom = h * 2 + 8 * 3 };
+      postbuildCommands.anchor = { left = 8, top = h + 8 * 2, right = 8, bottom = h + 8 * 2 };
+      installCommands.anchor = { left = 8, top = h * 2 + 8 * 3, right = 8, bottom = 8 };
+   }
 }