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 autoSize = dataBox.autoSize;
760 anchor = { 0, 0, 0, 0 };
763 void DataBox::NotifyUpdate(EditBox editBox)
766 modifiedDocument = true;
769 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
771 opacity = active ? 1.0f : parent.opacity;
775 editBox.contents = this;
776 editBox.visible = true;
780 editBox.contents = this;
784 bool OnSaveEdit(Window window, void * object)
786 bool changed = false;
787 EditBox editBox = (EditBox)window;
788 if(editBox.modifiedDocument)
796 for(line = editBox.firstLine; line; line = line.next)
797 size += line.count+1;
798 this = string = new char[size+1];
800 for(line = editBox.firstLine; line; line = line.next)
802 memcpy(string + size, line.text, line.count);
818 public struct DataList : OldList
820 class_data Class type;
821 class_data char * typeName;
822 // class_property Class type { set { class_data(type) = value; } };
823 class_property char * type { set { class_data(typeName) = value; } };
824 class_property Class dataType { get { return class_data(type); } };
826 void OnUnserialize(IOChannel channel)
829 if(!class_data(type))
830 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
831 type = class_data(type);
839 channel.Unserialize(truth);
845 if(type.type == structClass)
846 link.data = new0 byte[type.structSize];
847 type._vTbl[__ecereVMethodID_class_OnUnserialize](type, (type.type == structClass) ? link.data : &link.data, channel);
853 void OnSerialize(IOChannel channel)
855 OldLink node = first;
857 if(!class_data(type))
858 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
859 type = class_data(type);
866 channel.Serialize(truth);
867 if(type.type == bitClass || type.type == unitClass || (type.type == systemClass && type.typeSize))
868 type._vTbl[__ecereVMethodID_class_OnSerialize](type, &node.data, channel);
870 type._vTbl[__ecereVMethodID_class_OnSerialize](type, node.data, channel);
876 channel.Serialize(truth);
883 int OnCompare(DataList b)
885 OldLink nodeA = first, nodeB = b.first;
886 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
889 if(nodeA && !nodeB) return 1;
890 else if(nodeB && !nodeA) return -1;
893 Class type = class_data(type);
894 result = type._vTbl[__ecereVMethodID_class_OnCompare](type,
895 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeA.data : (void *)nodeA.data,
896 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeB.data : (void *)nodeB.data);
897 if(result) return result;
903 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
910 anchor = { 0, 0, 0, 0 };
912 bool OnKeyHit(Key key, unichar ch)
914 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
917 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
919 Class type = ((subclass(DataList))this.type).dataType;
920 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
922 String string = row.GetData(null);
923 if(!string || !string[0])
927 listBox.DeleteRow(row);
928 listBox.firstChild.Activate();
933 if(row == listBox.lastRow)
935 /*row = listBox.AddRow();
936 row.SetData(null, null);
937 listBox.scroll.y = listBox.scrollArea.h;*/
943 listBox.SelectRow(row);
950 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
952 Class type = ((subclass(DataList))this.type).dataType;
953 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
955 String string = row.GetData(null);
956 if(!string || !string[0])
960 listBox.DeleteRow(row);
961 listBox.firstChild.Activate();
966 if(row == listBox.lastRow)
968 row = listBox.AddRow();
969 row.SetData(null, null);
970 listBox.scroll.y = listBox.scrollArea.h;
972 else if(row.next == listBox.lastRow)
973 listBox.scroll.y = listBox.scrollArea.h;
980 bool DataBox::NotifyEditing(ListBox listBox, DataRow row)
982 Class type = ((subclass(DataList))this.type).dataType;
983 DataBox editData = (DataBox)listBox.firstChild;
984 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
988 if(type.type == normalClass && !*(void **)editData.data && strcmp(type.dataTypeString, "char *"))
990 *(void **)editData.data = eInstance_New(type);
991 row.SetData(null, *(void **)editData.data);
995 if(row == listBox.lastRow)
997 listBox.alwaysEdit = false;
998 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
999 listBox.AddRow().SetData(null, null);
1001 listBox.AddRow().SetData(null, 0);
1002 listBox.scroll.y = listBox.scrollArea.h;
1003 listBox.alwaysEdit = true;
1009 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
1011 listBox.firstChild.Activate();
1015 bool DataBox::NotifyEditDone(ListBox listBox, DataRow row)
1017 Class type = ((subclass(DataList))this.type).dataType;
1018 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1021 void * data = ((type.type == normalClass || type.type == noHeadClass || type.type == structClass) ? row.GetData(null) : *(uint *)row.GetData(null));
1024 //if(strcmp(type.dataTypeString, char *"))
1025 //listBox.currentRow = null;
1026 if(row != listBox.lastRow)
1028 listBox.alwaysEdit = false;
1029 listBox.DeleteRow(row);
1030 listBox.alwaysEdit = true;
1040 Class type = firstField.dataType;
1041 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1044 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1045 eInstance_Delete(lastRow.GetData(null));
1046 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1047 lastRow.SetData(null, null);
1049 lastRow.SetData(null, 0);
1057 if(!class_data(type))
1058 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1059 type = class_data(type);
1061 list.AddField({ type, editable = true });
1062 for(node = first; node; node = node.next)
1067 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1068 r.SetData(null, CopyString((String)node.data));
1070 r.SetData(null, node.data);
1074 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1075 r.SetData(null, null);
1079 list.modifiedDocument = false;
1083 bool OnSaveEdit(Window window, void * object)
1085 ListBox list = (ListBox) window;
1086 if(list.modifiedDocument)
1088 Class type = class_data(type);
1090 if(list.activeChild)
1091 ((DataBox)list.activeChild).SaveData();
1093 if(type.type != normalClass || !strcmp(type.dataTypeString, "char *"))
1095 else if(type.type == structClass)
1096 Free(OldLink::Free);
1100 for(r = list.firstRow; r; r = r.next)
1102 if(type.type == noHeadClass || type.type == normalClass || type.type == structClass)
1104 void * data = r.GetData(null);
1107 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1108 Add(OldLink { data = CopyString(data) });
1109 else if(type.type == structClass)
1111 OldLink link { data = new byte[type.structSize] };
1113 memcpy(link.data, data, type.structSize);
1116 Add(OldLink { data = data });
1121 uint i = r.GetData(null);
1123 Add(OldLink { data = (void *)i });
1136 if(!class_data(type))
1137 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1138 type = class_data(type);
1141 // TO STUDY: ONFREE SHOULD BE USED ONLY FOR LISTBOX?
1144 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1145 eInstance_Delete(node.data);
1146 else if(type.type == structClass)
1149 type._vTbl[__ecereVMethodID_class_OnFree](type, node.data);