2 public import static "ecere"
11 extern int __ecereVMethodID_class_OnGetString;
12 extern int __ecereVMethodID_class_OnCompare;
13 extern int __ecereVMethodID_class_OnUnserialize;
14 extern int __ecereVMethodID_class_OnSerialize;
15 extern int __ecereVMethodID_class_OnFree;
17 __attribute__((unused)) static void UnusedFunction()
25 a.OnEdit(null,null,0,0,0,0,0);
26 a.OnDisplay(null,0,0,0,0,0,0);
27 a.OnGetDataFromString(null);
28 a.OnUnserialize(null);
33 public class Id : uint64
35 class_data Table * table; class_property Table * table { set { class_data(table) = value; } get { return class_data(table); } };
36 //class_data Field * idField; class_property Field * idField { set { class_data(nameField) = value; } get { return class_data(idField); } };
37 //class_data Field * displayField; class_property Field * displayField { set { class_data(displayField) = value; } get { return class_data(displayField); } };
38 class_data Field * nameField; class_property Field * nameField { set { class_data(nameField) = value; } get { return class_data(nameField); } };
39 class_data char * addText; class_property char * addText { set { class_data(addText) = value; } };
40 class_data void * Refill; class_property void * Refill { set { class_data(Refill) = value; } };
42 Window OnEdit(DataBox dataBox, void * obsolete, int x, int y, int w, int h, void * userData)
44 TableDropBox dropBox = dataBox.keepEditor ? (TableDropBox)dataBox.editor /*obsolete*/ : null;
48 if(eClass_IsDerived(dataBox._class, class(FieldDropBox)))
50 FieldDropBox fieldDropBox = (FieldDropBox)dataBox;
53 else if(eClass_IsDerived(dataBox._class, class(FieldBox)))
55 FieldBox fieldBox = (FieldBox)dataBox;
60 dropBox = TableDropBox
62 dataBox, borderStyle = 0, anchor = { 0, 0, 0, 0 },
63 modifyVirtualArea = false, activeStipple = false;
65 nameField = class_data(nameField) ? *class_data(nameField) : null;
66 table = class_data(table) ? *class_data(table) : null;
68 bool DataBox::NotifySelect(DropBox control, DataRow row, Modifiers mods)
70 Id id = (Id)(row ? row.tag : 0);
71 SetData(&id, mods.closingDropDown);
75 bool DataBox::NotifyTextEntry(DropBox _dropBox, const char * string, bool confirmed)
77 TableDropBox dropBox = (TableDropBox)_dropBox;
78 //Table tbl = dropBox.table.db.OpenTable(dropBox.table.name, { tableRows });
81 /*FieldIndex indexedFields[1];
83 char * trimmed = new char[strlen(string) + 1];
84 /*indexedFields[0] = { dropBox.nameField };
85 tbl.GenerateIndex(1, indexedFields, false);
89 TrimLSpaces(string, trimmed);
90 TrimRSpaces(trimmed, trimmed);
92 /*if(r.Find(dropBox.nameField, middle, nil, trimmed))
94 if(dropBox.filterField)
96 // TODO: Improve this... Multi field?
101 Field fldId = dropBox.table.FindField(defaultIdField);
102 r.GetData(fldId, id);
103 row = dropBox.FindSubRow(id);
106 dropBox.SelectRow(row);
109 //if(!r.Find(dropBox.nameField, next, nil, trimmed))
117 Field fldId = dropBox.table.FindField(defaultIdField);
118 r.GetData(fldId, id);
119 dropBox.SelectRow(dropBox.FindSubRow(id));
125 for(row = dropBox.firstRow; row; row = row.next)
127 const char * string = row.string;
128 if(string && !strcmp(trimmed, string))
134 dropBox.SelectRow(row);
138 dropBox.changeContents = false;
139 dropBox.contents = trimmed;
140 dropBox.SelectRow(null);
141 dropBox.changeContents = true;
148 if(class_data(Refill))
149 dropBox.Refill = class_data(Refill);
153 dataBox.OnConfigure(dropBox);
155 dropBox.currentRow = dropBox.FindSubRow(this);
156 if(!dropBox.currentRow && this)
157 dataBox.SetData((Id *)&this, false);
159 DataRow r = dropBox.currentRow;
161 for(r = r.parent; r; r = r.parent)
167 const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
173 Table tbl = class_data(table) ? *class_data(table) : null;
176 Field idField = tbl.FindField(defaultIdField);
178 idRowCacheMutex.Wait();
181 tbl.cachedIdRow = Row { tbl };
182 incref tbl.cachedIdRow;
188 if(r.Find(idField, middle, nil, thisID))
191 Field * nameField = class_data(nameField);
195 //const char * fn = nameField->name;
197 // Get name data from row
199 Class type = nameField->type;
200 if(type.type == unitClass && !type.typeSize)
202 Class dataType = eSystem_FindClass(type.module, type.dataTypeString);
206 if(type.type == structClass)
207 data = (int64)(intptr)new0 byte[type.structSize];
208 ((bool (*)())(void *)r.GetData)(r, *nameField, type, (type.type == structClass) ? (void *)(intptr)data : &data);
210 if(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass)
211 name = ((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, (void *)&data, tempString, null, null);
213 name = ((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, (void *)(intptr)data, tempString, null, null);
215 if(name && name != tempString)
216 strcpy(tempString, name ? name : "");
217 if(!(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass))
218 ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, (void *)(intptr)data);
222 PrintLn("Id::OnGetString -- data type"/*, this._class.name, */" has no class_data(nameField)");
227 sprintf(tempString, "(Invalid %s entry: "
228 #if defined(__WIN32__)
233 ")", tbl.name, thisID);
238 sprintf(tempString, $"(Click to add a new %s...)", $"item"/*class_data(addText)*/);
241 idRowCacheMutex.Release();
246 id.OnGetString(tempString, null, null);
258 class_data Class type;
259 class_property Class type
261 set { class_data(type) = value; }
262 get { return class_data(type); }
279 for(c = 0; c < count; c++)
289 for(c = 0; c < count; c++)
290 if(ids[c] == id) break;
293 ids = renew ids Id[count + 1];
304 for(c = 0; c < count; c++)
308 memcpy(ids + c, ids + c + 1, (count - 1 - c) * sizeof(Id));
309 ids = renew ids Id[count - 1];
316 void OnUnserialize(IOChannel channel)
322 channel.Unserialize(count);
323 if(count != MAXDWORD)
325 IdList idList = eInstance_New(_class); //IdList { };
326 idList.count = count;
327 idList.ids = new Id[count];
328 for(c = 0; c < count; c++)
331 channel.Unserialize(id);
339 void OnSerialize(IOChannel channel)
344 channel.Serialize(count);
345 for(c = 0; c < count; c++)
346 channel.Serialize(ids[c]);
351 channel.Serialize(none);
355 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
361 const char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
366 Class type = class_data(type);
369 char tempString[256];
371 for(c = 0; c<count; c++)
373 String s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &ids[c], tempString, null, null);
374 if(c) strcat(stringOutput, ", ");
376 // strcatf(stringOutput, "%d", ids[c]);
377 strcat(stringOutput, s);
384 bool OnGetDataFromString(const char * string)
388 while(GetAlNum(&string, value, sizeof(value)))
389 if(isdigit(value[0]))
394 int OnCompare(IdList b)
396 if(!this && !b) return 0;
397 else if(this && !b) return 1;
398 else if(!this && b) return -1;
399 else if(count > b.count) return 1;
400 else if(count < b.count) return -1;
404 for(c = 0; c<count; c++)
406 Id idA = ids[c], idB = b.ids[c];
407 if(idA > idB) return 1;
408 else if(idA < idB) return -1;
414 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
421 anchor = { 0, 0, 0, 0 };
423 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
425 Id id = row.GetData(null);
429 listBox.DeleteRow(row);
433 if(row == listBox.lastRow)
435 row = listBox.AddRow();
436 row.SetData(null, (Id)0);
437 listBox.scroll.y = listBox.scrollArea.h;
439 else if(row.next == listBox.lastRow)
440 listBox.scroll.y = listBox.scrollArea.h;
450 this = eInstance_New(_class);
453 Class type = class_data(type);
454 list.AddField({ type, editable = true });
456 for(c = 0; c < (this ? count : 0); c++)
459 r.SetData(null, ids[c]);
462 r.SetData(null, (Id)0);
464 list.modifiedDocument = false;
468 bool OnSaveEdit(Window window, void * object)
470 ListBox list = (ListBox) window;
471 if(list.modifiedDocument)
475 this = eInstance_New(_class);
477 for(r = list.firstRow; r; r = r.next)
479 Id id = r.GetData(null);
494 public class IdList32 : IdList
496 void OnUnserialize(IOChannel channel)
502 channel.Unserialize(count);
503 if(count != MAXDWORD)
505 IdList idList = eInstance_New(_class);
506 idList.count = count;
507 idList.ids = new Id[count];
508 for(c = 0; c < count; c++)
511 channel.Unserialize(id);
518 void OnSerialize(IOChannel channel)
523 channel.Serialize(count);
524 for(c = 0; c < count; c++)
525 channel.Serialize((uint32)ids[c]);
530 channel.Serialize((uint32)none);
535 public class IdListIncludes : SQLCustomFunction
537 // Should private methods be added to the component system?
539 bool function(IdList list, Id id)
541 return list.Includes(id);
545 public class IdList32Includes : SQLCustomFunction
547 // Should private methods be added to the component system?
549 bool function(IdList32 list, Id id)
551 return list.Includes(id);
555 static void FreeString(String string)
560 public class StringList
562 StringBinaryTree strings
564 CompareKey = (void *)BinaryTree::CompareString;
565 FreeKey = (void *)FreeString;
573 bool Includes(String string)
575 return strings.FindString(string) != null;
578 bool Add(String string)
580 BTNode node { key = (uintptr)CopyString(string) };
581 if(strings.Add(node))
585 FreeString((String)node.key);
591 bool Delete(String string)
593 BTNode node = strings.FindString(string);
596 strings.Delete(node);
602 void _OnUnserialize(IOChannel channel)
604 channel.Get(strings);
607 void OnUnserialize(IOChannel channel)
609 this = eInstance_New(class(StringList));
610 _OnUnserialize(channel);
613 void OnSerialize(IOChannel channel)
615 channel.Put(strings);
618 int OnCompare(StringList b)
620 BTNode nodeA = strings.first, nodeB = b.strings.first;
621 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
624 if(nodeA && !nodeB) return 1;
625 else if(nodeB && !nodeA) return -1;
628 result = strcmp((char *)nodeA.key, (char *)nodeB.key);
629 if(result) return result;
635 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
642 anchor = { 0, 0, 0, 0 };
644 bool OnKeyHit(Key key, unichar ch)
646 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
649 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
651 String string = row.GetData(null);
652 if(!string || !string[0])
656 listBox.DeleteRow(row);
657 listBox.firstChild.Activate();
662 if(row == listBox.lastRow)
664 row = listBox.AddRow();
665 row.SetData(null, null);
666 listBox.scroll.y = listBox.scrollArea.h;
672 if(row.next == listBox.lastRow)
673 listBox.scroll.y = listBox.scrollArea.h;
676 listBox.SelectRow(row);
682 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
684 listBox.firstChild.Activate();
688 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
690 String string = row.GetData(null);
691 if(!string || !string[0])
695 listBox.DeleteRow(row);
696 listBox.firstChild.Activate();
701 if(row == listBox.lastRow)
703 row = listBox.AddRow();
704 row.SetData(null, null);
705 listBox.scroll.y = listBox.scrollArea.h;
707 else if(row.next == listBox.lastRow)
708 listBox.scroll.y = listBox.scrollArea.h;
721 this = eInstance_New(_class);
725 list.AddField({ class(char *), editable = true });
726 for(node = strings.first; node; node = node.next)
729 r.SetData(null, (String)node.key);
732 r.SetData(null, null);
734 list.modifiedDocument = false;
738 bool OnSaveEdit(Window window, void * object)
740 ListBox list = (ListBox) window;
741 if(list.modifiedDocument)
746 ((DataBox)list.activeChild).SaveData();
749 this = eInstance_New(_class);
751 // TODO: Fix how to get the data box...
753 for(r = list.firstRow; r; r = r.next)
755 String string = r.GetData(null);
772 public class FixedMultiLineString : String
774 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
776 // Don't show the editbox right away so that the text is highlighted by default
779 dataBox, visible = false,
781 textHorzScroll = true,
782 modifyVirtualArea = false,
783 anchor = { 0, 0, 0, 0 };
786 void DataBox::NotifyUpdate(EditBox editBox)
789 modifiedDocument = true;
792 editBox.contents = this;
793 editBox.visible = true;
797 editBox.contents = this;
801 bool OnSaveEdit(Window window, void * object)
803 bool changed = false;
804 EditBox editBox = (EditBox)window;
805 if(editBox.modifiedDocument)
813 for(line = editBox.firstLine; line; line = line.next)
814 size += line.count+1;
815 this = string = new char[size+1];
817 for(line = editBox.firstLine; line; line = line.next)
819 memcpy(string + size, line.text, line.count);
835 public class CIString : String
840 public struct DataList : OldList
842 class_data Class type;
843 class_data char * typeName;
844 // class_property Class type { set { class_data(type) = value; } };
845 class_property char * type { set { class_data(typeName) = value; } };
846 class_property Class dataType { get { return class_data(type); } };
848 void OnUnserialize(IOChannel channel)
851 if(!class_data(type))
852 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
853 type = class_data(type);
861 channel.Unserialize(truth);
867 if(type.type == structClass)
868 link.data = new0 byte[type.structSize];
869 ((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnUnserialize])(type, (type.type == structClass) ? link.data : &link.data, channel);
875 void OnSerialize(IOChannel channel)
877 OldLink node = first;
879 if(!class_data(type))
880 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
881 type = class_data(type);
888 channel.Serialize(truth);
889 if(type.type == bitClass || type.type == unitClass || (type.type == systemClass && type.typeSize))
890 ((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnSerialize])(type, &node.data, channel);
892 ((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnSerialize])(type, node.data, channel);
898 channel.Serialize(truth);
905 int OnCompare(DataList b)
907 OldLink nodeA = first, nodeB = b.first;
908 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
911 if(nodeA && !nodeB) return 1;
912 else if(nodeB && !nodeA) return -1;
915 Class type = class_data(type);
916 result = ((int (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnCompare])(type,
917 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeA.data : (void *)nodeA.data,
918 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeB.data : (void *)nodeB.data);
919 if(result) return result;
925 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
932 anchor = { 0, 0, 0, 0 };
934 bool OnKeyHit(Key key, unichar ch)
936 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
939 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
941 Class type = ((subclass(DataList))this.type).dataType;
942 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
944 String string = row.GetData(null);
945 if(!string || !string[0])
949 listBox.DeleteRow(row);
950 listBox.firstChild.Activate();
955 if(row == listBox.lastRow)
957 /*row = listBox.AddRow();
958 row.SetData(null, null);
959 listBox.scroll.y = listBox.scrollArea.h;*/
965 listBox.SelectRow(row);
972 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
974 Class type = ((subclass(DataList))this.type).dataType;
975 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
977 String string = row.GetData(null);
978 if(!string || !string[0])
982 listBox.DeleteRow(row);
983 listBox.firstChild.Activate();
988 if(row == listBox.lastRow)
990 row = listBox.AddRow();
991 row.SetData(null, null);
992 listBox.scroll.y = listBox.scrollArea.h;
994 else if(row.next == listBox.lastRow)
995 listBox.scroll.y = listBox.scrollArea.h;
1002 bool DataBox::NotifyEditing(ListBox listBox, DataRow row)
1004 Class type = ((subclass(DataList))this.type).dataType;
1005 DataBox editData = (DataBox)listBox.firstChild;
1006 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1010 if(type.type == normalClass && !*(void **)editData.data && strcmp(type.dataTypeString, "char *"))
1012 *(void **)editData.data = eInstance_New(type);
1013 row.SetData(null, *(void **)editData.data);
1017 if(row == listBox.lastRow)
1019 listBox.alwaysEdit = false;
1020 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1021 listBox.AddRow().SetData(null, null);
1023 listBox.AddRow().SetData(null, (Id)0);
1024 listBox.scroll.y = listBox.scrollArea.h;
1025 listBox.alwaysEdit = true;
1031 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
1033 listBox.firstChild.Activate();
1037 bool DataBox::NotifyEditDone(ListBox listBox, DataRow row)
1039 Class type = ((subclass(DataList))this.type).dataType;
1040 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1043 void * data = ((type.type == normalClass || type.type == noHeadClass || type.type == structClass) ? row.GetData(null) : (void *)(uintptr)*(Id *)row.GetData(null));
1046 //if(strcmp(type.dataTypeString, char *"))
1047 //listBox.currentRow = null;
1048 if(row != listBox.lastRow)
1050 listBox.alwaysEdit = false;
1051 listBox.DeleteRow(row);
1052 listBox.alwaysEdit = true;
1062 Class type = firstField.dataType;
1063 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1066 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1067 eInstance_Delete(lastRow.GetData(null));
1068 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1069 lastRow.SetData(null, null);
1071 lastRow.SetData(null, (Id)0);
1079 if(!class_data(type))
1080 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1081 type = class_data(type);
1083 list.AddField({ type, editable = true });
1084 for(node = first; node; node = node.next)
1089 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1090 r.SetData(null, CopyString((String)node.data));
1092 r.SetData(null, node.data);
1096 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1097 r.SetData(null, null);
1099 r.SetData(null, (Id)0);
1101 list.modifiedDocument = false;
1105 bool OnSaveEdit(Window window, void * object)
1107 ListBox list = (ListBox) window;
1108 if(list.modifiedDocument)
1110 Class type = class_data(type);
1112 if(list.activeChild)
1113 ((DataBox)list.activeChild).SaveData();
1115 if(type.type != normalClass || !strcmp(type.dataTypeString, "char *"))
1117 else if(type.type == structClass)
1118 Free(OldLink::Free);
1122 for(r = list.firstRow; r; r = r.next)
1124 if(type.type == noHeadClass || type.type == normalClass || type.type == structClass)
1126 void * data = r.GetData(null);
1129 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1130 Add(OldLink { data = CopyString(data) });
1131 else if(type.type == structClass)
1133 OldLink link { data = new byte[type.structSize] };
1135 memcpy(link.data, data, type.structSize);
1138 Add(OldLink { data = data });
1143 void * i = r.GetData(null);
1145 Add(OldLink { data = i });
1158 if(!class_data(type))
1159 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1160 type = class_data(type);
1161 while((node = first))
1163 // TO STUDY: ONFREE SHOULD BE USED ONLY FOR LISTBOX?
1166 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1167 eInstance_Delete(node.data);
1168 else if(type.type == structClass)
1171 ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, node.data);