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);
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 = (String)type._vTbl[__ecereVMethodID_class_OnGetString](type, (void *)&data, tempString, null, null);
213 name = (String)type._vTbl[__ecereVMethodID_class_OnGetString](type, (void *)data, tempString, null, null);
215 strcpy(tempString, name ? name : "");
216 if(!(type.type == systemClass || type.type == unitClass || type.type == bitClass || type.type == enumClass))
217 type._vTbl[__ecereVMethodID_class_OnFree](type, data);
221 PrintLn("Id::OnGetString -- data type"/*, this._class.name, */" has no class_data(nameField)");
227 sprintf(tempString, $"(Click to add a new %s...)", $"item"/*class_data(addText)*/);
230 idRowCacheMutex.Release();
241 class_data Class type;
242 class_property Class type
244 set { class_data(type) = value; }
245 get { return class_data(type); }
257 public bool Includes(Id id)
262 for(c = 0; c < count; c++)
269 public bool Add(Id id)
272 for(c = 0; c < count; c++)
273 if(ids[c] == id) break;
276 ids = renew ids Id[count + 1];
284 public bool Delete(Id id)
287 for(c = 0; c < count; c++)
291 memcpy(ids + c, ids + c + 1, (count - 1 - c) * sizeof(Id));
292 ids = renew ids Id[count - 1];
299 void OnUnserialize(IOChannel channel)
305 channel.Unserialize(count);
306 if(count != MAXDWORD)
308 IdList idList = eInstance_New(_class); //IdList { };
309 idList.count = count;
310 idList.ids = new Id[count];
311 for(c = 0; c < count; c++)
314 channel.Unserialize(id);
322 void OnSerialize(IOChannel channel)
327 channel.Serialize(count);
328 for(c = 0; c < count; c++)
329 channel.Serialize(ids[c]);
334 channel.Serialize(none);
338 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
343 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
349 for(c = 0; c<count; c++)
351 char tempString[256];
352 Class type = class_data(type);
353 if(c) strcat(stringOutput, ", ");
356 type._vTbl[__ecereVMethodID_class_OnGetString](type, &ids[c], tempString, null, null);
357 // strcatf(stringOutput, "%d", ids[c]);
358 strcat(stringOutput, tempString);
364 bool OnGetDataFromString(char * string)
368 while(GetAlNum(&string, value, sizeof(value)))
369 if(isdigit(value[0]))
374 int OnCompare(IdList b)
376 if(count > b.count) return 1;
377 else if(count < b.count) return -1;
381 for(c = 0; c<count; c++)
383 int idA = ids[c], idB = b.ids[c];
384 if(idA > idB) return 1;
385 else if(idA < idB) return -1;
391 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
398 anchor = { 0, 0, 0, 0 };
400 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
402 Id id = row.GetData(null);
406 listBox.DeleteRow(row);
410 if(row == listBox.lastRow)
412 row = listBox.AddRow();
413 row.SetData(null, 0);
414 listBox.scroll.y = listBox.scrollArea.h;
416 else if(row.next == listBox.lastRow)
417 listBox.scroll.y = listBox.scrollArea.h;
427 this = eInstance_New(_class);
429 if(this || !this) // FIXME
431 Class type = class_data(type);
432 list.AddField({ type, editable = true });
434 for(c = 0; c < (this ? count : 0); c++)
437 r.SetData(null, ids[c]);
442 list.modifiedDocument = false;
446 bool OnSaveEdit(Window window, void * object)
448 ListBox list = (ListBox) window;
449 if(list.modifiedDocument)
453 this = eInstance_New(_class);
455 for(r = list.firstRow; r; r = r.next)
457 Id id = r.GetData(null);
472 static void FreeString(String string)
477 public class StringList
479 StringBinaryTree strings
481 CompareKey = (void *)BinaryTree::CompareString;
482 FreeKey = (void *)FreeString;
490 bool Includes(String string)
492 return strings.FindString(string) != null;
495 bool Add(String string)
497 BTNode node { key = (uint)CopyString(string) };
498 if(strings.Add(node))
502 FreeString((String)node.key);
508 bool Delete(String string)
510 BTNode node = strings.FindString(string);
513 strings.Delete(node);
519 void _OnUnserialize(IOChannel channel)
521 channel.Get(strings);
524 void OnUnserialize(IOChannel channel)
526 this = eInstance_New(class(StringList));
527 _OnUnserialize(channel);
530 void OnSerialize(IOChannel channel)
532 channel.Put(strings);
535 int OnCompare(StringList b)
537 BTNode nodeA = strings.first, nodeB = b.strings.first;
538 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
541 if(nodeA && !nodeB) return 1;
542 else if(nodeB && !nodeA) return -1;
545 result = strcmp((char *)nodeA.key, (char *)nodeB.key);
546 if(result) return result;
552 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
559 anchor = { 0, 0, 0, 0 };
561 bool OnKeyHit(Key key, unichar ch)
563 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
566 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
568 String string = row.GetData(null);
569 if(!string || !string[0])
573 listBox.DeleteRow(row);
574 listBox.firstChild.Activate();
579 if(row == listBox.lastRow)
581 row = listBox.AddRow();
582 row.SetData(null, null);
583 listBox.scroll.y = listBox.scrollArea.h;
589 if(row.next == listBox.lastRow)
590 listBox.scroll.y = listBox.scrollArea.h;
593 listBox.SelectRow(row);
599 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
601 listBox.firstChild.Activate();
605 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
607 String string = row.GetData(null);
608 if(!string || !string[0])
612 listBox.DeleteRow(row);
613 listBox.firstChild.Activate();
618 if(row == listBox.lastRow)
620 row = listBox.AddRow();
621 row.SetData(null, null);
622 listBox.scroll.y = listBox.scrollArea.h;
624 else if(row.next == listBox.lastRow)
625 listBox.scroll.y = listBox.scrollArea.h;
638 this = eInstance_New(_class);
642 if(this || !this) // FIXME
644 list.AddField({ class(char *), editable = true });
646 for(node = strings.first; node; node = node.next)
649 r.SetData(null, (String)node.key);
652 r.SetData(null, null);
654 list.modifiedDocument = false;
658 bool OnSaveEdit(Window window, void * object)
660 ListBox list = (ListBox) window;
661 if(list.modifiedDocument)
666 ((DataBox)list.activeChild).SaveData();
669 this = eInstance_New(_class);
671 // TODO: Fix how to get the data box...
673 for(r = list.firstRow; r; r = r.next)
675 String string = r.GetData(null);
692 public class FixedMultiLineString : String
694 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
696 // Don't show the editbox right away so that the text is highlighted by default
700 dataBox, visible = false,
702 textHorzScroll = true,
703 modifyVirtualArea = false,
704 anchor = { 0, 0, 0, 0 };
707 void DataBox::NotifyUpdate(EditBox editBox)
710 modifiedDocument = true;
713 editBox.contents = this;
714 editBox.visible = true;
718 editBox.contents = this;
722 bool OnSaveEdit(Window window, void * object)
724 bool changed = false;
725 EditBox editBox = (EditBox)window;
726 if(editBox.modifiedDocument)
734 for(line = editBox.firstLine; line; line = line.next)
735 size += line.count+1;
736 this = string = new char[size+1];
738 for(line = editBox.firstLine; line; line = line.next)
740 memcpy(string + size, line.text, line.count);
756 public class CIString : String
761 public class MultiLineString : String
763 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
765 // Don't show the editbox right away so that the text is highlighted by default
769 dataBox, visible = false,
771 hasHorzScroll = true, hasVertScroll = true,
772 modifyVirtualArea = false,
773 autoSize = dataBox.autoSize;
774 anchor = { 0, 0, 0, 0 };
777 void DataBox::NotifyUpdate(EditBox editBox)
780 modifiedDocument = true;
783 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
785 opacity = active ? 1.0f : parent.opacity;
789 editBox.contents = this;
790 editBox.visible = true;
794 editBox.contents = this;
798 bool OnSaveEdit(Window window, void * object)
800 bool changed = false;
801 EditBox editBox = (EditBox)window;
802 if(editBox.modifiedDocument)
810 for(line = editBox.firstLine; line; line = line.next)
811 size += line.count+1;
812 this = string = new char[size+1];
814 for(line = editBox.firstLine; line; line = line.next)
816 memcpy(string + size, line.text, line.count);
832 public struct DataList : OldList
834 class_data Class type;
835 class_data char * typeName;
836 // class_property Class type { set { class_data(type) = value; } };
837 class_property char * type { set { class_data(typeName) = value; } };
838 class_property Class dataType { get { return class_data(type); } };
840 void OnUnserialize(IOChannel channel)
843 if(!class_data(type))
844 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
845 type = class_data(type);
853 channel.Unserialize(truth);
859 if(type.type == structClass)
860 link.data = new0 byte[type.structSize];
861 type._vTbl[__ecereVMethodID_class_OnUnserialize](type, (type.type == structClass) ? link.data : &link.data, channel);
867 void OnSerialize(IOChannel channel)
869 OldLink node = first;
871 if(!class_data(type))
872 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
873 type = class_data(type);
880 channel.Serialize(truth);
881 if(type.type == bitClass || type.type == unitClass || (type.type == systemClass && type.typeSize))
882 type._vTbl[__ecereVMethodID_class_OnSerialize](type, &node.data, channel);
884 type._vTbl[__ecereVMethodID_class_OnSerialize](type, node.data, channel);
890 channel.Serialize(truth);
897 int OnCompare(DataList b)
899 OldLink nodeA = first, nodeB = b.first;
900 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
903 if(nodeA && !nodeB) return 1;
904 else if(nodeB && !nodeA) return -1;
907 Class type = class_data(type);
908 result = type._vTbl[__ecereVMethodID_class_OnCompare](type,
909 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeA.data : (void *)nodeA.data,
910 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeB.data : (void *)nodeB.data);
911 if(result) return result;
917 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
924 anchor = { 0, 0, 0, 0 };
926 bool OnKeyHit(Key key, unichar ch)
928 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
931 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
933 Class type = ((subclass(DataList))this.type).dataType;
934 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
936 String string = row.GetData(null);
937 if(!string || !string[0])
941 listBox.DeleteRow(row);
942 listBox.firstChild.Activate();
947 if(row == listBox.lastRow)
949 /*row = listBox.AddRow();
950 row.SetData(null, null);
951 listBox.scroll.y = listBox.scrollArea.h;*/
957 listBox.SelectRow(row);
964 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
966 Class type = ((subclass(DataList))this.type).dataType;
967 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
969 String string = row.GetData(null);
970 if(!string || !string[0])
974 listBox.DeleteRow(row);
975 listBox.firstChild.Activate();
980 if(row == listBox.lastRow)
982 row = listBox.AddRow();
983 row.SetData(null, null);
984 listBox.scroll.y = listBox.scrollArea.h;
986 else if(row.next == listBox.lastRow)
987 listBox.scroll.y = listBox.scrollArea.h;
994 bool DataBox::NotifyEditing(ListBox listBox, DataRow row)
996 Class type = ((subclass(DataList))this.type).dataType;
997 DataBox editData = (DataBox)listBox.firstChild;
998 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1002 if(type.type == normalClass && !*(void **)editData.data && strcmp(type.dataTypeString, "char *"))
1004 *(void **)editData.data = eInstance_New(type);
1005 row.SetData(null, *(void **)editData.data);
1009 if(row == listBox.lastRow)
1011 listBox.alwaysEdit = false;
1012 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1013 listBox.AddRow().SetData(null, null);
1015 listBox.AddRow().SetData(null, 0);
1016 listBox.scroll.y = listBox.scrollArea.h;
1017 listBox.alwaysEdit = true;
1023 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
1025 listBox.firstChild.Activate();
1029 bool DataBox::NotifyEditDone(ListBox listBox, DataRow row)
1031 Class type = ((subclass(DataList))this.type).dataType;
1032 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1035 void * data = ((type.type == normalClass || type.type == noHeadClass || type.type == structClass) ? row.GetData(null) : *(uint *)row.GetData(null));
1038 //if(strcmp(type.dataTypeString, char *"))
1039 //listBox.currentRow = null;
1040 if(row != listBox.lastRow)
1042 listBox.alwaysEdit = false;
1043 listBox.DeleteRow(row);
1044 listBox.alwaysEdit = true;
1054 Class type = firstField.dataType;
1055 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1058 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1059 eInstance_Delete(lastRow.GetData(null));
1060 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1061 lastRow.SetData(null, null);
1063 lastRow.SetData(null, 0);
1071 if(!class_data(type))
1072 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1073 type = class_data(type);
1075 list.AddField({ type, editable = true });
1076 for(node = first; node; node = node.next)
1081 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1082 r.SetData(null, CopyString((String)node.data));
1084 r.SetData(null, node.data);
1088 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1089 r.SetData(null, null);
1093 list.modifiedDocument = false;
1097 bool OnSaveEdit(Window window, void * object)
1099 ListBox list = (ListBox) window;
1100 if(list.modifiedDocument)
1102 Class type = class_data(type);
1104 if(list.activeChild)
1105 ((DataBox)list.activeChild).SaveData();
1107 if(type.type != normalClass || !strcmp(type.dataTypeString, "char *"))
1109 else if(type.type == structClass)
1110 Free(OldLink::Free);
1114 for(r = list.firstRow; r; r = r.next)
1116 if(type.type == noHeadClass || type.type == normalClass || type.type == structClass)
1118 void * data = r.GetData(null);
1121 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1122 Add(OldLink { data = CopyString(data) });
1123 else if(type.type == structClass)
1125 OldLink link { data = new byte[type.structSize] };
1127 memcpy(link.data, data, type.structSize);
1130 Add(OldLink { data = data });
1135 uint i = r.GetData(null);
1137 Add(OldLink { data = (void *)i });
1150 if(!class_data(type))
1151 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1152 type = class_data(type);
1155 // TO STUDY: ONFREE SHOULD BE USED ONLY FOR LISTBOX?
1158 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1159 eInstance_Delete(node.data);
1160 else if(type.type == structClass)
1163 type._vTbl[__ecereVMethodID_class_OnFree](type, node.data);