source: Common/ItemList.pas

Last change on this file was 583, checked in by chronos, 10 days ago
  • Added: ItemList class and forms to Common package.
File size: 22.4 KB
Line 
1unit ItemList;
2
3interface
4
5uses
6 Classes, SysUtils, Generics.Collections, DOM, XML, Common, Graphics, Math;
7
8type
9 TUndefinedEnum = (eeNone);
10
11 TDataType = (dtNone, dtString, dtBoolean, dtInteger, dtFloat, dtColor,
12 dtTime, dtDate, dtDateTime, dtEnumeration, dtReference);
13
14 { TItemField }
15
16 TItemField = class
17 SysName: string;
18 Name: string;
19 Index: Integer;
20 DataType: TDataType;
21 Position: TPoint;
22 Size: TPoint;
23 EnumStates: TStringList;
24 VisibleIfIndex: Integer;
25 constructor Create;
26 destructor Destroy; override;
27 procedure Assign(Source: TItemField);
28 end;
29
30 { TItemFields }
31
32 TItemFields = class(TObjectList<TItemField>)
33 function AddField(Index: Integer; SysName, Name: string; DataType: TDataType): TItemField;
34 function SearchByIndex(Index: Integer): TItemField;
35 end;
36
37 TBaseItemList = class;
38
39 { TItem }
40
41 TItem = class
42 private
43 procedure AssignValue(Source: TItem; Field: TItemField);
44 function CompareValue(Item: TItem; Field: TItemField): Boolean;
45 procedure LoadValueFromNode(Node: TDOMNode; Field: TItemField); virtual;
46 procedure SaveValueToNode(Node: TDOMNode; Field: TItemField); virtual;
47 public
48 Id: Integer;
49 Name: string;
50 class function GetFields: TItemFields; virtual;
51 function GetField(Index: Integer): TItemField;
52 procedure GetValue(Index: Integer; out Value); virtual;
53 function GetValueInteger(Index: Integer): Integer;
54 function GetValueString(Index: Integer): string;
55 function GetValueColor(Index: Integer): TColor;
56 function GetValueBoolean(Index: Integer): Boolean;
57 function GetValueEnumeration(Index: Integer): TUndefinedEnum;
58 function GetValueReference(Index: Integer): TItem;
59 function GetValueAsText(Index: Integer): string;
60 procedure SetValue(Index: Integer; var Value); virtual;
61 procedure SetValueInteger(Index: Integer; Value: Integer);
62 procedure SetValueString(Index: Integer; Value: string);
63 procedure SetValueColor(Index: Integer; Value: TColor);
64 procedure SetValueBoolean(Index: Integer; Value: Boolean);
65 procedure SetValueEnumeration(Index: Integer; Value: TUndefinedEnum);
66 procedure SetValueReference(Index: Integer; Value: TItem);
67 procedure Assign(Source: TItem); virtual;
68 function Compare(Item: TItem): Boolean; virtual;
69 function ToString: string; override;
70 procedure LoadFromNode(Node: TDOMNode); virtual;
71 procedure SaveToNode(Node: TDOMNode); virtual;
72 class function GetClassSysName: string; virtual;
73 class function GetClassName: string; virtual;
74 function GetReferenceList(Index: Integer): TBaseItemList; virtual;
75 constructor Create; virtual;
76 end;
77
78 TItemClass = class of TItem;
79
80 { TBaseItemList }
81
82 TBaseItemList = class
83 public
84 type
85 TAddEvent = function (constref AValue: TItem): SizeInt of object;
86 TGetCountEvent = function: SizeInt of object;
87 TSetItemEvent = procedure(Index: SizeInt; AValue: TItem) of object;
88 TGetNameEvent = procedure (out Name: string) of object;
89 TGetItemEvent = function(Index: SizeInt): TItem of object;
90 TGetItemFieldsEvent = function: TItemFields of object;
91 TRemoveEvent = function(constref AValue: TItem): SizeInt of object;
92 TGetNextAvailableNameEvent = procedure (Name: string; out NewName: string) of object;
93 TCreateItemEvent = function(Name: string = ''): TItem of object;
94 private
95 FOnAdd: TAddEvent;
96 FOnCreateItem: TCreateItemEvent;
97 FOnGetCount: TGetCountEvent;
98 FOnGetItem: TGetItemEvent;
99 FOnGetItemFields: TGetItemFieldsEvent;
100 FOnGetName: TGetNameEvent;
101 FOnGetNextAvailableName: TGetNextAvailableNameEvent;
102 FOnRemove: TRemoveEvent;
103 FOnSetItem: TSetItemEvent;
104 procedure SetItem(Index: SizeInt; AValue: TItem);
105 function GetItem(Index: SizeInt): TItem;
106 public
107 function GetName: string;
108 function GetCount: SizeInt;
109 function Remove(constref AValue: TItem): SizeInt;
110 function Add(constref AValue: TItem): SizeInt;
111 function CreateItem(Name: string = ''): TItem;
112 function GetNextAvailableName(Name: string): string;
113 function GetItemFields: TItemFields;
114 property Count: SizeInt read GetCount;
115 property Items[Index: SizeInt]: TItem read GetItem write SetItem; default;
116 property OnAdd: TAddEvent read FOnAdd write FOnAdd;
117 property OnGetCount: TGetCountEvent read FOnGetCount write FOnGetCount;
118 property OnSetItem: TSetItemEvent read FOnSetItem write FOnSetItem;
119 property OnGetItem: TGetItemEvent read FOnGetItem write FOnGetItem;
120 property OnGetName: TGetNameEvent read FOnGetName write FOnGetName;
121 property OnRemove: TRemoveEvent read FOnRemove write FOnRemove;
122 property OnGetItemFields: TGetItemFieldsEvent read FOnGetItemFields write FOnGetItemFields;
123 property OnGetNextAvailableName: TGetNextAvailableNameEvent read
124 FOnGetNextAvailableName write FOnGetNextAvailableName;
125 property OnCreateItem: TCreateItemEvent read FOnCreateItem
126 write FOnCreateItem;
127 end;
128
129 { TItemList }
130
131 TItemList<T: TItem> = class(TObjectList<T>)
132 private
133 FBaseItemList: TBaseItemList;
134 procedure RecalculateNewId(Reset: Boolean);
135 procedure RecalculateItemsId;
136 function BaseGetItem(Index: SizeInt): TItem;
137 procedure BaseSetItem(Index: SizeInt; AValue: TItem);
138 function BaseAdd(constref AValue: TItem): SizeInt;
139 function BaseGetCount: SizeInt;
140 procedure BaseGetName(out Name: string);
141 function BaseRemove(constref AValue: TItem): SizeInt;
142 function BaseGetItemFields: TItemFields;
143 function BaseCreateItem(Name: string = ''): TItem;
144 procedure BaseGetNextAvailableName(Name: string; out NewName: string);
145 public
146 NewId: Integer;
147 function CreateItem(Name: string = ''): T; virtual;
148 function IncrementName(Name: string): string;
149 function FindById(Id: Integer): T;
150 function FindByName(Name: string): T;
151 function GetNewId: Integer;
152 function ToString: string; override;
153 procedure Assign(Source: TItemList<T>); virtual;
154 function Compare(ItemList: TItemList<T>): Boolean; virtual;
155 function AddItem(Name: string = ''): T; virtual;
156 procedure LoadFromNode(Node: TDOMNode); virtual;
157 procedure SaveToNode(Node: TDOMNode); virtual;
158 constructor Create(FreeObjects: Boolean = True);
159 destructor Destroy; override;
160 property BaseItemList: TBaseItemList read FBaseItemList;
161 end;
162
163const
164 DataTypeStr: array[TDataType] of string = ('None', 'String', 'Boolean',
165 'Integer', 'Float', 'Color', 'Time', 'Date', 'DateTime', 'Enumeration',
166 'Reference');
167
168resourcestring
169 SUnsupportedDataType = 'Unsupported field value data type %s';
170 SUnsupportedValueIndex = 'Unsupported value index %d';
171
172
173implementation
174
175resourcestring
176 SYes = 'Yes';
177 SNo = 'No';
178 SItem = 'Item';
179 SName = 'Name';
180
181{ TItemField }
182
183constructor TItemField.Create;
184begin
185 EnumStates := TStringList.Create;
186end;
187
188destructor TItemField.Destroy;
189begin
190 FreeAndNil(EnumStates);
191 inherited;
192end;
193
194procedure TItemField.Assign(Source: TItemField);
195begin
196 SysName := Source.SysName;
197 Name := Source.Name;
198 Index := Source.Index;
199 DataType := Source.DataType;
200 Position := Source.Position;
201 Size := Source.Size;
202 EnumStates.Assign(Source.EnumStates);
203end;
204
205{ TItemList }
206
207procedure TItemList<T>.Assign(Source: TItemList<T>);
208var
209 I: Integer;
210begin
211 while Count > Source.Count do Delete(Count - 1);
212 while Count < Source.Count do AddItem('');
213 for I := 0 to Count - 1 do
214 Items[I].Assign(Source.Items[I]);
215end;
216
217function TItemList<T>.Compare(ItemList: TItemList<T>): Boolean;
218var
219 I: Integer;
220begin
221 Result := Count = ItemList.Count;
222 if not Result then Exit;
223 for I := 0 to Count - 1 do begin
224 Result := Result and TItem(Items[I]).Compare(ItemList.Items[I]);
225 if not Result then Break;
226 end;
227end;
228
229function TItemList<T>.AddItem(Name: string): T;
230begin
231 Result := CreateItem(Name);
232 Result.Id := GetNewId;
233 Add(Result);
234end;
235
236function TItemList<T>.CreateItem(Name: string): T;
237begin
238 Result := T.Create;
239 Result.Name := Name;
240end;
241
242function TItemList<T>.BaseCreateItem(Name: string): TItem;
243begin
244 Result := TItem(CreateItem(Name));
245end;
246
247procedure TItemList<T>.LoadFromNode(Node: TDOMNode);
248var
249 Node2: TDOMNode;
250 NewItem: T;
251begin
252 Count := 0;
253 Node2 := Node.FirstChild;
254 while Assigned(Node2) and (Node2.NodeName = UnicodeString(T.GetClassSysName)) do begin
255 NewItem := CreateItem;
256 NewItem.LoadFromNode(Node2);
257 Add(NewItem);
258 Node2 := Node2.NextSibling;
259 end;
260end;
261
262procedure TItemList<T>.SaveToNode(Node: TDOMNode);
263var
264 I: Integer;
265 NewNode2: TDOMNode;
266begin
267 RecalculateItemsId;
268 for I := 0 to Count - 1 do
269 with TItem(Items[I]) do begin
270 NewNode2 := Node.OwnerDocument.CreateElement(UnicodeString(T.GetClassSysName));
271 Node.AppendChild(NewNode2);
272 SaveToNode(NewNode2);
273 end;
274end;
275
276constructor TItemList<T>.Create(FreeObjects: Boolean);
277begin
278 inherited;
279 FBaseItemList := TBaseItemList.Create;
280 FBaseItemList.OnAdd := BaseAdd;
281 FBaseItemList.OnGetCount := BaseGetCount;
282 FBaseItemList.OnSetItem := BaseSetItem;
283 FBaseItemList.OnGetItem := BaseGetItem;
284 FBaseItemList.OnRemove := BaseRemove;
285 FBaseItemList.OnGetItemFields := BaseGetItemFields;
286 FBaseItemList.OnCreateItem := BaseCreateItem;
287 FBaseItemList.OnGetNextAvailableName := BaseGetNextAvailableName;
288 FBaseItemList.OnGetName := BaseGetName;
289 NewId := 1;
290end;
291
292destructor TItemList<T>.Destroy;
293begin
294 FreeAndNil(FBaseItemList);
295 inherited;
296end;
297
298function TItemList<T>.BaseGetCount: SizeInt;
299begin
300 Result := Count;
301end;
302
303procedure TItemList<T>.BaseGetName(out Name: string);
304begin
305 Name := T.GetClassName;
306end;
307
308function TItemList<T>.BaseGetItemFields: TItemFields;
309begin
310 Result := T.GetFields;
311end;
312
313function TItemList<T>.BaseRemove(constref AValue: TItem): SizeInt;
314begin
315 Result := inherited Remove(T(AValue));
316end;
317
318function TItemList<T>.BaseAdd(constref AValue: TItem): SizeInt;
319begin
320 Result := inherited Add(T(AValue));
321 AValue.Id := GetNewId;
322end;
323
324procedure TItemList<T>.RecalculateNewId(Reset: Boolean);
325var
326 I: Integer;
327begin
328 NewId := 1;
329 for I := 0 to Count - 1 do
330 with TItem(Items[I]) do begin
331 NewId := Max(NewId, Id + 1);
332 end;
333end;
334
335procedure TItemList<T>.RecalculateItemsId;
336var
337 I: Integer;
338begin
339 for I := 0 to Count - 1 do
340 Items[I].Id := I + 1;
341 NewId := Count + 1;
342end;
343
344function TItemList<T>.BaseGetItem(Index: SizeInt): TItem;
345begin
346 Result := inherited GetItem(Index);
347end;
348
349procedure TItemList<T>.BaseSetItem(Index: SizeInt; AValue: TItem);
350begin
351 inherited SetItem(Index, T(AValue));
352end;
353
354function TItemList<T>.IncrementName(Name: string): string;
355var
356 I: Integer;
357 Num: Integer;
358begin
359 I := LastPos(' ', Name);
360 if I > 0 then begin
361 if TryStrToInt(Copy(Name, I + 1, Length(Name)), Num) then
362 Result := Trim(Copy(Name, 1, I - 1)) + ' ' + IntToStr(Num + 1)
363 else Result := Name + ' 2';
364 end else Result := Name + ' 2';
365end;
366
367procedure TItemList<T>.BaseGetNextAvailableName(Name: string; out
368 NewName: string);
369begin
370 NewName := Name;
371 while Assigned(FindByName(NewName)) do
372 NewName := IncrementName(NewName);
373end;
374
375function TItemList<T>.FindById(Id: Integer): T;
376var
377 I: Integer;
378begin
379 I := 0;
380 while (I < Count) and (Items[I].Id <> Id) do Inc(I);
381 if I < Count then Result := Items[I]
382 else Result := nil;
383end;
384
385function TItemList<T>.FindByName(Name: string): T;
386var
387 I: Integer;
388begin
389 I := 0;
390 while (I < Count) and (Items[I].Name <> Name) do Inc(I);
391 if I < Count then Result := Items[I]
392 else Result := nil;
393end;
394
395function TItemList<T>.GetNewId: Integer;
396begin
397 Result := NewId;
398 Inc(NewId);
399end;
400
401function TItemList<T>.ToString: string;
402var
403 I: Integer;
404begin
405 Result := '';
406 for I := 0 to Count - 1 do
407 with TItem(Items[I]) do begin
408 Result := Result + ToString + LineEnding;
409 end;
410end;
411
412{ TItemFields }
413
414function TItemFields.AddField(Index: Integer; SysName, Name: string; DataType: TDataType): TItemField;
415begin
416 Result := TItemField.Create;
417 Result.Index := Index;
418 Result.Name := Name;
419 Result.SysName := SysName;
420 Result.DataType := DataType;
421 Add(Result);
422end;
423
424function TItemFields.SearchByIndex(Index: Integer): TItemField;
425var
426 I: Integer;
427begin
428 I := 0;
429 while (I < Count) and (Items[I].Index <> Index) do Inc(I);
430 if I < Count then Result := Items[I]
431 else Result := nil;
432end;
433
434{ TItem }
435
436procedure TItem.AssignValue(Source: TItem; Field: TItemField);
437begin
438 if Field.DataType = dtString then begin
439 SetValueString(Field.Index, Source.GetValueString(Field.Index));
440 end else
441 if Field.DataType = dtColor then begin
442 SetValueColor(Field.Index, Source.GetValueColor(Field.Index));
443 end else
444 if Field.DataType = dtInteger then begin
445 SetValueInteger(Field.Index, Source.GetValueInteger(Field.Index));
446 end else
447 if Field.DataType = dtBoolean then begin
448 SetValueBoolean(Field.Index, Source.GetValueBoolean(Field.Index));
449 end else
450 if Field.DataType = dtEnumeration then begin
451 SetValueEnumeration(Field.Index, Source.GetValueEnumeration(Field.Index));
452 end else
453 if Field.DataType = dtReference then begin
454 SetValueReference(Field.Index, Source.GetValueReference(Field.Index));
455 end else
456 raise Exception.Create(Format(SUnsupportedDataType, [DataTypeStr[Field.DataType]]));
457end;
458
459function TItem.CompareValue(Item: TItem; Field: TItemField): Boolean;
460begin
461 if Field.DataType = dtString then begin
462 Result := GetValueString(Field.Index) = Item.GetValueString(Field.Index);
463 end else
464 if Field.DataType = dtColor then begin
465 Result := GetValueColor(Field.Index) = Item.GetValueColor(Field.Index);
466 end else
467 if Field.DataType = dtInteger then begin
468 Result := GetValueInteger(Field.Index) = Item.GetValueInteger(Field.Index);
469 end else
470 if Field.DataType = dtBoolean then begin
471 Result := GetValueBoolean(Field.Index) = Item.GetValueBoolean(Field.Index);
472 end else
473 if Field.DataType = dtEnumeration then begin
474 Result := GetValueEnumeration(Field.Index) = Item.GetValueEnumeration(Field.Index);
475 end else
476 if Field.DataType = dtReference then begin
477 Result := GetValueReference(Field.Index) = Item.GetValueReference(Field.Index);
478 end else
479 raise Exception.Create(Format(SUnsupportedDataType, [DataTypeStr[Field.DataType]]));
480end;
481
482procedure TItem.LoadValueFromNode(Node: TDOMNode; Field: TItemField);
483var
484 ReadId: Integer;
485 ReferenceList: TBaseItemList;
486begin
487 if Field.DataType = dtString then begin
488 SetValueString(Field.Index, ReadString(Node, Field.SysName, ''));
489 end else
490 if Field.DataType = dtColor then begin
491 SetValueColor(Field.Index, ReadInteger(Node, Field.SysName, 0));
492 end else
493 if Field.DataType = dtInteger then begin
494 SetValueInteger(Field.Index, ReadInteger(Node, Field.SysName, 0));
495 end else
496 if Field.DataType = dtBoolean then begin
497 SetValueBoolean(Field.Index, ReadBoolean(Node, Field.SysName, False));
498 end else
499 if Field.DataType = dtEnumeration then begin
500 SetValueEnumeration(Field.Index, TUndefinedEnum(ReadInteger(Node, Field.SysName, 0)));
501 end else
502 if Field.DataType = dtReference then begin
503 ReadId := ReadInteger(Node, Field.SysName, 0);
504 ReferenceList := GetReferenceList(Field.Index);
505 if (ReadId > 0) and Assigned(ReferenceList) then
506 SetValueReference(Field.Index, TItem(ReferenceList[ReadId]));
507 end else
508 raise Exception.Create(Format(SUnsupportedDataType, [DataTypeStr[Field.DataType]]));
509end;
510
511procedure TItem.SaveValueToNode(Node: TDOMNode; Field: TItemField);
512var
513 Item: TItem;
514begin
515 if Field.DataType = dtString then begin
516 WriteString(Node, Field.SysName, GetValueString(Field.Index));
517 end else
518 if Field.DataType = dtColor then begin
519 WriteInteger(Node, Field.SysName, GetValueColor(Field.Index));
520 end else
521 if Field.DataType = dtInteger then begin
522 WriteInteger(Node, Field.SysName, GetValueInteger(Field.Index));
523 end else
524 if Field.DataType = dtBoolean then begin
525 WriteBoolean(Node, Field.SysName, GetValueBoolean(Field.Index));
526 end else
527 if Field.DataType = dtEnumeration then begin
528 WriteInteger(Node, Field.SysName, Integer(GetValueEnumeration(Field.Index)));
529 end else
530 if Field.DataType = dtReference then begin
531 Item := TItem(GetValueReference(Field.Index));
532 if Assigned(Item) then WriteInteger(Node, Field.SysName, Item.Id)
533 else WriteInteger(Node, Field.SysName, 0);
534 end else
535 raise Exception.Create(Format(SUnsupportedDataType, [DataTypeStr[Field.DataType]]));
536end;
537
538class function TItem.GetFields: TItemFields;
539begin
540 Result := TItemFields.Create;
541 Result.AddField(1, 'Name', SName, dtString);
542end;
543
544function TItem.GetField(Index: Integer): TItemField;
545var
546 Fields: TItemFields;
547begin
548 Result := TItemField.Create;
549 Fields := GetFields;
550 try
551 Result.Assign(Fields.SearchByIndex(Index));
552 finally
553 Fields.Free;
554 end;
555end;
556
557procedure TItem.GetValue(Index: Integer; out Value);
558begin
559 raise Exception.Create(Format(SUnsupportedValueIndex, [Index]));
560end;
561
562function TItem.GetValueString(Index: Integer): string;
563begin
564 GetValue(Index, Result);
565end;
566
567function TItem.GetValueInteger(Index: Integer): Integer;
568begin
569 GetValue(Index, Result);
570end;
571
572function TItem.GetValueColor(Index: Integer): TColor;
573begin
574 GetValue(Index, Result);
575end;
576
577function TItem.GetValueBoolean(Index: Integer): Boolean;
578begin
579 GetValue(Index, Result);
580end;
581
582function TItem.GetValueEnumeration(Index: Integer): TUndefinedEnum;
583begin
584 GetValue(Index, Result);
585end;
586
587function TItem.GetValueReference(Index: Integer): TItem;
588begin
589 GetValue(Index, Result);
590end;
591
592function TItem.GetValueAsText(Index: Integer): string;
593var
594 Field: TItemField;
595 Item: TItem;
596begin
597 Field := GetField(Index);
598 try
599 if Field.DataType = dtInteger then Result := IntToStr(GetValueInteger(Index))
600 else if Field.DataType = dtString then Result := GetValueString(Index)
601 else if Field.DataType = dtColor then Result := ''
602 else if Field.DataType = dtEnumeration then Result := Field.EnumStates[Integer(GetValueEnumeration(Index))]
603 else if Field.DataType = dtReference then begin
604 Item := TItem(GetValueReference(Index));
605 if Assigned(Item) then Result := Item.Name
606 else Result := '';
607 end else if Field.DataType = dtBoolean then begin
608 if GetValueBoolean(Index) then Result := SYes else Result := SNo;
609 end else
610 raise Exception.Create(Format(SUnsupportedDataType, [DataTypeStr[Field.DataType]]));
611 finally
612 Field.Free;
613 end;
614end;
615
616procedure TItem.SetValue(Index: Integer; var Value);
617begin
618 raise Exception.Create(Format(SUnsupportedValueIndex, [Index]));
619end;
620
621procedure TItem.SetValueInteger(Index: Integer; Value: Integer);
622begin
623 SetValue(Index, Value);
624end;
625
626procedure TItem.SetValueString(Index: Integer; Value: string);
627begin
628 SetValue(Index, Value);
629end;
630
631procedure TItem.SetValueColor(Index: Integer; Value: TColor);
632begin
633 SetValue(Index, Value);
634end;
635
636procedure TItem.SetValueBoolean(Index: Integer; Value: Boolean);
637begin
638 SetValue(Index, Value);
639end;
640
641procedure TItem.SetValueEnumeration(Index: Integer;
642 Value: TUndefinedEnum);
643begin
644 SetValue(Index, Value);
645end;
646
647procedure TItem.SetValueReference(Index: Integer; Value: TItem);
648begin
649 SetValue(Index, Value);
650end;
651
652procedure TItem.Assign(Source: TItem);
653var
654 I: Integer;
655 Fields: TItemFields;
656begin
657 Id := Source.Id;
658 if Source is ClassType then begin
659 Fields := GetFields;
660 try
661 for I := 0 to Fields.Count - 1 do
662 AssignValue(Source, Fields[I]);
663 finally
664 Fields.Free;
665 end;
666 end;
667end;
668
669function TItem.Compare(Item: TItem): Boolean;
670var
671 I: Integer;
672 Fields: TItemFields;
673begin
674 Result := True;
675 Result := Result and (Id = Item.Id);
676 if Item is ClassType then begin
677 Fields := GetFields;
678 try
679 for I := 0 to Fields.Count - 1 do begin
680 Result := Result and CompareValue(Item, Fields[I]);
681 if not Result then Break;
682 end;
683 finally
684 Fields.Free;
685 end;
686 end;
687end;
688
689function TItem.ToString: string;
690var
691 Fields: TItemFields;
692 I: Integer;
693begin
694 Result := 'Id: ' + IntToStr(Id) + LineEnding;
695 Fields := GetFields;
696 try
697 for I := 0 to Fields.Count - 1 do begin
698 Result := Result + Fields[I].SysName + ': ' + GetValueAsText(Fields[I].Index) + LineEnding;
699 end;
700 finally
701 Fields.Free;
702 end;
703end;
704
705procedure TItem.LoadFromNode(Node: TDOMNode);
706var
707 Fields: TItemFields;
708 I: Integer;
709begin
710 Id := ReadInteger(Node, 'Id', 0);
711 Fields := GetFields;
712 try
713 for I := 0 to Fields.Count - 1 do begin
714 LoadValueFromNode(Node, Fields[I]);
715 end;
716 finally
717 Fields.Free;
718 end;
719end;
720
721procedure TItem.SaveToNode(Node: TDOMNode);
722var
723 Fields: TItemFields;
724 I: Integer;
725begin
726 WriteInteger(Node, 'Id', Id);
727 Fields := GetFields;
728 try
729 for I := 0 to Fields.Count - 1 do begin
730 SaveValueToNode(Node, Fields[I]);
731 end;
732 finally
733 Fields.Free;
734 end;
735end;
736
737class function TItem.GetClassSysName: string;
738begin
739 Result := 'Item';
740end;
741
742class function TItem.GetClassName: string;
743begin
744 Result := SItem;
745end;
746
747function TItem.GetReferenceList(Index: Integer): TBaseItemList;
748begin
749 Result := nil;
750end;
751
752constructor TItem.Create;
753begin
754end;
755
756{ TBaseItemList }
757
758procedure TBaseItemList.SetItem(Index: SizeInt; AValue: TItem);
759begin
760 if Assigned(FOnSetItem) then FOnSetItem(Index, AValue)
761 else raise Exception.Create('Undefined SetItem handler');
762end;
763
764function TBaseItemList.GetName: string;
765var
766 Name: string;
767begin
768 if Assigned(FOnGetName) then begin
769 FOnGetName(Name);
770 Result := Name;
771 end else raise Exception.Create('Undefined GetName handler');
772end;
773
774function TBaseItemList.GetCount: SizeInt;
775begin
776 if Assigned(FOnGetCount) then Result := FOnGetCount
777 else raise Exception.Create('Undefined GetCount handler');
778end;
779
780function TBaseItemList.GetItem(Index: SizeInt): TItem;
781begin
782 if Assigned(FOnGetItem) then Result := FOnGetItem(Index)
783 else raise Exception.Create('Undefined GetItem handler');
784end;
785
786function TBaseItemList.Remove(constref AValue: TItem): SizeInt;
787begin
788 if Assigned(FOnRemove) then Result := FOnRemove(AValue)
789 else raise Exception.Create('Undefined Remove handler');
790end;
791
792function TBaseItemList.Add(constref AValue: TItem): SizeInt;
793begin
794 if Assigned(FOnAdd) then Result := FOnAdd(AValue)
795 else raise Exception.Create('Undefined Add handler');
796end;
797
798function TBaseItemList.CreateItem(Name: string): TItem;
799begin
800 if Assigned(FOnCreateItem) then Result := FOnCreateItem(Name)
801 else raise Exception.Create('Undefined CreateItem handler');
802end;
803
804function TBaseItemList.GetNextAvailableName(Name: string): string;
805var
806 NewName: string;
807begin
808 if Assigned(FOnGetNextAvailableName) then begin
809 FOnGetNextAvailableName(Name, NewName);
810 Result := NewName;
811 end else raise Exception.Create('Undefined GetNextAvailableName handler');
812end;
813
814function TBaseItemList.GetItemFields: TItemFields;
815begin
816 if Assigned(FOnGetItemFields) then Result := FOnGetItemFields
817 else raise Exception.Create('Undefined GetItemFields handler');
818end;
819
820end.
821
Note: See TracBrowser for help on using the repository browser.