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 class IdRowCache : Map<Table, Row>
38 MapIterator<Table, Row> it { map = this };
40 if(it.Index(tbl, false))
57 IdRowCache idRowCache { };
59 public class Id : uint
61 class_data Table * table; class_property Table * table { set { class_data(table) = value; } get { return class_data(table); } };
62 //class_data Field * idField; class_property Field * idField { set { class_data(nameField) = value; } get { return class_data(idField); } };
63 //class_data Field * displayField; class_property Field * displayField { set { class_data(displayField) = value; } get { return class_data(displayField); } };
64 class_data Field * nameField; class_property Field * nameField { set { class_data(nameField) = value; } get { return class_data(nameField); } };
65 class_data char * addText; class_property char * addText { set { class_data(addText) = value; } };
66 class_data void * Refill; class_property void * Refill { set { class_data(Refill) = value; } };
68 Window OnEdit(DataBox dataBox, void * obsolete, int x, int y, int w, int h, void * userData)
70 if(this || !this) { // FIXME
71 TableDropBox dropBox = dataBox.keepEditor ? (TableDropBox)dataBox.editor /*obsolete*/ : null;
75 if(eClass_IsDerived(dataBox._class, class(FieldDropBox)))
77 FieldDropBox fieldDropBox = (FieldDropBox)dataBox;
80 else if(eClass_IsDerived(dataBox._class, class(FieldBox)))
82 FieldBox fieldBox = (FieldBox)dataBox;
87 dropBox = TableDropBox
89 dataBox, borderStyle = 0, anchor = { 0, 0, 0, 0 },
90 modifyVirtualArea = false, activeStipple = false;
92 nameField = *class_data(nameField);
93 table = *class_data(table);
95 bool DataBox::NotifySelect(DropBox control, DataRow row, Modifiers mods)
97 uint id = row ? row.tag : 0;
98 SetData(&id, mods.closingDropDown);
102 bool DataBox::NotifyTextEntry(DropBox _dropBox, char * string, bool confirmed)
104 TableDropBox dropBox = (TableDropBox)_dropBox;
105 //Table tbl = dropBox.table.db.OpenTable(dropBox.table.name, { tableRows });
108 /*FieldIndex indexedFields[1];
110 char * trimmed = new char[strlen(string) + 1];
111 /*indexedFields[0] = { dropBox.nameField };
112 tbl.GenerateIndex(1, indexedFields, false);
116 TrimLSpaces(string, trimmed);
117 TrimRSpaces(trimmed, trimmed);
119 /*if(r.Find(dropBox.nameField, middle, nil, trimmed))
121 if(dropBox.filterField)
123 // TODO: Improve this... Multi field?
128 Field fldId = dropBox.table.FindField(defaultIdField);
129 r.GetData(fldId, id);
130 row = dropBox.FindSubRow(id);
133 dropBox.SelectRow(row);
136 //if(!r.Find(dropBox.nameField, next, nil, trimmed))
144 Field fldId = dropBox.table.FindField(defaultIdField);
145 r.GetData(fldId, id);
146 dropBox.SelectRow(dropBox.FindSubRow(id));
152 for(row = dropBox.firstRow; row; row = row.next)
154 char * string = row.string;
155 if(string && !strcmp(trimmed, string))
161 dropBox.SelectRow(row);
165 dropBox.changeContents = false;
166 dropBox.contents = trimmed;
167 dropBox.SelectRow(null);
168 dropBox.changeContents = true;
175 if(class_data(Refill))
176 dropBox.Refill = class_data(Refill);
180 dataBox.OnConfigure(dropBox);
182 dropBox.currentRow = dropBox.FindSubRow(this);
183 if(!dropBox.currentRow && this)
184 dataBox.SetData((uint *)&this, false);
186 DataRow r = dropBox.currentRow;
188 for(r = r.parent; r; r = r.parent)
196 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
201 Table tbl = *class_data(table);
202 Field idField = tbl.FindField(defaultIdField);
203 Row r = idRowCache.GetRow(tbl);
207 if(r.Find(idField, middle, nil, this))
210 Field * nameField = class_data(nameField);
214 char * fn = nameField->name;
216 // Get name data from row
218 Class type = nameField->type;
219 if(type.type == unitClass && !type.typeSize)
221 Class dataType = eSystem_FindClass(type.module, type.dataTypeString);
225 if(type.type == structClass)
226 data = (int64)new0 byte[type.structSize];
227 ((bool (*)())(void *)r.GetData)(r, *nameField, type, (type.type == structClass) ? (void *)data : &data);
229 if(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass)
230 name = (String)type._vTbl[__ecereVMethodID_class_OnGetString](type, (void *)&data, tempString, null, null);
232 name = (String)type._vTbl[__ecereVMethodID_class_OnGetString](type, (void *)data, tempString, null, null);
234 strcpy(tempString, name ? name : "");
235 if(!(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass))
236 type._vTbl[__ecereVMethodID_class_OnFree](type, data);
240 PrintLn("Id::OnGetString -- data type"/*, this._class.name, */" has no class_data(nameField)");
246 sprintf(tempString, $"(Click to add a new %s...)", $"item"/*class_data(addText)*/);
249 idRowCache.mutex.Release();
260 class_data Class type;
261 class_property Class type
263 set { class_data(type) = value; }
264 get { return class_data(type); }
276 public bool Includes(Id id)
281 for(c = 0; c < count; c++)
288 public bool Add(Id id)
291 for(c = 0; c < count; c++)
292 if(ids[c] == id) break;
295 ids = renew ids Id[count + 1];
303 public bool Delete(Id id)
306 for(c = 0; c < count; c++)
310 memcpy(ids + c, ids + c + 1, (count - 1 - c) * sizeof(Id));
311 ids = renew ids Id[count - 1];
318 void OnUnserialize(IOChannel channel)
324 channel.Unserialize(count);
325 if(count != MAXDWORD)
327 IdList idList = eInstance_New(_class); //IdList { };
328 idList.count = count;
329 idList.ids = new Id[count];
330 for(c = 0; c < count; c++)
333 channel.Unserialize(id);
341 void OnSerialize(IOChannel channel)
346 channel.Serialize(count);
347 for(c = 0; c < count; c++)
348 channel.Serialize(ids[c]);
353 channel.Serialize(none);
357 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
362 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
368 for(c = 0; c<count; c++)
370 char tempString[256];
371 Class type = class_data(type);
372 if(c) strcat(stringOutput, ", ");
375 type._vTbl[__ecereVMethodID_class_OnGetString](type, &ids[c], tempString, null, null);
376 // strcatf(stringOutput, "%d", ids[c]);
377 strcat(stringOutput, tempString);
383 bool OnGetDataFromString(char * string)
387 while(GetAlNum(&string, value, sizeof(value)))
388 if(isdigit(value[0]))
393 int OnCompare(IdList b)
395 if(count > b.count) return 1;
396 else if(count < b.count) return -1;
400 for(c = 0; c<count; c++)
402 int idA = ids[c], idB = b.ids[c];
403 if(idA > idB) return 1;
404 else if(idA < idB) return -1;
410 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
417 anchor = { 0, 0, 0, 0 };
419 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
421 Id id = row.GetData(null);
425 listBox.DeleteRow(row);
429 if(row == listBox.lastRow)
431 row = listBox.AddRow();
432 row.SetData(null, 0);
433 listBox.scroll.y = listBox.scrollArea.h;
435 else if(row.next == listBox.lastRow)
436 listBox.scroll.y = listBox.scrollArea.h;
446 this = eInstance_New(_class);
448 if(this || !this) // FIXME
450 Class type = class_data(type);
451 list.AddField({ type, editable = true });
453 for(c = 0; c < (this ? count : 0); c++)
456 r.SetData(null, ids[c]);
461 list.modifiedDocument = false;
465 bool OnSaveEdit(Window window, void * object)
467 ListBox list = (ListBox) window;
468 if(list.modifiedDocument)
472 this = eInstance_New(_class);
474 for(r = list.firstRow; r; r = r.next)
476 Id id = r.GetData(null);
491 static void FreeString(String string)
496 public class StringList
498 StringBinaryTree strings
500 CompareKey = (void *)BinaryTree::CompareString;
501 FreeKey = (void *)FreeString;
509 bool Includes(String string)
511 return strings.FindString(string) != null;
514 bool Add(String string)
516 BTNode node { key = (uint)CopyString(string) };
517 if(strings.Add(node))
521 FreeString((String)node.key);
527 bool Delete(String string)
529 BTNode node = strings.FindString(string);
532 strings.Delete(node);
538 void _OnUnserialize(IOChannel channel)
540 channel.Get(strings);
543 void OnUnserialize(IOChannel channel)
545 this = eInstance_New(class(StringList));
546 _OnUnserialize(channel);
549 void OnSerialize(IOChannel channel)
551 channel.Put(strings);
554 int OnCompare(StringList b)
556 BTNode nodeA = strings.first, nodeB = b.strings.first;
557 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
560 if(nodeA && !nodeB) return 1;
561 else if(nodeB && !nodeA) return -1;
564 result = strcmp((char *)nodeA.key, (char *)nodeB.key);
565 if(result) return result;
571 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
578 anchor = { 0, 0, 0, 0 };
580 bool OnKeyHit(Key key, unichar ch)
582 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
585 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
587 String string = row.GetData(null);
588 if(!string || !string[0])
592 listBox.DeleteRow(row);
593 listBox.firstChild.Activate();
598 if(row == listBox.lastRow)
600 row = listBox.AddRow();
601 row.SetData(null, null);
602 listBox.scroll.y = listBox.scrollArea.h;
608 if(row.next == listBox.lastRow)
609 listBox.scroll.y = listBox.scrollArea.h;
612 listBox.SelectRow(row);
618 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
620 listBox.firstChild.Activate();
624 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
626 String string = row.GetData(null);
627 if(!string || !string[0])
631 listBox.DeleteRow(row);
632 listBox.firstChild.Activate();
637 if(row == listBox.lastRow)
639 row = listBox.AddRow();
640 row.SetData(null, null);
641 listBox.scroll.y = listBox.scrollArea.h;
643 else if(row.next == listBox.lastRow)
644 listBox.scroll.y = listBox.scrollArea.h;
657 this = eInstance_New(_class);
661 if(this || !this) // FIXME
663 list.AddField({ class(char *), editable = true });
665 for(node = strings.first; node; node = node.next)
668 r.SetData(null, (String)node.key);
671 r.SetData(null, null);
673 list.modifiedDocument = false;
677 bool OnSaveEdit(Window window, void * object)
679 ListBox list = (ListBox) window;
680 if(list.modifiedDocument)
685 ((DataBox)list.activeChild).SaveData();
688 this = eInstance_New(_class);
690 // TODO: Fix how to get the data box...
692 for(r = list.firstRow; r; r = r.next)
694 String string = r.GetData(null);
711 public class FixedMultiLineString : String
713 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
715 // Don't show the editbox right away so that the text is highlighted by default
719 dataBox, visible = false,
721 textHorzScroll = true,
722 modifyVirtualArea = false,
723 anchor = { 0, 0, 0, 0 };
726 void DataBox::NotifyUpdate(EditBox editBox)
729 modifiedDocument = true;
732 editBox.contents = this;
733 editBox.visible = true;
737 editBox.contents = this;
741 bool OnSaveEdit(Window window, void * object)
743 bool changed = false;
744 EditBox editBox = (EditBox)window;
745 if(editBox.modifiedDocument)
753 for(line = editBox.firstLine; line; line = line.next)
754 size += line.count+1;
755 this = string = new char[size+1];
757 for(line = editBox.firstLine; line; line = line.next)
759 memcpy(string + size, line.text, line.count);
775 public class CIString : String
780 public class MultiLineString : String
782 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
784 // Don't show the editbox right away so that the text is highlighted by default
788 dataBox, visible = false,
790 hasHorzScroll = true, hasVertScroll = true,
791 modifyVirtualArea = false,
792 autoSize = dataBox.autoSize;
793 anchor = { 0, 0, 0, 0 };
796 void DataBox::NotifyUpdate(EditBox editBox)
799 modifiedDocument = true;
802 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
804 opacity = active ? 1.0f : parent.opacity;
808 editBox.contents = this;
809 editBox.visible = true;
813 editBox.contents = this;
817 bool OnSaveEdit(Window window, void * object)
819 bool changed = false;
820 EditBox editBox = (EditBox)window;
821 if(editBox.modifiedDocument)
829 for(line = editBox.firstLine; line; line = line.next)
830 size += line.count+1;
831 this = string = new char[size+1];
833 for(line = editBox.firstLine; line; line = line.next)
835 memcpy(string + size, line.text, line.count);
851 public struct DataList : OldList
853 class_data Class type;
854 class_data char * typeName;
855 // class_property Class type { set { class_data(type) = value; } };
856 class_property char * type { set { class_data(typeName) = value; } };
857 class_property Class dataType { get { return class_data(type); } };
859 void OnUnserialize(IOChannel channel)
862 if(!class_data(type))
863 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
864 type = class_data(type);
872 channel.Unserialize(truth);
878 if(type.type == structClass)
879 link.data = new0 byte[type.structSize];
880 type._vTbl[__ecereVMethodID_class_OnUnserialize](type, (type.type == structClass) ? link.data : &link.data, channel);
886 void OnSerialize(IOChannel channel)
888 OldLink node = first;
890 if(!class_data(type))
891 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
892 type = class_data(type);
899 channel.Serialize(truth);
900 if(type.type == bitClass || type.type == unitClass || (type.type == systemClass && type.typeSize))
901 type._vTbl[__ecereVMethodID_class_OnSerialize](type, &node.data, channel);
903 type._vTbl[__ecereVMethodID_class_OnSerialize](type, node.data, channel);
909 channel.Serialize(truth);
916 int OnCompare(DataList b)
918 OldLink nodeA = first, nodeB = b.first;
919 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
922 if(nodeA && !nodeB) return 1;
923 else if(nodeB && !nodeA) return -1;
926 Class type = class_data(type);
927 result = type._vTbl[__ecereVMethodID_class_OnCompare](type,
928 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeA.data : (void *)nodeA.data,
929 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeB.data : (void *)nodeB.data);
930 if(result) return result;
936 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
943 anchor = { 0, 0, 0, 0 };
945 bool OnKeyHit(Key key, unichar ch)
947 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
950 bool DataBox::NotifyChanged(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;*/
976 listBox.SelectRow(row);
983 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
985 Class type = ((subclass(DataList))this.type).dataType;
986 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
988 String string = row.GetData(null);
989 if(!string || !string[0])
993 listBox.DeleteRow(row);
994 listBox.firstChild.Activate();
999 if(row == listBox.lastRow)
1001 row = listBox.AddRow();
1002 row.SetData(null, null);
1003 listBox.scroll.y = listBox.scrollArea.h;
1005 else if(row.next == listBox.lastRow)
1006 listBox.scroll.y = listBox.scrollArea.h;
1013 bool DataBox::NotifyEditing(ListBox listBox, DataRow row)
1015 Class type = ((subclass(DataList))this.type).dataType;
1016 DataBox editData = (DataBox)listBox.firstChild;
1017 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1021 if(type.type == normalClass && !*(void **)editData.data && strcmp(type.dataTypeString, "char *"))
1023 *(void **)editData.data = eInstance_New(type);
1024 row.SetData(null, *(void **)editData.data);
1028 if(row == listBox.lastRow)
1030 listBox.alwaysEdit = false;
1031 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1032 listBox.AddRow().SetData(null, null);
1034 listBox.AddRow().SetData(null, 0);
1035 listBox.scroll.y = listBox.scrollArea.h;
1036 listBox.alwaysEdit = true;
1042 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
1044 listBox.firstChild.Activate();
1048 bool DataBox::NotifyEditDone(ListBox listBox, DataRow row)
1050 Class type = ((subclass(DataList))this.type).dataType;
1051 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1054 void * data = ((type.type == normalClass || type.type == noHeadClass || type.type == structClass) ? row.GetData(null) : *(uint *)row.GetData(null));
1057 //if(strcmp(type.dataTypeString, char *"))
1058 //listBox.currentRow = null;
1059 if(row != listBox.lastRow)
1061 listBox.alwaysEdit = false;
1062 listBox.DeleteRow(row);
1063 listBox.alwaysEdit = true;
1073 Class type = firstField.dataType;
1074 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1077 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1078 eInstance_Delete(lastRow.GetData(null));
1079 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1080 lastRow.SetData(null, null);
1082 lastRow.SetData(null, 0);
1090 if(!class_data(type))
1091 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1092 type = class_data(type);
1094 list.AddField({ type, editable = true });
1095 for(node = first; node; node = node.next)
1100 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1101 r.SetData(null, CopyString((String)node.data));
1103 r.SetData(null, node.data);
1107 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1108 r.SetData(null, null);
1112 list.modifiedDocument = false;
1116 bool OnSaveEdit(Window window, void * object)
1118 ListBox list = (ListBox) window;
1119 if(list.modifiedDocument)
1121 Class type = class_data(type);
1123 if(list.activeChild)
1124 ((DataBox)list.activeChild).SaveData();
1126 if(type.type != normalClass || !strcmp(type.dataTypeString, "char *"))
1128 else if(type.type == structClass)
1129 Free(OldLink::Free);
1133 for(r = list.firstRow; r; r = r.next)
1135 if(type.type == noHeadClass || type.type == normalClass || type.type == structClass)
1137 void * data = r.GetData(null);
1140 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1141 Add(OldLink { data = CopyString(data) });
1142 else if(type.type == structClass)
1144 OldLink link { data = new byte[type.structSize] };
1146 memcpy(link.data, data, type.structSize);
1149 Add(OldLink { data = data });
1154 uint i = r.GetData(null);
1156 Add(OldLink { data = (void *)i });
1169 if(!class_data(type))
1170 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1171 type = class_data(type);
1174 // TO STUDY: ONFREE SHOULD BE USED ONLY FOR LISTBOX?
1177 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1178 eInstance_Delete(node.data);
1179 else if(type.type == structClass)
1182 type._vTbl[__ecereVMethodID_class_OnFree](type, node.data);