compiler/libec; ecere; ide: (Emscripten WIP) Address virtual method issues
[sdk] / ide / src / designer / Sheet.ec
index 7f51649..cd4ee42 100644 (file)
@@ -2,10 +2,10 @@ import "ide"
 
 import "CodeObject"
 
-static void UnusedFunction()
+static __attribute__((unused)) void UnusedFunction()
 {
-   int a;
-   Module b;
+   int a = 0;
+   Module b = 0;
    a.OnGetString(0,0,0);
    a.OnFree();
    a.OnCopy(null);
@@ -39,7 +39,7 @@ void SetPropValue(Property prop, void * object, any_object value)
 
    if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
    {
-      prop.Set(object, value);
+      ((void (*)(void *, void *))(void *)prop.Set)(object, value);
    }
    // TOFIX: How to swiftly handle classes with base data type?
    else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
@@ -72,6 +72,7 @@ void SetPropValue(Property prop, void * object, any_object value)
    }
 }
 
+/*
 any_object GetPropValue(Property prop, Instance object)
 {
    if(object)
@@ -89,39 +90,41 @@ any_object GetPropValue(Property prop, Instance object)
       // TOFIX: How to swiftly handle classes with base data type?
       else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
       {
-         double d = ((double(*)())(void *)prop.Get)(object);
+         // NOTE: must return double by reference
+         double d = ((double(*)(void *))(void *)prop.Get)(object);
          return d;
       }
       else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
       {
-         float f =((float(*)())(void *)prop.Get)(object);
+         // NOTE: must return float by reference
+         float f =((float(*)(void *))(void *)prop.Get)(object);
          return f;
       }
       else if(type.typeSize == sizeof(int64))// || !strcmp(type.dataTypeString, "int64") || !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
       {
-         return ((int64(*)())(void *)prop.Get)(object);
+         return ((int64(*)(void *))(void *)prop.Get)(object);
       }
       else if(type.typeSize == sizeof(int))// || !strcmp(type.dataTypeString, "int") || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
       {
-         return ((int(*)())(void *)prop.Get)(object);
+         return ((int(*)(void *))(void *)prop.Get)(object);
       }
       else if(type.typeSize == sizeof(short int)) // || !strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||  !strcmp(type.dataTypeString, "int16"))
       {
-         return ((short(*)())(void *)prop.Get)(object);
+         return ((short(*)(void *))(void *)prop.Get)(object);
       }
       else if(type.typeSize == sizeof(byte))// || !strcmp(type.dataTypeString, "char") || !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
       {
-         return ((byte(*)())(void *)prop.Get)(object);
+         return ((byte(*)(void *))(void *)prop.Get)(object);
       }
       else
       {
-         return prop.Get(object);
+         return ((int (*)(void *))(void *)prop.Get)(object);
       }
    }
    else
       return 0;
 }
-
+*/
 void CopyProperty(Property prop, Instance dest, Instance src)
 {
    Class type = prop.dataTypeClass;
@@ -131,43 +134,43 @@ void CopyProperty(Property prop, Instance dest, Instance src)
    if(type.type == structClass)
    {
       void * propData = new0 byte[type.structSize];
-      prop.Get(src, propData);
-      prop.Set(dest, propData);
+      ((void (*)(void *, void *))(void *)prop.Get)(src, propData);
+      ((void (*)(void *, void *))(void *)prop.Set)(dest, propData);
       delete propData;
    }
    else if(type.type == normalClass || type.type == noHeadClass)
    {
       // TOCHECK: Why was there a return here?
-      /*return */prop.Set(dest, ((void*(*)())(void *)prop.Get)(src));
+      /*return */((void (*)(void *, void *))(void *)prop.Set)(dest, ((void*(*)(void *))(void *)prop.Get)(src));
    }
    // TOFIX: How to swiftly handle classes with base data type?
    else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
    {
-      ((void (*)(void *, double))(void *)prop.Set)(dest, ((double(*)())(void *)prop.Get)(src));
+      ((void (*)(void *, double))(void *)prop.Set)(dest, ((double(*)(void *))(void *)prop.Get)(src));
    }
    else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
    {
-      ((void (*)(void *, float))(void *)prop.Set)(dest, ((float(*)())(void *)prop.Get)(src));
+      ((void (*)(void *, float))(void *)prop.Set)(dest, ((float(*)(void *))(void *)prop.Get)(src));
    }
    else if(type.typeSize == sizeof(int64))// || !strcmp(type.dataTypeString, "int64") || !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
    {
-      ((void (*)(void *, int64))(void *)prop.Set)(dest, ((int64(*)())(void *)prop.Get)(src));
+      ((void (*)(void *, int64))(void *)prop.Set)(dest, ((int64(*)(void *))(void *)prop.Get)(src));
    }
    else if(type.typeSize == sizeof(int))// || !strcmp(type.dataTypeString, "int") || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
    {
-      ((void (*)(void *, int))(void *)prop.Set)(dest, ((int(*)())(void *)prop.Get)(src));
+      ((void (*)(void *, int))(void *)prop.Set)(dest, ((int(*)(void *))(void *)prop.Get)(src));
    }
    else if(type.typeSize == sizeof(short int)) // || !strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||  !strcmp(type.dataTypeString, "int16"))
    {
-      ((void (*)(void *, short))(void *)prop.Set)(dest, ((short(*)())(void *)prop.Get)(src));
+      ((void (*)(void *, short))(void *)prop.Set)(dest, ((short(*)(void *))(void *)prop.Get)(src));
    }
    else if(type.typeSize == sizeof(byte))// || !strcmp(type.dataTypeString, "char") || !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
    {
-      ((void (*)(void *, byte))(void *)prop.Set)(dest, ((byte(*)())(void *)prop.Get)(src));
+      ((void (*)(void *, byte))(void *)prop.Set)(dest, ((byte(*)(void *))(void *)prop.Get)(src));
    }
    else
    {
-      prop.Set(dest, prop.Get(src));
+      ((void (*)(void *, int))(void *)prop.Set)(dest, ((int (*)(void *))(void *)prop.Get)(src));
    }
 }
 
@@ -182,42 +185,42 @@ void GetProperty(Property prop, Instance object, DataValue value)
 #ifdef _DEBUG
          if(prop._class.module.application == __thisModule &&
             prop.dataTypeClass.module.application == ((Designer)GetActiveDesigner()).codeEditor.privateModule)
-            printf($"Warning");
+            printf("Warning");
 #endif
       }
 
       if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
       {
-         value.p = ((void*(*)())(void *)prop.Get)(object);
+         value.p = ((void*(*)(void *))(void *)prop.Get)(object);
       }
       // TOFIX: How to swiftly handle classes with base data type?
       else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
       {
-         value.d = ((double(*)())(void *)prop.Get)(object);
+         value.d = ((double(*)(void *))(void *)prop.Get)(object);
       }
       else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
       {
-         value.f = ((float(*)())(void *)prop.Get)(object);
+         value.f = ((float(*)(void *))(void *)prop.Get)(object);
       }
       else if(type.typeSize == sizeof(int64))// || !strcmp(type.dataTypeString, "int64") || !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
       {
-         value.i64 = ((int64(*)())(void *)prop.Get)(object);
+         value.i64 = ((int64(*)(void *))(void *)prop.Get)(object);
       }
       else if(type.typeSize == sizeof(int))// || !strcmp(type.dataTypeString, "int") || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
       {
-         value.i = ((int(*)())(void *)prop.Get)(object);
+         value.i = ((int(*)(void *))(void *)prop.Get)(object);
       }
       else if(type.typeSize == sizeof(short int)) // || !strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||  !strcmp(type.dataTypeString, "int16"))
       {
-         value.s = ((short(*)())(void *)prop.Get)(object);
+         value.s = ((short(*)(void *))(void *)prop.Get)(object);
       }
       else if(type.typeSize == sizeof(byte))// || !strcmp(type.dataTypeString, "char") || !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
       {
-         value.uc = ((byte(*)())(void *)prop.Get)(object);
+         value.uc = ((byte(*)(void *))(void *)prop.Get)(object);
       }
       else
       {
-         value.i = prop.Get(object);
+         value.i = ((int (*)(void *))(void *)prop.Get)(object);
       }
    }
    else
@@ -234,7 +237,7 @@ void SetProperty(Property prop, Instance object, DataValue value)
 
       if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
       {
-         prop.Set(object, value);
+         ((void (*)(void *, void *))(void *)prop.Set)(object, value);
       }
       // TOFIX: How to swiftly handle classes with base data type?
       else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
@@ -268,6 +271,9 @@ void SetProperty(Property prop, Instance object, DataValue value)
    }
 }
 
+static define sheetSelectionColor = Color { 170, 220, 255 };
+static define sheetSelectionText = black;
+
 class Sheet : Window
 {
    text = $"Sheet";
@@ -276,7 +282,7 @@ class Sheet : Window
    //tabCycle = true;
    size.w = 300;
    anchor = { left = 0, top = 0, bottom = 0 };
-   background = activeBorder;
+   background = formColor;
 
    Sheet()
    {
@@ -298,8 +304,8 @@ class Sheet : Window
 
       bool NotifySelect(DropBox control, DataRow row, Modifiers keyFlags)
       {
-         ObjectInfo selected = (ObjectInfo)(row ? row.tag : null);
-         ToolBox toolBox = ((IDE)parent).toolBox;
+         ObjectInfo selected = (ObjectInfo)(row ? (void *)(intptr)row.tag : null);
+         ToolBox toolBox = ((IDEWorkSpace)parent).toolBox;
 
          if(codeEditor && selected)
             codeEditor.SelectObject(selected);
@@ -323,7 +329,6 @@ class Sheet : Window
          if(selected && selected.instance && codeEditor)
          {
             Class _class;
-            int c = 0;
             int rowHeight = methods.rowHeight;
 
             propertyValue.userData = (void *)selected.instance;
@@ -395,7 +400,7 @@ class Sheet : Window
       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
          text = $"Properties";
-         button.font = { "Tahoma", 8.25f, bold = true };
+         button.font = { $"Tahoma", 8.25f, bold = true };
          methBtn.font = null;
 
          methods.visible = false;
@@ -407,7 +412,7 @@ class Sheet : Window
 
          properties.Activate();
 
-         // ((IDE)master).SheetSelected(Properties);
+         // ((IDEWorkSpace)master).SheetSelected(Properties);
          return true;
       }
    };
@@ -424,7 +429,7 @@ class Sheet : Window
       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
          text = $"Methods";
-         button.font = { "Tahoma", 8.25f, bold = true };
+         button.font = { $"Tahoma", 8.25f, bold = true };
          propBtn.font = null;
 
          properties.visible = false;
@@ -435,8 +440,8 @@ class Sheet : Window
          categorized.disabled = true;
 
          methods.Activate();
-                       
-         // ((IDE)master).SheetSelected(Methods);
+
+         // ((IDEWorkSpace)master).SheetSelected(Methods);
          return true;
       }
    };
@@ -453,6 +458,8 @@ class Sheet : Window
       hasVertScroll = true, alwaysEdit = true, collapseControl = true, resizable = true;
       background = viewsBackground;
       foreground = viewsText;
+      selectionText = sheetSelectionText;
+      selectionColor = sheetSelectionColor;
 
       bool NotifySelect(ListBox control, DataRow row, Modifiers keyFlags)
       {
@@ -493,7 +500,7 @@ class Sheet : Window
       {
          CodeObject object = control.GetData(methodName);
          if(object)
-            codeEditor.AddMethod(object.method);   
+            codeEditor.AddMethod(object.method);
          return false;
       }
 
@@ -502,7 +509,6 @@ class Sheet : Window
          CodeObject object = control.GetData(methodName);
          Menu menu { };
          PopupMenu popupMenu;
-         MenuItem item;
          if(object.overriden == 0)
          {
             MenuItem { menu, $"Override", o, enter, bold = true, NotifySelect = OverrideMethodSelected };
@@ -513,7 +519,7 @@ class Sheet : Window
                for(compatible = object.compatible.first; compatible; compatible = compatible.next)
                {
                   ClassFunction function = compatible.data;
-                  MenuItem { attachMenu, function.declarator.symbol.string, id = (int)function, NotifySelect = AttachMethodSelected };
+                  MenuItem { attachMenu, function.declarator.symbol.string, id = (int64)(intptr)function, NotifySelect = AttachMethodSelected };
                }
             }
          }
@@ -536,7 +542,7 @@ class Sheet : Window
                   ClassFunction function = compatible.data;
                   if(function != object.function)
                   {
-                     MenuItem { attachMenu, function.declarator.symbol.string, id = (int)function, NotifySelect = ReattachMethodSelected };
+                     MenuItem { attachMenu, function.declarator.symbol.string, id = (int64)(intptr)function, NotifySelect = ReattachMethodSelected };
                   }
                }
             }
@@ -589,12 +595,12 @@ class Sheet : Window
    DataField methodName { dataType = class(CodeObject) };
 
 #ifdef SHOW_METHODS
-   methBtn.font = { "Tahoma", 8.25, bold = true };
+   methBtn.font = { $"Tahoma", 8.25, bold = true };
    methBtn.checked = true;
    properties.visible = false;
    text = $"Methods";
 #else
-   propBtn.font = { "Tahoma", 8.25f, bold = true };
+   propBtn.font = { $"Tahoma", 8.25f, bold = true };
    propBtn.checked = true;
    methods.visible = false;
    text = $"Properties";
@@ -624,7 +630,7 @@ class Sheet : Window
       this, bevelOver = true, checked = true, inactive = true, position = { 0, 25 }, size = { 24, 24 };
       bitmap = { "<:ecere>elements/orderCategorized.png" };
       // isRadio = true;
-      
+
       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
          if(!categorized.checked)
@@ -649,7 +655,7 @@ class Sheet : Window
             dropBox.Clear();
             dropField.userData = codeEditor;
             methodName.userData = codeEditor;
-            
+
             if(codeEditor)
                codeEditor.EnumerateObjects(this);
           }
@@ -692,9 +698,9 @@ class Sheet : Window
       else if(key == escape)
       {
          Window activeClient = ide.activeClient;
-         if(activeClient) 
+         if(activeClient)
             activeClient.Activate();
-         else 
+         else
             ide.RepositionWindows(true);
       }
       return true;
@@ -715,8 +721,8 @@ class Sheet : Window
    void ListProperties(bool clear)
    {
       DataRow row = dropBox.currentRow;
-      ObjectInfo selected = row ? (ObjectInfo)row.tag : null;
-      
+      ObjectInfo selected = row ? (ObjectInfo)(intptr)row.tag : null;
+
       //int scroll = 0;
       bool categorized = this.categorized.checked;
       bool currentRow = false;
@@ -732,7 +738,7 @@ class Sheet : Window
             char * propName;
             while(propRow && propRow.parent && !propRow.parent.isHeader)
                propRow = row.parent;
-            
+
             propName = propRow.GetData(propertyName);
             strcpy(this.selectedProp, propName);
             selectedScroll = properties.scroll.y;
@@ -764,7 +770,6 @@ class Sheet : Window
          // Fill up the properties
          while(_class != selected.instance._class)
          {
-            BitMember bitMember = null;
             Class lastClass = _class;
             Property propIt;
 
@@ -775,8 +780,8 @@ class Sheet : Window
                if(propIt.isProperty)
                {
                   Property prop = eClass_FindProperty(selected.instance._class, propIt.name, GetPrivateModule());
-                  
-                  if(prop && prop.Set && prop.Get && prop.compiled)
+
+                  if(prop && prop.Set && prop.Get && prop.compiled && (!prop.category || strcmpi(prop.category, $"Deprecated")))
                   {
                      bool disabled = Code_IsPropertyDisabled(selected, prop.name);
                      bool bold;
@@ -786,18 +791,21 @@ class Sheet : Window
 
                      if(!strcmp(_class.name, "DesignerBase"))
                         disabled = true;
-                     bold = !disabled && Code_IsPropertyModified(test, selected, prop);                           
+                     bold = !disabled && Code_IsPropertyModified(test, selected, prop);
 
                      if(dataType)
                      {
                         DataRow row;
                         PropertyInfo info { prop, disabled, bold ? codeEditor.boldFont : codeEditor.normalFont };
-                        char * name = prop.category ? prop.category : $"Misc";
+                        const char * name = prop.category ? prop.category : $"Misc";
                         Category category = categories.FindName(name, false);
 
                         // Hide properties like this for now..
-                        if(name && !strcmp(name, "Private")) 
+                        if(name && !strcmp(name, "Private"))
+                        {
+                           delete info;
                            continue;
+                        }
 
                         if(!category)
                         {
@@ -816,13 +824,13 @@ class Sheet : Window
 
                         if(clear)
                         {
-                           row = categorized ? category.row.FindRow((int)prop) : properties.FindRow((int)prop);
+                           row = categorized ? category.row.FindRow((int64)(intptr)prop) : properties.FindRow((int64)(intptr)prop);
                            if(!row)
                               row = categorized ? category.row.AddRow() : properties.AddRow();
-                           row.tag = (int)prop;
+                           row.tag = (int64)(intptr)prop;
                         }
                         else
-                           row = categorized ? category.row.FindRow((int)prop) : properties.FindRow((int)prop);
+                           row = categorized ? category.row.FindRow((int64)(intptr)prop) : properties.FindRow((int64)(intptr)prop);
 
                         row.SetData(propertyName, prop.name);
                         row.SetData(propertyValue, info);
@@ -833,7 +841,7 @@ class Sheet : Window
                         if(!dataType.noExpansion && (dataType.type == structClass || dataType.type == normalClass || dataType.type == noHeadClass || dataType.type == bitClass))
                         {
                            DataMember member;
-                           
+
                            if(clear)
                               row.collapsed = true;
 
@@ -850,11 +858,11 @@ class Sheet : Window
                                     if(clear)
                                     {
                                        subRow = row.AddRow();
-                                       subRow.tag = (int)subProp;
+                                       subRow.tag = (int64)(intptr)subProp;
                                     }
                                     else
-                                       subRow = row.FindRow((int)subProp);
-                                    
+                                       subRow = row.FindRow((int64)(intptr)subProp);
+
                                     subRow.SetData(propertyName, subProp.name);
                                     subRow.SetData(propertyValue, info);
                                  }
@@ -866,10 +874,10 @@ class Sheet : Window
                                  if(clear)
                                  {
                                     subRow = row.AddRow();
-                                    subRow.tag = (int)member;
+                                    subRow.tag = (int64)(intptr)member;
                                  }
                                  else
-                                    subRow = row.FindRow((int)member);
+                                    subRow = row.FindRow((int64)(intptr)member);
 
                                  subRow.SetData(propertyName, member.name);
                                  subRow.SetData(propertyValue, info);
@@ -884,10 +892,10 @@ class Sheet : Window
                                     if(clear)
                                     {
                                        subRow = row.AddRow();
-                                       subRow.tag = (int)subMember;
+                                       subRow.tag = (int64)(intptr)subMember;
                                     }
                                     else
-                                       subRow = row.FindRow((int)subMember);
+                                       subRow = row.FindRow((int64)(intptr)subMember);
 
                                     subRow.SetData(propertyName, subMember.name);
                                     subRow.SetData(propertyValue, info);
@@ -909,7 +917,7 @@ class Sheet : Window
             if(!properties.currentRow)
             {
                bool found = false;
-               
+
                for(_class = selected.instance._class; _class; _class = _class.base)
                {
                   Property prop;
@@ -920,12 +928,12 @@ class Sheet : Window
                         if(_class.defaultProperty && !strcmp(prop.name, _class.defaultProperty))
                         {
                            DataRow row;
-                           char * name = prop.category ? prop.category : $"Misc";
+                           const char * name = prop.category ? prop.category : $"Misc";
                            Category category = categories.FindName(name, false);
-                           row = category ? (categorized ? category.row.FindRow((int)prop) : properties.FindRow((int)prop)) : null;
+                           row = category ? (categorized ? category.row.FindRow((int64)(intptr)prop) : properties.FindRow((int64)(intptr)prop)) : null;
                            properties.currentRow = row;
                            found = true;
-                           break;                                                                                                                              
+                           break;
                         }
                      }
                   }
@@ -944,7 +952,7 @@ class Sheet : Window
       }
    }
 
-   void AddObject(ObjectInfo object, char * name, CodeObjectType type, bool select)
+   void AddObject(ObjectInfo object, const char * name, CodeObjectType type, bool select)
    {
       DataRow after = null;
       DataRow row;
@@ -963,10 +971,10 @@ class Sheet : Window
       }
 
       row = (DataRow)dropBox.AddRowAfter(after);
-      
-      row.tag = (int)object;
 
-      codeObject = 
+      row.tag = (int64)(intptr)object;
+
+      codeObject =
       {
          object = object;
          name = name;
@@ -975,13 +983,13 @@ class Sheet : Window
       };
 
       if(type != typeClass)
-         bitmap = (char *)eClass_GetProperty(object.instance._class, "icon");
+         bitmap = (char *)(intptr)eClass_GetProperty(object.instance._class, "icon");
       if(bitmap)
       {
          codeObject.bitmap = { bitmap };
          AddResource(codeObject.bitmap);
       }
-      
+
       row.SetData(null, codeObject);
 
       if(select)
@@ -994,11 +1002,11 @@ class Sheet : Window
 
    void DeleteObject(ObjectInfo object)
    {
-      DataRow row = dropBox.FindRow((int)object);
+      DataRow row = dropBox.FindRow((int64)(intptr)object);
       if(row)
       {
          CodeObject codeObject = row.GetData(null);
-     
+
          if(codeObject.bitmap)
             RemoveResource(codeObject.bitmap);
          dropBox.DeleteRow(row);
@@ -1009,16 +1017,16 @@ class Sheet : Window
    {
       if(this)
       {
-         DataRow row = dropBox.FindRow((int)object);
+         DataRow row = dropBox.FindRow((int64)(intptr)object);
          this.object = object ? object.instance : null;
          propertyValue.userData = object ? (void *)object.instance : null;
          dropBox.SelectRow(row);
       }
    }
 
-   void RenameObject(ObjectInfo object, char * name)
+   void RenameObject(ObjectInfo object, const char * name)
    {
-      DataRow row = dropBox.FindRow((int)object);
+      DataRow row = dropBox.FindRow((int64)(intptr)object);
       CodeObject codeObject = row.GetData(null);
       // Isn't this useless? Shouldn't it be after?
       codeObject.name = name;
@@ -1037,7 +1045,7 @@ class Sheet : Window
       Property prop = propertyPtr ? propertyPtr.prop : null;
       Instance object = this.object;
       if(prop)
-      {   
+      {
          Class dataType = prop.dataTypeClass;
          if(!dataType)
             dataType = prop.dataTypeClass = eSystem_FindClass(codeEditor.privateModule, prop.dataTypeString);
@@ -1056,10 +1064,10 @@ class Sheet : Window
                if(dataType.type == structClass)
                {
                   data = new0 byte[dataType.structSize];
-                  prop.Get(object, data);
+                  ((void (*)(void *, void *))(void *)prop.Get)(object, data);
                   // CopyBytes((byte *)data + member.offset + propertyPtr.extraOffset, &setValue, subDataType.size);
                   CopyBytes((byte *)data + member.offset + propertyPtr.extraOffset, (void *)setValue, subDataType.dataType.size);
-                  prop.Set(object, data);
+                  ((void (*)(void *, void *))(void *)prop.Set)(object, data);
                }
                else if(dataType.type == normalClass || dataType.type == noHeadClass)
                {
@@ -1071,25 +1079,26 @@ class Sheet : Window
                      BitMember bitMember = (BitMember) member;
                      if(subDataType)
                      {
-                        DataValue value { 0 };
-                        value.ui = prop.Get(object);
+                        DataValue value { 0 };
+                        value.ui = ((uint (*)(void *))(void *)prop.Get)(object);
                         value.ui &= ~ (uint)bitMember.mask;
                         value.ui |= *(uint32 *)setValue << bitMember.pos;
-                        prop.Set(object, value.ui);
+                        ((void (*)(void *, uint))(void *)prop.Set)(object, value.ui);
                      }
                   }
                   else
                   {
+                     // TODO: What does this handle?
                      data = dataType.typeSize ? new0 byte[dataType.typeSize] : null;
-                     prop.Get(object, data);
+                     ((void (*)(void *, void *))(void *)prop.Get)(object, data);
                      // CopyBytes((byte *)data + member.offset + propertyPtr.extraOffset, &setValue, subDataType.typeSize);
                      CopyBytes((byte *)data + member.offset + propertyPtr.extraOffset, (void *)setValue, subDataType.dataType.size);
                      // TODO: Support non 32 bit datatypes here
-                     prop.Set(object, data);
+                     ((void (*)(void *, void *))(void *)prop.Set)(object, data);
                   }
                }
 
-               if(data) dataType._vTbl[__ecereVMethodID_class_OnFree](dataType,&data);
+               if(data) ((void (*)(void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnFree])(dataType,&data);
                delete data;
             }
          }
@@ -1106,35 +1115,35 @@ class Sheet : Window
                if(dataType.type == structClass)
                {
                   data = new0 byte[dataType.structSize];
-                  prop.Get(object, data);
-                  subProperty.Set(data, *(uint32 *)setValue);
-                  prop.Set(object, data);
+                  ((void (*)(void *, void *))(void *)prop.Get)(object, data);
+                  ((void (*)(void *, uint))(void *)subProperty.Set)(data, *(uint32 *)setValue);
+                  ((void (*)(void *, void *))(void *)prop.Set)(object, data);
                }
                else if(dataType.type == normalClass || dataType.type == noHeadClass)
                {
-                  Instance current = (Instance)prop.Get(object);
+                  Instance current = (Instance)((void *(*)(void *))(void *)prop.Get)(object);
                   Instance propObject = eInstance_New(dataType);
                   CopyInstanceData(dataType, propObject, current);
-                  subProperty.Set(propObject, (uint32)setValue);
-                  prop.Set(object, propObject);
+                  ((void (*)(void *, uint))(void *)subProperty.Set)(propObject, (uint32)setValue);
+                  ((void (*)(void *, void *))(void *)prop.Set)(object, propObject);
                }
                else
                {
                   data = dataType.typeSize ? new0 byte[dataType.typeSize] : null;
-                  prop.Get(object, data);
-                  subProperty.Set(data, (uint32)setValue);
+                  ((void (*)(void *, void *))(void *)prop.Get)(object, data);
+                  ((void (*)(void *, uint))(void *)subProperty.Set)(data, (uint32)setValue);
                   // TODO: Support not 32 bit data types here
-                  prop.Set(object, data);
+                  ((void (*)(void *, void *))(void *)prop.Set)(object, data);
                }
 
-               if(data) dataType._vTbl[__ecereVMethodID_class_OnFree](dataType,&data);
+               if(data) ((void (*)(void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnFree])(dataType,&data);
                delete data;
             }
          }
          else
          {
             SetPropValue(prop, object, (uint32)setValue);
-         }      
+         }
          Code_FixProperty(propertyPtr.prop, object);
 
          properties.Update(null);
@@ -1143,8 +1152,11 @@ class Sheet : Window
          codeEditor.Update(null);   // patch for redraw bug if on top
 
          ListProperties(false);
+         // DataRow values were changed by ListProperties, need to re-query
+         propertyPtr = properties.GetData(null);
+         if(propertyPtr)
+            dataBox.editor.font = { propertyPtr.font.faceName, propertyPtr.font.size, propertyPtr.font.bold };
 
-         dataBox.editor.font = { propertyPtr.font.faceName, propertyPtr.font.size, propertyPtr.font.bold };
          codeEditor.ModifyCode();
       }
    }
@@ -1179,31 +1191,28 @@ class Sheet : Window
 
    bool AttachMethodSelected(MenuItem selection, Modifiers mods)
    {
-      ClassFunction function = (ClassFunction)selection.id;
+      ClassFunction function = (ClassFunction)(intptr)selection.id;
       codeEditor.AttachMethod(attachMethod, function);
       return true;
    }
 
    bool ReattachMethodSelected(MenuItem selection, Modifiers mods)
    {
-      ClassFunction function = (ClassFunction)selection.id;
-      CodeObject object = methods.GetData(methodName);
+      ClassFunction function = (ClassFunction)(intptr)selection.id;
       codeEditor.ReAttachMethod(attachMethod, function);
       return true;
    }
 
    bool OverrideMethodSelected(MenuItem selection, Modifiers mods)
    {
-      ClassFunction function = (ClassFunction)selection.id;
       CodeObject object = methods.GetData(methodName);
       if(object)
-         codeEditor.AddMethod(object.method);   
+         codeEditor.AddMethod(object.method);
       return true;
    }
 
    bool GotoMethodSelected(MenuItem selection, Modifiers mods)
    {
-      ClassFunction function = (ClassFunction)selection.id;
       CodeObject object = methods.GetData(methodName);
       if(object)
          codeEditor.GoToMethod(object.method.name);
@@ -1212,7 +1221,6 @@ class Sheet : Window
 
    bool DetachMethodSelected(MenuItem selection, Modifiers mods)
    {
-      ClassFunction function = (ClassFunction)selection.id;
       CodeObject object = methods.GetData(methodName);
       if(object)
          codeEditor.DetachMethod(object.method, object.function, object.overriden);
@@ -1221,7 +1229,6 @@ class Sheet : Window
 
    bool DeleteMethodSelected(MenuItem selection, Modifiers mods)
    {
-      ClassFunction function = (ClassFunction)selection.id;
       CodeObject object = methods.GetData(methodName);
       if(object)
          object.deleteBtn.NotifyClicked(this, object.deleteBtn, 0,0,0);
@@ -1230,16 +1237,14 @@ class Sheet : Window
 
    bool AddMethodClicked(Button button, int x, int y, Modifiers mods)
    {
-      DataRow row = (DataRow)button.id;
+      DataRow row = (DataRow)(intptr)button.id;
       CodeObject object = row.GetData(methodName);
-      codeEditor.AddMethod(object.method);   
+      codeEditor.AddMethod(object.method);
       return true;
    }
 
    void CreateButtons(CodeObject codeObject, int y, int h, DataRow row)
    {
-      BitmapResource bitmap;
-      
       if(codeObject.overriden)
       {
          if(codeObject.overriden == 1)
@@ -1251,11 +1256,11 @@ class Sheet : Window
                bitmap = { ":actions/delete.png", alphaBlend = true },
                anchor = { right = 16, top = y },
                size = { 16, h },
-               id = (int)row;
+               id = (int64)(intptr)row;
 
                bool NotifyClicked(Button button, int x, int y, Modifiers mods)
                {
-                  CodeObject codeObject = ((DataRow)button.id).GetData(null);
+                  CodeObject codeObject = ((DataRow)(intptr)button.id).GetData(null);
                   bool confirmation = !Code_IsFunctionEmpty(codeObject.function, codeObject.method, codeEditor.selected);
 
                   if(confirmation)
@@ -1264,7 +1269,7 @@ class Sheet : Window
                      sprintf(title, $"Delete %s", codeObject.name);
                      if(MessageBox
                         {
-                           master = parent, type = okCancel, text = title, 
+                           master = parent, type = okCancel, text = title,
                            contents = $"Method still contains code. Are you sure you want to delete it?"
                         }.Modal() == ok)
                         confirmation = false;
@@ -1296,7 +1301,7 @@ class Sheet : Window
 
          if(codeObject.overriden == 2 || !codeObject.function.attached.count)
          {
-            codeObject.detachBtn = Button 
+            codeObject.detachBtn = Button
             {
                methods,
                master = methods.master,
@@ -1304,11 +1309,11 @@ class Sheet : Window
                bitmap = { ":actions/detach.png" },
                anchor = { right = 0, top = y },
                size = { 16, h },
-               id = (int)row;
+               id = (int64)(intptr)row;
 
                bool NotifyClicked(Button button, int x, int y, Modifiers mods)
                {
-                  DataRow row = (DataRow)button.id;
+                  DataRow row = (DataRow)(intptr)button.id;
                   CodeObject object = row.GetData(methodName);
 
                   codeEditor.DetachMethod(object.method, object.function, object.overriden);
@@ -1330,28 +1335,28 @@ class Sheet : Window
                bitmap = { ":actions/attach.png" },
                anchor = { right = 0, top = y },
                size = { 16, h },
-               id = (int)row;
+               id = (int64)(intptr)row;
 
                bool NotifyPushed(Button button, int x, int y, Modifiers mods)
                {
                   // Create menu
-                  DataRow row = (DataRow)button.id;
+                  DataRow row = (DataRow)(intptr)button.id;
                   CodeObject object = row.GetData(methodName);
                   OldLink compatible;
                   PopupMenu popupMenu;
 
                   Menu menu { };
-                  
+
                   for(compatible = object.compatible.first; compatible; compatible = compatible.next)
                   {
                      ClassFunction function = compatible.data;
-                     MenuItem { menu, function.declarator.symbol.string, id = (int)function, NotifySelect = AttachMethodSelected };
+                     MenuItem { menu, function.declarator.symbol.string, id = (int64)(intptr)function, NotifySelect = AttachMethodSelected };
                   }
                   attachMethod = object.method;
 
                   popupMenu = PopupMenu
-                  { 
-                     master = this, menu = menu, 
+                  {
+                     master = this, menu = menu,
                      position =
                      {
                         button.absPosition.x - app.desktop.position.x,
@@ -1378,7 +1383,7 @@ class Sheet : Window
    int selectedScroll;
 }
 
-static int String_OnCompare(char ** string1, char ** string2)
+static int String_OnCompare(const char ** string1, const char ** string2)
 {
    int result = 0;
    if(*string1 && *string2)
@@ -1397,7 +1402,7 @@ static void CopyInstanceData(Class dataType, Instance propObject, Instance curre
    {
       DataMember member;
       for(member = _class.membersAndProperties.first; member; member = member.next)
-      {               
+      {
          Class memberType = member.dataTypeClass;
          if(!memberType)
             memberType = member.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, member.dataTypeString);
@@ -1407,12 +1412,12 @@ static void CopyInstanceData(Class dataType, Instance propObject, Instance curre
             if(subProp.Get && subProp.Set)
                CopyProperty(subProp, propObject, current);
          }
-         else
+         else if(member.id > -1)
          {
             if(memberType)
                // TOCHECK: I have serious doubts this works in many cases.
-               memberType._vTbl[__ecereVMethodID_class_OnCopy](memberType, (byte *)propObject + member.offset, (byte *)current + member.offset);
-            else if(member.memberOffset)
+               ((void (*)(void *, void *, void *))(void *)memberType._vTbl[__ecereVMethodID_class_OnCopy])(memberType, (byte *)propObject + member.offset, (byte *)current + member.offset);
+            else
                memcpy((byte *)propObject + member.offset, (byte *)current + member.offset, member.memberOffset);
          }
       }
@@ -1425,7 +1430,7 @@ public:
    Property prop;
    bool disabled;
    FontResource font;
-   char * categoryName;
+   const char * categoryName;
    DataMember subMember;
    Property subProperty;
    uint extraOffset;
@@ -1436,7 +1441,7 @@ public:
 
       surface.TextFont(font.font);
       if(disabled)
-      {  
+      {
          surface.SetBackground(Color { 170, 170, 170 });
          surface.Area(0,0, x+width-1, y+100);
       }
@@ -1446,18 +1451,18 @@ public:
          Module module = ((Designer)GetActiveDesigner()).codeEditor.privateModule;
          if(!dataType)
             dataType = prop.dataTypeClass = eSystem_FindClass(module, prop.dataTypeString);
-         
+
          if(dataType && prop.Get)
          {
             void * dataPtr, * data = null, * subData = null;
             DataValue valueData, valueSubData;
             uint64 bitValue;
-            
+
             // Get main prop
             if(dataType.type == structClass)
             {
                data = new0 byte[dataType.structSize];
-               prop.Get(object, data);
+               ((void (*)(void *, void *))(void *)prop.Get)(object, data);
                dataPtr = data;
             }
             else
@@ -1469,7 +1474,7 @@ public:
                else
                   dataPtr = &valueData;
             }
-            
+
             // Get sub prop
             if(this.subMember)
             {
@@ -1502,7 +1507,7 @@ public:
                   if(subDataType.type == structClass)
                   {
                      subData = new0 byte[subDataType.structSize];
-                     subProperty.Get(dataPtr, subData);
+                     ((void (*)(void *, void *))(void *)subProperty.Get)(dataPtr, subData);
                      dataPtr = subData;
                   }
                   else
@@ -1518,7 +1523,7 @@ public:
             }
 
             if(dataType)
-               dataType._vTbl[__ecereVMethodID_class_OnDisplay](dataType, dataPtr, surface, x, y, width, null, alignment, displayFlags);
+               ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)dataType._vTbl[__ecereVMethodID_class_OnDisplay])(dataType, dataPtr, surface, x, y, width, null, alignment, displayFlags);
 
             delete data;
             delete subData;
@@ -1528,9 +1533,9 @@ public:
 
    Window OnEdit(DataBox dataBox, Window obsolete, int x, int y, int w, int h, void * unused)
    {
-      EditBox editData = null;
+      Window editData = null;
       Property prop = this.prop;
-      
+
       dataBox.SetData = Sheet::EditSetData;
       if(prop && prop.dataTypeString && !this.disabled)
       {
@@ -1545,23 +1550,36 @@ public:
             void * dataPtr, * data = null, * subData = null;
             DataValue valueData, valueSubData;
             uint64 bitValue;
-            
+            bool isEditBoxMultiLineContents = false;
+
             // Get main prop
             if(dataType.type == structClass)
             {
                data = new0 byte[dataType.structSize];
-               prop.Get(object, data);
+               ((void (*)(void *, void *))(void *)prop.Get)(object, data);
                dataPtr = data;
             }
             else
             {
-               GetProperty(prop, object, &valueData);
+               //bool freeDataForm = false, freeDataTest = false;
+               // Because contents property is broken for mutiline EditBox at the moment
+               if(!strcmp(prop.name, "contents") && !strcmp(prop._class.name, "EditBox") && ((EditBox)object).multiLine)
+               {
+                  isEditBoxMultiLineContents = true;
+                  dataType = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, "MultiLineString");
+                  valueData.p = ((EditBox)object).multiLineContents;
+                  dataBox.size.h = 3*(h-2);
+                  h = dataBox.clientSize.h;
+               }
+               else
+                  GetProperty(prop, object, &valueData);
+
                if(dataType.type == normalClass)
                   dataPtr = valueData.p;
                else
                   dataPtr = &valueData;
             }
-            
+
             // Get sub prop
             if(this.subMember)
             {
@@ -1594,7 +1612,7 @@ public:
                   if(subDataType.type == structClass)
                   {
                      subData = new0 byte[subDataType.structSize];
-                     subProperty.Get(dataPtr, subData);
+                     ((void (*)(void *, void *))(void *)subProperty.Get)(dataPtr, subData);
                      dataPtr = subData;
                   }
                   else
@@ -1610,12 +1628,31 @@ public:
             }
 
             if(dataType)
-               editData = (void *)dataType._vTbl[__ecereVMethodID_class_OnEdit](dataType, dataPtr, dataBox, obsolete,  x, y, w, h, object /*unused*/);
+            {
+               Window (* onEdit)(void *, void *, DataBox, void *, int, int, int, int, void*) = (void *)dataType._vTbl[__ecereVMethodID_class_OnEdit];
+               if(onEdit)
+                  editData = onEdit(dataType, dataPtr, dataBox, obsolete,  x, y, w, h, object /*unused*/);
+            }
 
             delete data;
             delete subData;
 
+            if(isEditBoxMultiLineContents)
+               delete valueData.p;
+
             editData.font = { font.faceName, font.size, font.bold };
+            if(eClass_IsDerived(editData._class, class(DropBox)))
+            {
+               DropBox db = (DropBox)editData;
+               db.selectionColor = sheetSelectionColor;
+               db.selectionText = sheetSelectionText;
+            }
+            else if(eClass_IsDerived(editData._class, class(EditBox)))
+            {
+               EditBox eb = (EditBox)editData;
+               eb.selectionColor = sheetSelectionColor;
+               eb.selectionText = sheetSelectionText;
+            }
          }
       }
       return editData;
@@ -1623,16 +1660,15 @@ public:
 
    int OnCompare(PropertyInfo data2)
    {
-      char * category1 = prop ? prop.category : categoryName;
-      char * category2 = data2.prop ? data2.prop.category : data2.categoryName;
+      const char * category1 = prop ? prop.category : categoryName;
+      const char * category2 = data2.prop ? data2.prop.category : data2.categoryName;
       int result;
 
       if(!category1) category1 = $"Misc";
       if(!category2) category2 = $"Misc";
-      
+
       if(!prop)
       {
-         // result = String::OnCompare((String)category1, (String)category2);
          result = String_OnCompare(&category1, &category2);
       }
       else
@@ -1679,7 +1715,7 @@ public:
          else
             // result = ((String)prop.name).OnCompare(data2.prop.name);
             // result = String::OnCompare((String)prop.name, (String)data2.prop.name);
-            result = String_OnCompare(&prop.name, &data2.prop.name);
+            result = String_OnCompare((const char **)&prop.name, (const char **)&data2.prop.name);
       }
       return result;
    }
@@ -1696,44 +1732,48 @@ public:
          bool result = false;
          void * dataPtr, * data = null, * subData = null;
          void * propObject = null;
-         DataValue valueData = { 0 }, valueSubData = { 0 };
+         DataValue valueData { 0 };
+         DataValue valueSubData { 0 };
          uint bitValue;
 
          if(!mainDataType)
             mainDataType = prop.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, prop.dataTypeString);
          dataType = mainDataType;
-         
+
+         // Because contents property is broken for mutiline EditBox at the moment
+         if(!strcmp(prop.name, "contents") && !strcmp(prop._class.name, "EditBox") && ((EditBox)object).multiLine)
+            dataType = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, "MultiLineString");
+
          // Prepare main prop
          if(dataType.type == structClass)
          {
             data = new0 byte[dataType.structSize];
             if(this.subMember || this.subProperty)
-               prop.Get(object, data);
+               ((void (*)(void *, void *))(void *)prop.Get)(object, data);
             dataPtr = data;
             propObject = data;
          }
          else if(dataType.type == normalClass || dataType.type == noHeadClass)
          {
             dataPtr = &valueData;
-            
+
             if(this.subMember || this.subProperty)
             {
-               Class _class;
-               Instance current = (Instance)prop.Get(object);
+               Instance current = (Instance)((void *(*)(void *))(void *)prop.Get)(object);
                propObject = valueData.p = eInstance_New(dataType);
                CopyInstanceData(dataType, propObject, current);
             }
          }
          else
          {
-            
+
             if(this.subMember || this.subProperty)
                GetProperty(prop, object, &valueData);
-            
+
             dataPtr = &valueData;
             propObject = &valueData;
          }
-         
+
          // Prepare sub prop
          if(this.subMember)
          {
@@ -1754,9 +1794,9 @@ public:
          {
             Property subProperty = this.subProperty;
             Class subDataType = subProperty.dataTypeClass;
-            
+
             if(!subDataType)
-               subDataType = subProperty.dataTypeClass = 
+               subDataType = subProperty.dataTypeClass =
                   eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, subProperty.dataTypeString);
             if(!subProperty.Get) subDataType = null;
             if(subDataType)
@@ -1774,7 +1814,8 @@ public:
 
          if(dataType)
          {
-            if(dataType._vTbl[__ecereVMethodID_class_OnSaveEdit](dataType, dataPtr, editControl, null))
+            bool (* onSaveEdit)(void *, void *, Window, void *) = (void *)dataType._vTbl[__ecereVMethodID_class_OnSaveEdit];
+            if(!onSaveEdit || onSaveEdit(dataType, dataPtr, editControl, null))
             {
                if(mainDataType.type == bitClass && this.subMember)
                {
@@ -1785,8 +1826,8 @@ public:
                if(this.subProperty)
                {
                   if(dataType.type == structClass)
-                     this.subProperty.Set(propObject, subData);
-                  else if(dataType.type == unitClass || dataType.type == enumClass || dataType.type == bitClass)
+                     ((void (*)(void *, void *))(void *)this.subProperty.Set)(propObject, subData);
+                  else if(dataType.type == unitClass || dataType.type == enumClass || dataType.type == bitClass || dataType.type == systemClass)
                   {
                      if(!strcmp(dataType.dataTypeString, "float"))
                         ((void(*)(void *,float))(void *)this.subProperty.Set)(propObject, valueSubData.f);
@@ -1796,15 +1837,15 @@ public:
                         ((void(*)(void *,byte))(void *)this.subProperty.Set)(propObject, valueSubData.uc);
                      else if(!strcmp(dataType.dataTypeString, "uint16"))
                         ((void(*)(void *,uint16))(void *)this.subProperty.Set)(propObject, valueSubData.us);
-                     else 
-                        this.subProperty.Set(propObject, valueSubData.ui);
+                     else
+                        ((void (*)(void *, uint))(void *)this.subProperty.Set)(propObject, valueSubData.ui);
                   }
                   else
-                     this.subProperty.Set(propObject, valueSubData.ui);
+                     ((void (*)(void *, void *))(void *)this.subProperty.Set)(propObject, valueSubData.p);
                }
                if(mainDataType.type == structClass)
-                  prop.Set(object, data);
-               else if(mainDataType.type == unitClass || mainDataType.type == enumClass || mainDataType.type == bitClass)
+                  ((void (*)(void *, void *))(void *)prop.Set)(object, data);
+               else if(mainDataType.type == unitClass || mainDataType.type == enumClass || mainDataType.type == bitClass || mainDataType.type == systemClass)
                {
                   if(!strcmp(mainDataType.dataTypeString, "float"))
                      ((void(*)(void *,float))(void *)prop.Set)(object, valueData.f);
@@ -1815,15 +1856,15 @@ public:
                   else if(!strcmp(mainDataType.dataTypeString, "uint16"))
                      ((void(*)(void *,uint16))(void *)prop.Set)(object, valueData.us);
                   else
-                     prop.Set(object, valueData.ui);
+                     ((void (*)(void *, uint))(void *)prop.Set)(object, valueData.ui);
                }
                else
-                  prop.Set(object, valueData.ui);
+                  ((void (*)(void *, void *))(void *)prop.Set)(object, valueData.p);
 
                result = true;
             }
-            if(data == dataPtr)     dataType._vTbl[__ecereVMethodID_class_OnFree](dataType, &data);
-            if(subData == dataPtr)  dataType._vTbl[__ecereVMethodID_class_OnFree](dataType, &subData);
+            if(data == dataPtr)     ((void (*)(void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnFree])(dataType, &data);
+            if(subData == dataPtr)  ((void (*)(void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnFree])(dataType, &subData);
          }
          delete data;
          delete subData;
@@ -1838,7 +1879,7 @@ public:
 class Category : struct
 {
    Category prev, next;
-   char * name;
+   const char * name;
    DataRow row;
    bool collapsed;
 };