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)");
225 sprintf(tempString, "(Invalid %s entry: %d)", tbl.name, this);
229 sprintf(tempString, $"(Click to add a new %s...)", $"item"/*class_data(addText)*/);
232 idRowCacheMutex.Release();
243 class_data Class type;
244 class_property Class type
246 set { class_data(type) = value; }
247 get { return class_data(type); }
259 public bool Includes(Id id)
264 for(c = 0; c < count; c++)
271 public bool Add(Id id)
274 for(c = 0; c < count; c++)
275 if(ids[c] == id) break;
278 ids = renew ids Id[count + 1];
286 public bool Delete(Id id)
289 for(c = 0; c < count; c++)
293 memcpy(ids + c, ids + c + 1, (count - 1 - c) * sizeof(Id));
294 ids = renew ids Id[count - 1];
301 void OnUnserialize(IOChannel channel)
307 channel.Unserialize(count);
308 if(count != MAXDWORD)
310 IdList idList = eInstance_New(_class); //IdList { };
311 idList.count = count;
312 idList.ids = new Id[count];
313 for(c = 0; c < count; c++)
316 channel.Unserialize(id);
324 void OnSerialize(IOChannel channel)
329 channel.Serialize(count);
330 for(c = 0; c < count; c++)
331 channel.Serialize(ids[c]);
336 channel.Serialize(none);
340 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
346 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
352 for(c = 0; c<count; c++)
354 char tempString[256];
355 Class type = class_data(type);
356 if(c) strcat(stringOutput, ", ");
359 type._vTbl[__ecereVMethodID_class_OnGetString](type, &ids[c], tempString, null, null);
360 // strcatf(stringOutput, "%d", ids[c]);
361 strcat(stringOutput, tempString);
367 bool OnGetDataFromString(char * string)
371 while(GetAlNum(&string, value, sizeof(value)))
372 if(isdigit(value[0]))
377 int OnCompare(IdList b)
379 if(!this && !b) return 0;
380 else if(this && !b) return 1;
381 else if(!this && b) return -1;
382 else if(count > b.count) return 1;
383 else if(count < b.count) return -1;
387 for(c = 0; c<count; c++)
389 int idA = ids[c], idB = b.ids[c];
390 if(idA > idB) return 1;
391 else if(idA < idB) return -1;
397 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
404 anchor = { 0, 0, 0, 0 };
406 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
408 Id id = row.GetData(null);
412 listBox.DeleteRow(row);
416 if(row == listBox.lastRow)
418 row = listBox.AddRow();
419 row.SetData(null, 0);
420 listBox.scroll.y = listBox.scrollArea.h;
422 else if(row.next == listBox.lastRow)
423 listBox.scroll.y = listBox.scrollArea.h;
433 this = eInstance_New(_class);
435 if(this || !this) // FIXME
437 Class type = class_data(type);
438 list.AddField({ type, editable = true });
440 for(c = 0; c < (this ? count : 0); c++)
443 r.SetData(null, ids[c]);
448 list.modifiedDocument = false;
452 bool OnSaveEdit(Window window, void * object)
454 ListBox list = (ListBox) window;
455 if(list.modifiedDocument)
459 this = eInstance_New(_class);
461 for(r = list.firstRow; r; r = r.next)
463 Id id = r.GetData(null);
478 static void FreeString(String string)
483 public class StringList
485 StringBinaryTree strings
487 CompareKey = (void *)BinaryTree::CompareString;
488 FreeKey = (void *)FreeString;
496 bool Includes(String string)
498 return strings.FindString(string) != null;
501 bool Add(String string)
503 BTNode node { key = (uintptr)CopyString(string) };
504 if(strings.Add(node))
508 FreeString((String)node.key);
514 bool Delete(String string)
516 BTNode node = strings.FindString(string);
519 strings.Delete(node);
525 void _OnUnserialize(IOChannel channel)
527 channel.Get(strings);
530 void OnUnserialize(IOChannel channel)
532 this = eInstance_New(class(StringList));
533 _OnUnserialize(channel);
536 void OnSerialize(IOChannel channel)
538 channel.Put(strings);
541 int OnCompare(StringList b)
543 BTNode nodeA = strings.first, nodeB = b.strings.first;
544 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
547 if(nodeA && !nodeB) return 1;
548 else if(nodeB && !nodeA) return -1;
551 result = strcmp((char *)nodeA.key, (char *)nodeB.key);
552 if(result) return result;
558 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
565 anchor = { 0, 0, 0, 0 };
567 bool OnKeyHit(Key key, unichar ch)
569 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
572 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
574 String string = row.GetData(null);
575 if(!string || !string[0])
579 listBox.DeleteRow(row);
580 listBox.firstChild.Activate();
585 if(row == listBox.lastRow)
587 row = listBox.AddRow();
588 row.SetData(null, null);
589 listBox.scroll.y = listBox.scrollArea.h;
595 if(row.next == listBox.lastRow)
596 listBox.scroll.y = listBox.scrollArea.h;
599 listBox.SelectRow(row);
605 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
607 listBox.firstChild.Activate();
611 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
613 String string = row.GetData(null);
614 if(!string || !string[0])
618 listBox.DeleteRow(row);
619 listBox.firstChild.Activate();
624 if(row == listBox.lastRow)
626 row = listBox.AddRow();
627 row.SetData(null, null);
628 listBox.scroll.y = listBox.scrollArea.h;
630 else if(row.next == listBox.lastRow)
631 listBox.scroll.y = listBox.scrollArea.h;
644 this = eInstance_New(_class);
648 if(this || !this) // FIXME
650 list.AddField({ class(char *), editable = true });
652 for(node = strings.first; node; node = node.next)
655 r.SetData(null, (String)node.key);
658 r.SetData(null, null);
660 list.modifiedDocument = false;
664 bool OnSaveEdit(Window window, void * object)
666 ListBox list = (ListBox) window;
667 if(list.modifiedDocument)
672 ((DataBox)list.activeChild).SaveData();
675 this = eInstance_New(_class);
677 // TODO: Fix how to get the data box...
679 for(r = list.firstRow; r; r = r.next)
681 String string = r.GetData(null);
698 public class FixedMultiLineString : String
700 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
702 // Don't show the editbox right away so that the text is highlighted by default
706 dataBox, visible = false,
708 textHorzScroll = true,
709 modifyVirtualArea = false,
710 anchor = { 0, 0, 0, 0 };
713 void DataBox::NotifyUpdate(EditBox editBox)
716 modifiedDocument = true;
719 editBox.contents = this;
720 editBox.visible = true;
724 editBox.contents = this;
728 bool OnSaveEdit(Window window, void * object)
730 bool changed = false;
731 EditBox editBox = (EditBox)window;
732 if(editBox.modifiedDocument)
740 for(line = editBox.firstLine; line; line = line.next)
741 size += line.count+1;
742 this = string = new char[size+1];
744 for(line = editBox.firstLine; line; line = line.next)
746 memcpy(string + size, line.text, line.count);
762 public class CIString : String
767 public class MultiLineString : String
769 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
771 // Don't show the editbox right away so that the text is highlighted by default
775 dataBox, visible = false,
777 hasHorzScroll = true, hasVertScroll = true,
778 modifyVirtualArea = false,
779 autoSize = dataBox.autoSize;
780 anchor = { 0, 0, 0, 0 };
783 void DataBox::NotifyUpdate(EditBox editBox)
786 modifiedDocument = true;
789 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
791 opacity = active ? 1.0f : parent.opacity;
795 editBox.contents = this;
796 editBox.visible = true;
800 editBox.contents = this;
804 bool OnSaveEdit(Window window, void * object)
806 bool changed = false;
807 EditBox editBox = (EditBox)window;
808 if(editBox.modifiedDocument)
816 for(line = editBox.firstLine; line; line = line.next)
817 size += line.count+1;
818 this = string = new char[size+1];
820 for(line = editBox.firstLine; line; line = line.next)
822 memcpy(string + size, line.text, line.count);
838 public struct DataList : OldList
840 class_data Class type;
841 class_data char * typeName;
842 // class_property Class type { set { class_data(type) = value; } };
843 class_property char * type { set { class_data(typeName) = value; } };
844 class_property Class dataType { get { return class_data(type); } };
846 void OnUnserialize(IOChannel channel)
849 if(!class_data(type))
850 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
851 type = class_data(type);
859 channel.Unserialize(truth);
865 if(type.type == structClass)
866 link.data = new0 byte[type.structSize];
867 type._vTbl[__ecereVMethodID_class_OnUnserialize](type, (type.type == structClass) ? link.data : &link.data, channel);
873 void OnSerialize(IOChannel channel)
875 OldLink node = first;
877 if(!class_data(type))
878 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
879 type = class_data(type);
886 channel.Serialize(truth);
887 if(type.type == bitClass || type.type == unitClass || (type.type == systemClass && type.typeSize))
888 type._vTbl[__ecereVMethodID_class_OnSerialize](type, &node.data, channel);
890 type._vTbl[__ecereVMethodID_class_OnSerialize](type, node.data, channel);
896 channel.Serialize(truth);
903 int OnCompare(DataList b)
905 OldLink nodeA = first, nodeB = b.first;
906 for(; nodeA || nodeB; nodeA = nodeA ? nodeA.next : null, nodeB = nodeB ? nodeB.next : null)
909 if(nodeA && !nodeB) return 1;
910 else if(nodeB && !nodeA) return -1;
913 Class type = class_data(type);
914 result = type._vTbl[__ecereVMethodID_class_OnCompare](type,
915 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeA.data : (void *)nodeA.data,
916 (type.type == systemClass || type.type == bitClass || type.type == enumClass || type.type == unitClass) ? &nodeB.data : (void *)nodeB.data);
917 if(result) return result;
923 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
930 anchor = { 0, 0, 0, 0 };
932 bool OnKeyHit(Key key, unichar ch)
934 return (key == enter) ? false : ListBox::OnKeyHit(key, ch);
937 bool DataBox::NotifyChanged(ListBox listBox, DataRow row)
939 Class type = ((subclass(DataList))this.type).dataType;
940 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
942 String string = row.GetData(null);
943 if(!string || !string[0])
947 listBox.DeleteRow(row);
948 listBox.firstChild.Activate();
953 if(row == listBox.lastRow)
955 /*row = listBox.AddRow();
956 row.SetData(null, null);
957 listBox.scroll.y = listBox.scrollArea.h;*/
963 listBox.SelectRow(row);
970 bool DataBox::NotifyModified(ListBox listBox, DataRow row)
972 Class type = ((subclass(DataList))this.type).dataType;
973 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
975 String string = row.GetData(null);
976 if(!string || !string[0])
980 listBox.DeleteRow(row);
981 listBox.firstChild.Activate();
986 if(row == listBox.lastRow)
988 row = listBox.AddRow();
989 row.SetData(null, null);
990 listBox.scroll.y = listBox.scrollArea.h;
992 else if(row.next == listBox.lastRow)
993 listBox.scroll.y = listBox.scrollArea.h;
1000 bool DataBox::NotifyEditing(ListBox listBox, DataRow row)
1002 Class type = ((subclass(DataList))this.type).dataType;
1003 DataBox editData = (DataBox)listBox.firstChild;
1004 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1008 if(type.type == normalClass && !*(void **)editData.data && strcmp(type.dataTypeString, "char *"))
1010 *(void **)editData.data = eInstance_New(type);
1011 row.SetData(null, *(void **)editData.data);
1015 if(row == listBox.lastRow)
1017 listBox.alwaysEdit = false;
1018 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1019 listBox.AddRow().SetData(null, null);
1021 listBox.AddRow().SetData(null, 0);
1022 listBox.scroll.y = listBox.scrollArea.h;
1023 listBox.alwaysEdit = true;
1029 bool DataBox::NotifyEdited(ListBox listBox, DataRow row)
1031 listBox.firstChild.Activate();
1035 bool DataBox::NotifyEditDone(ListBox listBox, DataRow row)
1037 Class type = ((subclass(DataList))this.type).dataType;
1038 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1041 void * data = ((type.type == normalClass || type.type == noHeadClass || type.type == structClass) ? row.GetData(null) : *(uint *)row.GetData(null));
1044 //if(strcmp(type.dataTypeString, char *"))
1045 //listBox.currentRow = null;
1046 if(row != listBox.lastRow)
1048 listBox.alwaysEdit = false;
1049 listBox.DeleteRow(row);
1050 listBox.alwaysEdit = true;
1060 Class type = firstField.dataType;
1061 // if(type.type != normalClass || strcmp(type.dataTypeString, "char *"))
1064 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1065 eInstance_Delete(lastRow.GetData(null));
1066 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1067 lastRow.SetData(null, null);
1069 lastRow.SetData(null, 0);
1077 if(!class_data(type))
1078 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1079 type = class_data(type);
1081 list.AddField({ type, editable = true });
1082 for(node = first; node; node = node.next)
1087 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1088 r.SetData(null, CopyString((String)node.data));
1090 r.SetData(null, node.data);
1094 if(type.type == normalClass || type.type == structClass || type.type == noHeadClass)
1095 r.SetData(null, null);
1099 list.modifiedDocument = false;
1103 bool OnSaveEdit(Window window, void * object)
1105 ListBox list = (ListBox) window;
1106 if(list.modifiedDocument)
1108 Class type = class_data(type);
1110 if(list.activeChild)
1111 ((DataBox)list.activeChild).SaveData();
1113 if(type.type != normalClass || !strcmp(type.dataTypeString, "char *"))
1115 else if(type.type == structClass)
1116 Free(OldLink::Free);
1120 for(r = list.firstRow; r; r = r.next)
1122 if(type.type == noHeadClass || type.type == normalClass || type.type == structClass)
1124 void * data = r.GetData(null);
1127 if(type.type == normalClass && !strcmp(type.dataTypeString, "char *"))
1128 Add(OldLink { data = CopyString(data) });
1129 else if(type.type == structClass)
1131 OldLink link { data = new byte[type.structSize] };
1133 memcpy(link.data, data, type.structSize);
1136 Add(OldLink { data = data });
1141 uint i = r.GetData(null);
1143 Add(OldLink { data = (void *)i });
1156 if(!class_data(type))
1157 class_data(type) = eSystem_FindClass(__thisModule.application, class_data(typeName));
1158 type = class_data(type);
1161 // TO STUDY: ONFREE SHOULD BE USED ONLY FOR LISTBOX?
1164 if(type.type == normalClass && strcmp(type.dataTypeString, "char *"))
1165 eInstance_Delete(node.data);
1166 else if(type.type == structClass)
1169 type._vTbl[__ecereVMethodID_class_OnFree](type, node.data);