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 if(this || !this) { // FIXME
45 TableDropBox dropBox = dataBox.keepEditor ? (TableDropBox)dataBox.editor /*obsolete*/ : null;
49 if(eClass_IsDerived(dataBox._class, class(FieldDropBox)))
51 FieldDropBox fieldDropBox = (FieldDropBox)dataBox;
54 else if(eClass_IsDerived(dataBox._class, class(FieldBox)))
56 FieldBox fieldBox = (FieldBox)dataBox;
61 dropBox = TableDropBox
63 dataBox, borderStyle = 0, anchor = { 0, 0, 0, 0 },
64 modifyVirtualArea = false, activeStipple = false;
66 nameField = *class_data(nameField);
67 table = *class_data(table);
69 bool DataBox::NotifySelect(DropBox control, DataRow row, Modifiers mods)
71 uint id = 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)
170 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
175 Table tbl = *class_data(table);
176 Field idField = tbl.FindField(defaultIdField);
181 if(r.Find(idField, middle, nil, this))
184 Field * nameField = class_data(nameField);
185 char * fn = nameField->name;
187 // r.GetData(*nameField, name);
189 // Get name data from row
191 Class type = nameField->type;
192 if(type.type == unitClass && !type.typeSize)
194 Class dataType = eSystem_FindClass(type.module, type.dataTypeString);
198 if(type.type == structClass)
199 data = (int64)new0 byte[type.structSize];
200 ((bool (*)())(void *)r.GetData)(r, *nameField, type, (type.type == structClass) ? (void *)data : &data);
202 if(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass)
203 name = (String)type._vTbl[__ecereVMethodID_class_OnGetString](type, (void *)&data, tempString, null, null);
205 name = (String)type._vTbl[__ecereVMethodID_class_OnGetString](type, (void *)data, tempString, null, null);
207 strcpy(tempString, name ? name : "");
208 if(!(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass))
209 type._vTbl[__ecereVMethodID_class_OnFree](type, data);
214 sprintf(tempString, $"(Click to add a new %s...)", $"item"/*class_data(addText)*/);
227 class_data Class type;
228 class_property Class type
230 set { class_data(type) = value; }
231 get { return class_data(type); }
243 public bool Includes(Id id)
248 for(c = 0; c < count; c++)
255 public bool Add(Id id)
258 for(c = 0; c < count; c++)
259 if(ids[c] == id) break;
262 ids = renew ids Id[count + 1];
270 public bool Delete(Id id)
273 for(c = 0; c < count; c++)
277 memcpy(ids + c, ids + c + 1, (count - 1 - c) * sizeof(Id));
278 ids = renew ids Id[count - 1];
285 void OnUnserialize(IOChannel channel)
291 channel.Unserialize(count);
292 if(count != MAXDWORD)
294 IdList idList = eInstance_New(_class); //IdList { };
295 idList.count = count;
296 idList.ids = new Id[count];
297 for(c = 0; c < count; c++)
300 channel.Unserialize(id);
308 void OnSerialize(IOChannel channel)
313 channel.Serialize(count);
314 for(c = 0; c < count; c++)
315 channel.Serialize(ids[c]);
320 channel.Serialize(none);
324 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
329 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
335 for(c = 0; c<count; c++)
337 char tempString[256];
338 Class type = class_data(type);
339 if(c) strcat(stringOutput, ", ");
342 type._vTbl[__ecereVMethodID_class_OnGetString](type, &ids[c], tempString, null, null);
343 // strcatf(stringOutput, "%d", ids[c]);
344 strcat(stringOutput, tempString);
350 bool OnGetDataFromString(char * string)
354 while(GetAlNum(&string, value, sizeof(value)))
355 if(isdigit(value[0]))
360 int OnCompare(IdList b)
362 if(count > b.count) return 1;
363 else if(count < b.count) return -1;
367 for(c = 0; c<count; c++)
369 int idA = ids[c], idB = b.ids[c];
370 if(idA > idB) return 1;
371 else if(idA < idB) return -1;
377 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
384 anchor = { 0, 0, 0, 0 };
386 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
388 Id id = row.GetData(null);
392 listBox.DeleteRow(row);
396 if(row == listBox.lastRow)
398 row = listBox.AddRow();
399 row.SetData(null, 0);
400 listBox.scroll.y = listBox.scrollArea.h;
402 else if(row.next == listBox.lastRow)
403 listBox.scroll.y = listBox.scrollArea.h;
413 this = eInstance_New(_class);
415 if(this || !this) // FIXME
417 Class type = class_data(type);
418 list.AddField({ type, editable = true });
420 for(c = 0; c < (this ? count : 0); c++)
423 r.SetData(null, ids[c]);
428 list.modifiedDocument = false;
432 bool OnSaveEdit(Window window, void * object)
434 ListBox list = (ListBox) window;
435 if(list.modifiedDocument)
439 this = eInstance_New(_class);
441 for(r = list.firstRow; r; r = r.next)
443 Id id = r.GetData(null);
458 static void FreeString(String string)
463 public class StringList
465 StringBinaryTree strings
467 CompareKey = (void *)BinaryTree::CompareString;
468 FreeKey = (void *)FreeString;
476 bool Includes(String string)
478 return strings.FindString(string) != null;
481 bool Add(String string)
483 BTNode node { key = (uint)CopyString(string) };
484 if(strings.Add(node))
488 FreeString((String)node.key);
494 bool Delete(String string)
496 BTNode node = strings.FindString(string);
499 strings.Delete(node);
505 void _OnUnserialize(IOChannel channel)
507 channel.Get(strings);
510 void OnUnserialize(IOChannel channel)
512 this = eInstance_New(class(StringList));
513 _OnUnserialize(channel);
516 void OnSerialize(IOChannel channel)
518 channel.Put(strings);
521 int OnCompare(StringList b)
523 BTNode nodeA = strings.first, nodeB = b.strings.first;
524 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
527 if(nodeA && !nodeB) return 1;
528 else if(nodeB && !nodeA) return -1;
531 result = strcmp((char *)nodeA.key, (char *)nodeB.key);
532 if(result) return result;
538 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
545 anchor = { 0, 0, 0, 0 };
547 bool OnKeyHit(Key key, unichar ch)
549 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
552 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
554 String string = row.GetData(null);
555 if(!string || !string[0])
559 listBox.DeleteRow(row);
560 listBox.firstChild.Activate();
565 if(row == listBox.lastRow)
567 row = listBox.AddRow();
568 row.SetData(null, null);
569 listBox.scroll.y = listBox.scrollArea.h;
575 if(row.next == listBox.lastRow)
576 listBox.scroll.y = listBox.scrollArea.h;
579 listBox.SelectRow(row);
585 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
587 listBox.firstChild.Activate();
591 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
593 String string = row.GetData(null);
594 if(!string || !string[0])
598 listBox.DeleteRow(row);
599 listBox.firstChild.Activate();
604 if(row == listBox.lastRow)
606 row = listBox.AddRow();
607 row.SetData(null, null);
608 listBox.scroll.y = listBox.scrollArea.h;
610 else if(row.next == listBox.lastRow)
611 listBox.scroll.y = listBox.scrollArea.h;
624 this = eInstance_New(_class);
628 if(this || !this) // FIXME
630 list.AddField({ class(char *), editable = true });
632 for(node = strings.first; node; node = node.next)
635 r.SetData(null, (String)node.key);
638 r.SetData(null, null);
640 list.modifiedDocument = false;
644 bool OnSaveEdit(Window window, void * object)
646 ListBox list = (ListBox) window;
647 if(list.modifiedDocument)
652 ((DataBox)list.activeChild).SaveData();
655 this = eInstance_New(_class);
657 // TODO: Fix how to get the data box...
659 for(r = list.firstRow; r; r = r.next)
661 String string = r.GetData(null);
678 public class FixedMultiLineString : String
680 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
682 // Don't show the editbox right away so that the text is highlighted by default
686 dataBox, visible = false,
688 textHorzScroll = true,
689 modifyVirtualArea = false,
690 anchor = { 0, 0, 0, 0 };
693 void DataBox::NotifyUpdate(EditBox editBox)
696 modifiedDocument = true;
699 editBox.contents = this;
700 editBox.visible = true;
704 editBox.contents = this;
708 bool OnSaveEdit(Window window, void * object)
710 bool changed = false;
711 EditBox editBox = (EditBox)window;
712 if(editBox.modifiedDocument)
720 for(line = editBox.firstLine; line; line = line.next)
721 size += line.count+1;
722 this = string = new char[size+1];
724 for(line = editBox.firstLine; line; line = line.next)
726 memcpy(string + size, line.text, line.count);
742 public class CIString : String
747 public class MultiLineString : String
749 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
751 // Don't show the editbox right away so that the text is highlighted by default
755 dataBox, visible = false,
757 hasHorzScroll = true, hasVertScroll = true,
758 modifyVirtualArea = false,
759 anchor = { 0, 0, 0, 0 };
762 void DataBox::NotifyUpdate(EditBox editBox)
765 modifiedDocument = true;
768 editBox.contents = this;
769 editBox.visible = true;
773 editBox.contents = this;
777 bool OnSaveEdit(Window window, void * object)
779 bool changed = false;
780 EditBox editBox = (EditBox)window;
781 if(editBox.modifiedDocument)
789 for(line = editBox.firstLine; line; line = line.next)
790 size += line.count+1;
791 this = string = new char[size+1];
793 for(line = editBox.firstLine; line; line = line.next)
795 memcpy(string + size, line.text, line.count);
811 public struct DataList : OldList
813 class_data Class type;
814 class_data char * typeName;
815 // class_property Class type { set { class_data(type) = value; } };
816 class_property char * type { set { class_data(typeName) = value; } };
817 class_property Class dataType { get { return class_data(type); } };
819 void OnUnserialize(IOChannel channel)
822 if(!class_data(type))
823 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
824 type = class_data(type);
832 channel.Unserialize(truth);
838 if(type.type == structClass)
839 link.data = new0 byte[type.structSize];
840 type._vTbl[__ecereVMethodID_class_OnUnserialize](type, (type.type == structClass) ? link.data : &link.data, channel);
846 void OnSerialize(IOChannel channel)
848 OldLink node = first;
850 if(!class_data(type))
851 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
852 type = class_data(type);
859 channel.Serialize(truth);
860 if(type.type == bitClass || type.type == unitClass || (type.type == systemClass && type.typeSize))
861 type._vTbl[__ecereVMethodID_class_OnSerialize](type, &node.data, channel);
863 type._vTbl[__ecereVMethodID_class_OnSerialize](type, node.data, channel);
869 channel.Serialize(truth);
876 int OnCompare(DataList b)
878 OldLink nodeA = first, nodeB = b.first;
879 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
882 if(nodeA && !nodeB) return 1;
883 else if(nodeB && !nodeA) return -1;
886 Class type = class_data(type);
887 result = type._vTbl[__ecereVMethodID_class_OnCompare](type,
888 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeA.data : (void *)nodeA.data,
889 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeB.data : (void *)nodeB.data);
890 if(result) return result;
896 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
903 anchor = { 0, 0, 0, 0 };
905 bool OnKeyHit(Key key, unichar ch)
907 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
910 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
912 Class type = ((subclass(DataList))this.type).dataType;
913 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
915 String string = row.GetData(null);
916 if(!string || !string[0])
920 listBox.DeleteRow(row);
921 listBox.firstChild.Activate();
926 if(row == listBox.lastRow)
928 /*row = listBox.AddRow();
929 row.SetData(null, null);
930 listBox.scroll.y = listBox.scrollArea.h;*/
936 listBox.SelectRow(row);
943 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
945 Class type = ((subclass(DataList))this.type).dataType;
946 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
948 String string = row.GetData(null);
949 if(!string || !string[0])
953 listBox.DeleteRow(row);
954 listBox.firstChild.Activate();
959 if(row == listBox.lastRow)
961 row = listBox.AddRow();
962 row.SetData(null, null);
963 listBox.scroll.y = listBox.scrollArea.h;
965 else if(row.next == listBox.lastRow)
966 listBox.scroll.y = listBox.scrollArea.h;
973 bool DataBox::NotifyEditing(ListBox listBox, DataRow row)
975 Class type = ((subclass(DataList))this.type).dataType;
976 DataBox editData = (DataBox)listBox.firstChild;
977 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
981 if(type.type == normalClass && !*(void **)editData.data && strcmp(type.dataTypeString, "char *"))
983 *(void **)editData.data = eInstance_New(type);
984 row.SetData(null, *(void **)editData.data);
988 if(row == listBox.lastRow)
990 listBox.alwaysEdit = false;
991 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
992 listBox.AddRow().SetData(null, null);
994 listBox.AddRow().SetData(null, 0);
995 listBox.scroll.y = listBox.scrollArea.h;
996 listBox.alwaysEdit = true;
1002 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
1004 listBox.firstChild.Activate();
1008 bool DataBox::NotifyEditDone(ListBox listBox, DataRow row)
1010 Class type = ((subclass(DataList))this.type).dataType;
1011 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1014 void * data = ((type.type == normalClass || type.type == noHeadClass || type.type == structClass) ? row.GetData(null) : *(uint *)row.GetData(null));
1017 //if(strcmp(type.dataTypeString, char *"))
1018 //listBox.currentRow = null;
1019 if(row != listBox.lastRow)
1021 listBox.alwaysEdit = false;
1022 listBox.DeleteRow(row);
1023 listBox.alwaysEdit = true;
1033 Class type = firstField.dataType;
1034 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1037 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1038 eInstance_Delete(lastRow.GetData(null));
1039 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1040 lastRow.SetData(null, null);
1042 lastRow.SetData(null, 0);
1050 if(!class_data(type))
1051 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1052 type = class_data(type);
1054 list.AddField({ type, editable = true });
1055 for(node = first; node; node = node.next)
1060 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1061 r.SetData(null, CopyString((String)node.data));
1063 r.SetData(null, node.data);
1067 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1068 r.SetData(null, null);
1072 list.modifiedDocument = false;
1076 bool OnSaveEdit(Window window, void * object)
1078 ListBox list = (ListBox) window;
1079 if(list.modifiedDocument)
1081 Class type = class_data(type);
1083 if(list.activeChild)
1084 ((DataBox)list.activeChild).SaveData();
1086 if(type.type != normalClass || !strcmp(type.dataTypeString, "char *"))
1088 else if(type.type == structClass)
1089 Free(OldLink::Free);
1093 for(r = list.firstRow; r; r = r.next)
1095 if(type.type == noHeadClass || type.type == normalClass || type.type == structClass)
1097 void * data = r.GetData(null);
1100 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1101 Add(OldLink { data = CopyString(data) });
1102 else if(type.type == structClass)
1104 OldLink link { data = new byte[type.structSize] };
1106 memcpy(link.data, data, type.structSize);
1109 Add(OldLink { data = data });
1114 uint i = r.GetData(null);
1116 Add(OldLink { data = (void *)i });
1129 if(!class_data(type))
1130 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1131 type = class_data(type);
1134 // TO STUDY: ONFREE SHOULD BE USED ONLY FOR LISTBOX?
1137 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1138 eInstance_Delete(node.data);
1139 else if(type.type == structClass)
1142 type._vTbl[__ecereVMethodID_class_OnFree](type, node.data);