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 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 : uint
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 // TOFIX: Id is still 32 bit
71 uint id = (uint)(row ? row.tag : 0);
72 SetData(&id, mods.closingDropDown);
76 bool DataBox::NotifyTextEntry(DropBox _dropBox, char * string, bool confirmed)
78 TableDropBox dropBox = (TableDropBox)_dropBox;
79 //Table tbl = dropBox.table.db.OpenTable(dropBox.table.name, { tableRows });
82 /*FieldIndex indexedFields[1];
84 char * trimmed = new char[strlen(string) + 1];
85 /*indexedFields[0] = { dropBox.nameField };
86 tbl.GenerateIndex(1, indexedFields, false);
90 TrimLSpaces(string, trimmed);
91 TrimRSpaces(trimmed, trimmed);
93 /*if(r.Find(dropBox.nameField, middle, nil, trimmed))
95 if(dropBox.filterField)
97 // TODO: Improve this... Multi field?
102 Field fldId = dropBox.table.FindField(defaultIdField);
103 r.GetData(fldId, id);
104 row = dropBox.FindSubRow(id);
107 dropBox.SelectRow(row);
110 //if(!r.Find(dropBox.nameField, next, nil, trimmed))
118 Field fldId = dropBox.table.FindField(defaultIdField);
119 r.GetData(fldId, id);
120 dropBox.SelectRow(dropBox.FindSubRow(id));
126 for(row = dropBox.firstRow; row; row = row.next)
128 char * string = row.string;
129 if(string && !strcmp(trimmed, string))
135 dropBox.SelectRow(row);
139 dropBox.changeContents = false;
140 dropBox.contents = trimmed;
141 dropBox.SelectRow(null);
142 dropBox.changeContents = true;
149 if(class_data(Refill))
150 dropBox.Refill = class_data(Refill);
154 dataBox.OnConfigure(dropBox);
156 dropBox.currentRow = dropBox.FindSubRow(this);
157 if(!dropBox.currentRow && this)
158 dataBox.SetData((uint *)&this, false);
160 DataRow r = dropBox.currentRow;
162 for(r = r.parent; r; r = r.parent)
168 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, this))
191 Field * nameField = class_data(nameField);
195 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)new0 byte[type.structSize];
208 ((bool (*)())(void *)r.GetData)(r, *nameField, type, (type.type == structClass) ? (void *)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 *)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 *)data);
222 PrintLn("Id::OnGetString -- data type"/*, this._class.name, */" has no class_data(nameField)");
226 sprintf(tempString, "(Invalid %s entry: %d)", tbl.name, this);
230 sprintf(tempString, $"(Click to add a new %s...)", $"item"/*class_data(addText)*/);
233 idRowCacheMutex.Release();
238 id.OnGetString(tempString, null, null);
250 class_data Class type;
251 class_property Class type
253 set { class_data(type) = value; }
254 get { return class_data(type); }
271 for(c = 0; c < count; c++)
281 for(c = 0; c < count; c++)
282 if(ids[c] == id) break;
285 ids = renew ids Id[count + 1];
296 for(c = 0; c < count; c++)
300 memcpy(ids + c, ids + c + 1, (count - 1 - c) * sizeof(Id));
301 ids = renew ids Id[count - 1];
308 void OnUnserialize(IOChannel channel)
314 channel.Unserialize(count);
315 if(count != MAXDWORD)
317 IdList idList = eInstance_New(_class); //IdList { };
318 idList.count = count;
319 idList.ids = new Id[count];
320 for(c = 0; c < count; c++)
323 channel.Unserialize(id);
331 void OnSerialize(IOChannel channel)
336 channel.Serialize(count);
337 for(c = 0; c < count; c++)
338 channel.Serialize(ids[c]);
343 channel.Serialize(none);
347 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
353 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
359 for(c = 0; c<count; c++)
361 char tempString[256];
362 Class type = class_data(type);
364 if(c) strcat(stringOutput, ", ");
367 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &ids[c], tempString, null, null);
368 // strcatf(stringOutput, "%d", ids[c]);
369 strcat(stringOutput, s);
375 bool OnGetDataFromString(char * string)
379 while(GetAlNum(&string, value, sizeof(value)))
380 if(isdigit(value[0]))
385 int OnCompare(IdList b)
387 if(!this && !b) return 0;
388 else if(this && !b) return 1;
389 else if(!this && b) return -1;
390 else if(count > b.count) return 1;
391 else if(count < b.count) return -1;
395 for(c = 0; c<count; c++)
397 int idA = ids[c], idB = b.ids[c];
398 if(idA > idB) return 1;
399 else if(idA < idB) return -1;
405 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
412 anchor = { 0, 0, 0, 0 };
414 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
416 Id id = row.GetData(null);
420 listBox.DeleteRow(row);
424 if(row == listBox.lastRow)
426 row = listBox.AddRow();
427 row.SetData(null, 0);
428 listBox.scroll.y = listBox.scrollArea.h;
430 else if(row.next == listBox.lastRow)
431 listBox.scroll.y = listBox.scrollArea.h;
441 this = eInstance_New(_class);
444 Class type = class_data(type);
445 list.AddField({ type, editable = true });
447 for(c = 0; c < (this ? count : 0); c++)
450 r.SetData(null, ids[c]);
455 list.modifiedDocument = false;
459 bool OnSaveEdit(Window window, void * object)
461 ListBox list = (ListBox) window;
462 if(list.modifiedDocument)
466 this = eInstance_New(_class);
468 for(r = list.firstRow; r; r = r.next)
470 Id id = r.GetData(null);
485 static void FreeString(String string)
490 public class StringList
492 StringBinaryTree strings
494 CompareKey = (void *)BinaryTree::CompareString;
495 FreeKey = (void *)FreeString;
503 bool Includes(String string)
505 return strings.FindString(string) != null;
508 bool Add(String string)
510 BTNode node { key = (uintptr)CopyString(string) };
511 if(strings.Add(node))
515 FreeString((String)node.key);
521 bool Delete(String string)
523 BTNode node = strings.FindString(string);
526 strings.Delete(node);
532 void _OnUnserialize(IOChannel channel)
534 channel.Get(strings);
537 void OnUnserialize(IOChannel channel)
539 this = eInstance_New(class(StringList));
540 _OnUnserialize(channel);
543 void OnSerialize(IOChannel channel)
545 channel.Put(strings);
548 int OnCompare(StringList b)
550 BTNode nodeA = strings.first, nodeB = b.strings.first;
551 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
554 if(nodeA && !nodeB) return 1;
555 else if(nodeB && !nodeA) return -1;
558 result = strcmp((char *)nodeA.key, (char *)nodeB.key);
559 if(result) return result;
565 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
572 anchor = { 0, 0, 0, 0 };
574 bool OnKeyHit(Key key, unichar ch)
576 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
579 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
581 String string = row.GetData(null);
582 if(!string || !string[0])
586 listBox.DeleteRow(row);
587 listBox.firstChild.Activate();
592 if(row == listBox.lastRow)
594 row = listBox.AddRow();
595 row.SetData(null, null);
596 listBox.scroll.y = listBox.scrollArea.h;
602 if(row.next == listBox.lastRow)
603 listBox.scroll.y = listBox.scrollArea.h;
606 listBox.SelectRow(row);
612 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
614 listBox.firstChild.Activate();
618 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
620 String string = row.GetData(null);
621 if(!string || !string[0])
625 listBox.DeleteRow(row);
626 listBox.firstChild.Activate();
631 if(row == listBox.lastRow)
633 row = listBox.AddRow();
634 row.SetData(null, null);
635 listBox.scroll.y = listBox.scrollArea.h;
637 else if(row.next == listBox.lastRow)
638 listBox.scroll.y = listBox.scrollArea.h;
651 this = eInstance_New(_class);
655 list.AddField({ class(char *), editable = true });
656 for(node = strings.first; node; node = node.next)
659 r.SetData(null, (String)node.key);
662 r.SetData(null, null);
664 list.modifiedDocument = false;
668 bool OnSaveEdit(Window window, void * object)
670 ListBox list = (ListBox) window;
671 if(list.modifiedDocument)
676 ((DataBox)list.activeChild).SaveData();
679 this = eInstance_New(_class);
681 // TODO: Fix how to get the data box...
683 for(r = list.firstRow; r; r = r.next)
685 String string = r.GetData(null);
702 public class FixedMultiLineString : String
704 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
706 // Don't show the editbox right away so that the text is highlighted by default
710 dataBox, visible = false,
712 textHorzScroll = true,
713 modifyVirtualArea = false,
714 anchor = { 0, 0, 0, 0 };
717 void DataBox::NotifyUpdate(EditBox editBox)
720 modifiedDocument = true;
723 editBox.contents = this;
724 editBox.visible = true;
728 editBox.contents = this;
732 bool OnSaveEdit(Window window, void * object)
734 bool changed = false;
735 EditBox editBox = (EditBox)window;
736 if(editBox.modifiedDocument)
744 for(line = editBox.firstLine; line; line = line.next)
745 size += line.count+1;
746 this = string = new char[size+1];
748 for(line = editBox.firstLine; line; line = line.next)
750 memcpy(string + size, line.text, line.count);
766 public class CIString : String
771 public class MultiLineString : String
773 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
775 // Don't show the editbox right away so that the text is highlighted by default
779 dataBox, visible = false,
781 hasHorzScroll = true, hasVertScroll = true,
782 modifyVirtualArea = false,
783 autoSize = dataBox.autoSize;
784 anchor = { 0, 0, 0, 0 };
787 void DataBox::NotifyUpdate(EditBox editBox)
790 modifiedDocument = true;
793 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
795 opacity = active ? 1.0f : parent.opacity;
799 editBox.contents = this;
800 editBox.visible = true;
804 editBox.contents = this;
808 bool OnSaveEdit(Window window, void * object)
810 bool changed = false;
811 EditBox editBox = (EditBox)window;
812 if(editBox.modifiedDocument)
820 for(line = editBox.firstLine; line; line = line.next)
821 size += line.count+1;
822 this = string = new char[size+1];
824 for(line = editBox.firstLine; line; line = line.next)
826 memcpy(string + size, line.text, line.count);
842 public struct DataList : OldList
844 class_data Class type;
845 class_data char * typeName;
846 // class_property Class type { set { class_data(type) = value; } };
847 class_property char * type { set { class_data(typeName) = value; } };
848 class_property Class dataType { get { return class_data(type); } };
850 void OnUnserialize(IOChannel channel)
853 if(!class_data(type))
854 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
855 type = class_data(type);
863 channel.Unserialize(truth);
869 if(type.type == structClass)
870 link.data = new0 byte[type.structSize];
871 ((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnUnserialize])(type, (type.type == structClass) ? link.data : &link.data, channel);
877 void OnSerialize(IOChannel channel)
879 OldLink node = first;
881 if(!class_data(type))
882 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
883 type = class_data(type);
890 channel.Serialize(truth);
891 if(type.type == bitClass || type.type == unitClass || (type.type == systemClass && type.typeSize))
892 ((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnSerialize])(type, &node.data, channel);
894 ((void (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnSerialize])(type, node.data, channel);
900 channel.Serialize(truth);
907 int OnCompare(DataList b)
909 OldLink nodeA = first, nodeB = b.first;
910 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
913 if(nodeA && !nodeB) return 1;
914 else if(nodeB && !nodeA) return -1;
917 Class type = class_data(type);
918 result = ((int (*)(void *, void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnCompare])(type,
919 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeA.data : (void *)nodeA.data,
920 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeB.data : (void *)nodeB.data);
921 if(result) return result;
927 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
934 anchor = { 0, 0, 0, 0 };
936 bool OnKeyHit(Key key, unichar ch)
938 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
941 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
943 Class type = ((subclass(DataList))this.type).dataType;
944 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
946 String string = row.GetData(null);
947 if(!string || !string[0])
951 listBox.DeleteRow(row);
952 listBox.firstChild.Activate();
957 if(row == listBox.lastRow)
959 /*row = listBox.AddRow();
960 row.SetData(null, null);
961 listBox.scroll.y = listBox.scrollArea.h;*/
967 listBox.SelectRow(row);
974 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
976 Class type = ((subclass(DataList))this.type).dataType;
977 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
979 String string = row.GetData(null);
980 if(!string || !string[0])
984 listBox.DeleteRow(row);
985 listBox.firstChild.Activate();
990 if(row == listBox.lastRow)
992 row = listBox.AddRow();
993 row.SetData(null, null);
994 listBox.scroll.y = listBox.scrollArea.h;
996 else if(row.next == listBox.lastRow)
997 listBox.scroll.y = listBox.scrollArea.h;
1004 bool DataBox::NotifyEditing(ListBox listBox, DataRow row)
1006 Class type = ((subclass(DataList))this.type).dataType;
1007 DataBox editData = (DataBox)listBox.firstChild;
1008 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1012 if(type.type == normalClass && !*(void **)editData.data && strcmp(type.dataTypeString, "char *"))
1014 *(void **)editData.data = eInstance_New(type);
1015 row.SetData(null, *(void **)editData.data);
1019 if(row == listBox.lastRow)
1021 listBox.alwaysEdit = false;
1022 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1023 listBox.AddRow().SetData(null, null);
1025 listBox.AddRow().SetData(null, 0);
1026 listBox.scroll.y = listBox.scrollArea.h;
1027 listBox.alwaysEdit = true;
1033 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
1035 listBox.firstChild.Activate();
1039 bool DataBox::NotifyEditDone(ListBox listBox, DataRow row)
1041 Class type = ((subclass(DataList))this.type).dataType;
1042 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1045 void * data = ((type.type == normalClass || type.type == noHeadClass || type.type == structClass) ? row.GetData(null) : *(uint *)row.GetData(null));
1048 //if(strcmp(type.dataTypeString, char *"))
1049 //listBox.currentRow = null;
1050 if(row != listBox.lastRow)
1052 listBox.alwaysEdit = false;
1053 listBox.DeleteRow(row);
1054 listBox.alwaysEdit = true;
1064 Class type = firstField.dataType;
1065 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1068 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1069 eInstance_Delete(lastRow.GetData(null));
1070 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1071 lastRow.SetData(null, null);
1073 lastRow.SetData(null, 0);
1081 if(!class_data(type))
1082 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1083 type = class_data(type);
1085 list.AddField({ type, editable = true });
1086 for(node = first; node; node = node.next)
1091 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1092 r.SetData(null, CopyString((String)node.data));
1094 r.SetData(null, node.data);
1098 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1099 r.SetData(null, null);
1103 list.modifiedDocument = false;
1107 bool OnSaveEdit(Window window, void * object)
1109 ListBox list = (ListBox) window;
1110 if(list.modifiedDocument)
1112 Class type = class_data(type);
1114 if(list.activeChild)
1115 ((DataBox)list.activeChild).SaveData();
1117 if(type.type != normalClass || !strcmp(type.dataTypeString, "char *"))
1119 else if(type.type == structClass)
1120 Free(OldLink::Free);
1124 for(r = list.firstRow; r; r = r.next)
1126 if(type.type == noHeadClass || type.type == normalClass || type.type == structClass)
1128 void * data = r.GetData(null);
1131 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1132 Add(OldLink { data = CopyString(data) });
1133 else if(type.type == structClass)
1135 OldLink link { data = new byte[type.structSize] };
1137 memcpy(link.data, data, type.structSize);
1140 Add(OldLink { data = data });
1145 uint i = r.GetData(null);
1147 Add(OldLink { data = (void *)i });
1160 if(!class_data(type))
1161 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1162 type = class_data(type);
1165 // TO STUDY: ONFREE SHOULD BE USED ONLY FOR LISTBOX?
1168 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1169 eInstance_Delete(node.data);
1170 else if(type.type == structClass)
1173 ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, node.data);