* fixed leaks in uutlGenerics and uutlObservable * implemented TryGet methods fpr TutlMcfSection * implemented TryGet methods fpr TutlXmlHelpermaster
| @@ -22,7 +22,10 @@ type | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TutlEventHandler = procedure (constref aSender: TObject; constref aEventArgs: IutlEventArgs) of object; | |||
| TutlEventArgs = class(TInterfacedObject, IutlEventArgs); | |||
| TutlEventArgs = class(TutlInterfacedObject, IutlEventArgs) | |||
| public | |||
| constructor Create; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| IutlObservable = interface(IUnknown) | |||
| @@ -93,7 +96,7 @@ type | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TutlEventListenerAsync = class( | |||
| TutlInterfaceNoRefCount | |||
| TInterfacedObject | |||
| , IutlEventListener) | |||
| private type | |||
| @@ -104,10 +107,9 @@ type | |||
| end; | |||
| private | |||
| fEventLock: TCriticalSection; | |||
| fListenerLock: TCriticalSection; | |||
| fEvents: TEventList; | |||
| fListener: TutlEventListenerSet; | |||
| fEventLock: TCriticalSection; | |||
| fEvents: TEventList; | |||
| fListener: IutlEventListener; | |||
| function PopEventPair(out aPair: TEventPair): Boolean; | |||
| @@ -115,17 +117,23 @@ type | |||
| procedure DispatchEvent(constref aSender: TObject; constref aEventArgs: IutlEventArgs); | |||
| public | |||
| function RegisterListener (const aListener: IutlEventListener): Boolean; | |||
| function UnregisterListener(const aListener: IutlEventListener): Boolean; | |||
| procedure DispatchEvents; | |||
| constructor Create; | |||
| constructor Create(const aListener: IutlEventListener); | |||
| destructor Destroy; override; | |||
| end; | |||
| implementation | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //TutlEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TutlEventArgs.Create; | |||
| begin | |||
| inherited Create; | |||
| AutoFree := true; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //TutlEventList///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -272,67 +280,37 @@ begin | |||
| end; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlEventListenerAsync.RegisterListener(const aListener: IutlEventListener): Boolean; | |||
| begin | |||
| fListenerLock.Enter; | |||
| try | |||
| result := fListener.Add(aListener); | |||
| finally | |||
| fListenerLock.Leave; | |||
| end; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlEventListenerAsync.UnregisterListener(const aListener: IutlEventListener): Boolean; | |||
| begin | |||
| fListenerLock.Enter; | |||
| try | |||
| result := fListener.Remove(aListener); | |||
| finally | |||
| fListenerLock.Leave; | |||
| end; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlEventListenerAsync.DispatchEvents; | |||
| var | |||
| p: TEventPair; | |||
| begin | |||
| while PopEventPair(p) do begin | |||
| fListenerLock.Enter; | |||
| try | |||
| fListener.DispatchEvent(p.first, p.second); | |||
| finally | |||
| fListenerLock.Leave; | |||
| end; | |||
| end; | |||
| while PopEventPair(p) do | |||
| fListener.DispatchEvent(p.first, p.second); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TutlEventListenerAsync.Create; | |||
| constructor TutlEventListenerAsync.Create(const aListener: IutlEventListener); | |||
| begin | |||
| if not Assigned(aListener) then | |||
| raise EArgumentNilException.Create('aListener'); | |||
| inherited Create; | |||
| fEventLock := TCriticalSection.Create; | |||
| fListenerLock := TCriticalSection.Create; | |||
| fEvents := TEventList.Create(true); | |||
| fListener := TutlEventListenerSet.Create; | |||
| fEventLock := TCriticalSection.Create; | |||
| fEvents := TEventList.Create(true); | |||
| fListener := aListener; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| destructor TutlEventListenerAsync.Destroy; | |||
| begin | |||
| fEventLock.Enter; | |||
| fListenerLock.Enter; | |||
| try | |||
| FreeAndNil(fEvents); | |||
| FreeAndNil(fListener); | |||
| fListener := nil; | |||
| finally | |||
| fListenerLock.Leave; | |||
| fEventLock.Leave; | |||
| end; | |||
| FreeAndNil(fEventLock); | |||
| FreeAndNil(fListenerLock); | |||
| inherited Destroy; | |||
| end; | |||
| @@ -14,8 +14,8 @@ uses | |||
| type | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TutlEventType = byte; | |||
| TutlEventTypes = set of TutlEventType; | |||
| TutlEventType = byte; | |||
| TutlEventTypes = set of TutlEventType; | |||
| TutlMouseButtons = set of TMouseButton; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -48,7 +48,7 @@ type | |||
| property ScreenPos: TPoint read fScreenPos; | |||
| constructor Create( | |||
| const aSender: TControl; | |||
| const aControl: TControl; | |||
| const aEventType: TutlEventType; | |||
| const aButtons: TutlMouseButtons; | |||
| const aClientPos: TPoint); | |||
| @@ -67,7 +67,7 @@ type | |||
| property ScreenPos: TPoint read fScreenPos; | |||
| constructor Create( | |||
| const aSender: TControl; | |||
| const aControl: TControl; | |||
| const aWheelDelta: Integer; | |||
| const aClientPos: TPoint); | |||
| end; | |||
| @@ -83,7 +83,7 @@ type | |||
| property KeyCode: Word read fKeyCode; | |||
| constructor Create( | |||
| const aSender: TControl; | |||
| const aControl: TControl; | |||
| const aEventType: TutlEventType; | |||
| const aCharCode: WideChar; | |||
| const aKeyCode: Word); | |||
| @@ -102,7 +102,7 @@ type | |||
| property ClientHeight: Cardinal read fClientHeight; | |||
| constructor Create( | |||
| const aSender: TControl; | |||
| const aControl: TControl; | |||
| const aEventType: TutlEventType; | |||
| const aScreenRect: TRect; | |||
| const aClientWidth: Cardinal; | |||
| @@ -152,6 +152,17 @@ type | |||
| EVENT_WINDOW_DEACTIVATE | |||
| ]; | |||
| public type | |||
| TutlEventType = uutlEventManager.TutlEventType; | |||
| TutlEventTypes = uutlEventManager.TutlEventTypes; | |||
| TutlMouseButtons = uutlEventManager.TutlMouseButtons; | |||
| TutlWinControlEventArgs = uutlEventManager.TutlWinControlEventArgs; | |||
| TutlMouseEventArgs = uutlEventManager.TutlMouseEventArgs; | |||
| TutlMouseWheelEventArgs = uutlEventManager.TutlMouseWheelEventArgs; | |||
| TutlKeyEventArgs = uutlEventManager.TutlKeyEventArgs; | |||
| TutlWindowEventArgs = uutlEventManager.TutlWindowEventArgs; | |||
| private type | |||
| TKeyboardState = record | |||
| Modifiers: TShiftState; | |||
| @@ -170,6 +181,7 @@ type | |||
| ClientWidth: Integer; | |||
| ClientHeight: Integer; | |||
| end; | |||
| private | |||
| fKeyboard: TKeyboardState; | |||
| fMouse: TMouseState; | |||
| @@ -195,23 +207,24 @@ type | |||
| procedure RecordEvent(constref aEventArgs: IutlEventArgs); virtual; | |||
| function CreateMouseEventArgs( | |||
| aSender: TObject; | |||
| aControl: TControl; | |||
| aType: TutlEventType; | |||
| aButtons: TutlMouseButtons; | |||
| aClientPos: TPoint): TutlMouseEventArgs; virtual; | |||
| aClientPos: TPoint): IutlEventArgs; virtual; | |||
| function CreateMouseWheelEventArgs( | |||
| aSender: TObject; | |||
| aControl: TControl; | |||
| aDelta: Integer; | |||
| aClientPos: TPoint): TutlMouseWheelEventArgs; virtual; | |||
| aClientPos: TPoint): IutlEventArgs; virtual; | |||
| function CreateKeyEventArgs( | |||
| aSender: TObject; aType: TutlEventType; | |||
| aKey: Word): TutlKeyEventArgs; virtual; | |||
| aControl: TControl; | |||
| aType: TutlEventType; | |||
| aKey: Word): IutlEventArgs; virtual; | |||
| function CreateWindowEventArgs( | |||
| aSender: TObject; | |||
| aType: TutlEventType): TutlWindowEventArgs; virtual; | |||
| aControl: TControl; | |||
| aType: TutlEventType): IutlEventArgs; virtual; | |||
| public | |||
| property Keyboard: TKeyboardState read fKeyboard; | |||
| @@ -262,12 +275,12 @@ end; | |||
| //TutlMouseEventArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TutlMouseEventArgs.Create( | |||
| const aSender: TControl; | |||
| const aControl: TControl; | |||
| const aEventType: TutlEventType; | |||
| const aButtons: TutlMouseButtons; | |||
| const aClientPos: TPoint); | |||
| begin | |||
| inherited Create(aSender, aEventType); | |||
| inherited Create(aControl, aEventType); | |||
| fButtons := aButtons; | |||
| fClientPos := aClientPos; | |||
| fScreenPos := Control.ClientToScreen(fClientPos); | |||
| @@ -277,13 +290,13 @@ end; | |||
| //TutlMouseWheelEventArgs//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TutlMouseWheelEventArgs.Create( | |||
| const aSender: TControl; | |||
| const aControl: TControl; | |||
| const aWheelDelta: Integer; | |||
| const aClientPos: TPoint); | |||
| begin | |||
| if (aWheelDelta < 0) | |||
| then inherited Create(aSender, TutlWinControlEventManager.EVENT_MOUSE_WHEEL_DOWN) | |||
| else inherited Create(aSender, TutlWinControlEventManager.EVENT_MOUSE_WHEEL_UP); | |||
| then inherited Create(aControl, TutlWinControlEventManager.EVENT_MOUSE_WHEEL_DOWN) | |||
| else inherited Create(aControl, TutlWinControlEventManager.EVENT_MOUSE_WHEEL_UP); | |||
| fWheelDelta := aWheelDelta; | |||
| fClientPos := aClientPos; | |||
| fScreenPos := Control.ClientToScreen(fClientPos); | |||
| @@ -293,12 +306,12 @@ end; | |||
| //TutlKeyEventArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TutlKeyEventArgs.Create( | |||
| const aSender: TControl; | |||
| const aControl: TControl; | |||
| const aEventType: TutlEventType; | |||
| const aCharCode: WideChar; | |||
| const aKeyCode: Word); | |||
| begin | |||
| inherited Create(aSender, aEventType); | |||
| inherited Create(aControl, aEventType); | |||
| fCharCode := aCharCode; | |||
| fKeyCode := aKeyCode; | |||
| end; | |||
| @@ -307,13 +320,13 @@ end; | |||
| //TutlWindowEventArgs//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TutlWindowEventArgs.Create( | |||
| const aSender: TControl; | |||
| const aControl: TControl; | |||
| const aEventType: TutlEventType; | |||
| const aScreenRect: TRect; | |||
| const aClientWidth: Cardinal; | |||
| const aClientHeight: Cardinal); | |||
| begin | |||
| inherited Create(aSender, aEventType); | |||
| inherited Create(aControl, aEventType); | |||
| fScreenRect := aScreenRect; | |||
| fClientWidth := aClientWidth; | |||
| fClientHeight := aClientHeight; | |||
| @@ -325,82 +338,81 @@ end; | |||
| procedure TutlWinControlEventManager.HandlerMouseDown(Sender: TObject; Button: TMouseButton; | |||
| Shift: TShiftState; X, Y: Integer); | |||
| begin | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender, EVENT_MOUSE_DOWN, [ Button ], Point(X, Y))); | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender as TControl, EVENT_MOUSE_DOWN, [Button], Point(X, Y))); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerMouseUp(Sender: TObject; Button: TMouseButton; | |||
| Shift: TShiftState; X, Y: Integer); | |||
| procedure TutlWinControlEventManager.HandlerMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); | |||
| begin | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender, EVENT_MOUSE_UP, [Button], Point(X, Y))); | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender as TControl, EVENT_MOUSE_UP, [Button], Point(X, Y))); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); | |||
| begin | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender, EVENT_MOUSE_MOVE, [], Point(X, Y))); | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender as TControl, EVENT_MOUSE_MOVE, [], Point(X, Y))); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerMouseEnter(Sender: TObject); | |||
| begin | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender, EVENT_MOUSE_ENTER, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender as TControl, EVENT_MOUSE_ENTER, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerMouseLeave(Sender: TObject); | |||
| begin | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender, EVENT_MOUSE_LEAVE, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender as TControl, EVENT_MOUSE_LEAVE, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerClick(Sender: TObject); | |||
| begin | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender, EVENT_MOUSE_CLICK, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender as TControl, EVENT_MOUSE_CLICK, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerDblClick(Sender: TObject); | |||
| begin | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender, EVENT_MOUSE_DBL_CLICK, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); | |||
| DispatchEvent(self, CreateMouseEventArgs(Sender as TControl, EVENT_MOUSE_DBL_CLICK, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerMouseWheel(Sender: TObject; Shift: TShiftState; | |||
| WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); | |||
| begin | |||
| DispatchEvent(self, CreateMouseWheelEventArgs(Sender, WheelDelta, MousePos)); | |||
| DispatchEvent(self, CreateMouseWheelEventArgs(Sender as TControl, WheelDelta, MousePos)); | |||
| Handled := false; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); | |||
| begin | |||
| DispatchEvent(self, CreateKeyEventArgs(Sender, EVENT_KEY_DOWN, Key)); | |||
| DispatchEvent(self, CreateKeyEventArgs(Sender as TControl, EVENT_KEY_DOWN, Key)); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); | |||
| begin | |||
| DispatchEvent(self, CreateKeyEventArgs(Sender, EVENT_KEY_UP, Key)); | |||
| DispatchEvent(self, CreateKeyEventArgs(Sender as TControl, EVENT_KEY_UP, Key)); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerResize(Sender: TObject); | |||
| begin | |||
| DispatchEvent(self, CreateWindowEventArgs(Sender, EVENT_WINDOW_RESIZE)); | |||
| DispatchEvent(self, CreateWindowEventArgs(Sender as TControl, EVENT_WINDOW_RESIZE)); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerActivate(Sender: TObject); | |||
| begin | |||
| DispatchEvent(self, CreateWindowEventArgs(Sender, EVENT_WINDOW_ACTIVATE)); | |||
| DispatchEvent(self, CreateWindowEventArgs(Sender as TControl, EVENT_WINDOW_ACTIVATE)); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlWinControlEventManager.HandlerDeactivate(Sender: TObject); | |||
| begin | |||
| DispatchEvent(self, CreateWindowEventArgs(Sender, EVENT_WINDOW_DEACTIVATE)); | |||
| DispatchEvent(self, CreateWindowEventArgs(Sender as TControl, EVENT_WINDOW_DEACTIVATE)); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -480,53 +492,63 @@ begin | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlWinControlEventManager.CreateMouseEventArgs(aSender: TObject; aType: TutlEventType; | |||
| aButtons: TutlMouseButtons; aClientPos: TPoint): TutlMouseEventArgs; | |||
| function TutlWinControlEventManager.CreateMouseEventArgs( | |||
| aControl: TControl; | |||
| aType: TutlEventType; | |||
| aButtons: TutlMouseButtons; | |||
| aClientPos: TPoint): IutlEventArgs; | |||
| begin | |||
| result := TutlMouseEventArgs.Create( | |||
| (aSender as TControl), | |||
| aControl, | |||
| aType, | |||
| aButtons, | |||
| aClientPos); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlWinControlEventManager.CreateMouseWheelEventArgs(aSender: TObject; aDelta: Integer; | |||
| aClientPos: TPoint): TutlMouseWheelEventArgs; | |||
| function TutlWinControlEventManager.CreateMouseWheelEventArgs( | |||
| aControl: TControl; | |||
| aDelta: Integer; | |||
| aClientPos: TPoint): IutlEventArgs; | |||
| begin | |||
| result := TutlMouseWheelEventArgs.Create( | |||
| (aSender as TControl), | |||
| aControl, | |||
| aDelta, | |||
| aClientPos); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlWinControlEventManager.CreateKeyEventArgs(aSender: TObject; aType: TutlEventType; aKey: Word): TutlKeyEventArgs; | |||
| function TutlWinControlEventManager.CreateKeyEventArgs( | |||
| aControl: TControl; | |||
| aType: TutlEventType; | |||
| aKey: Word): IutlEventArgs; | |||
| begin | |||
| if (aType = EVENT_KEY_DOWN) and fKeyboard.KeyState[aKey and $FF] then | |||
| aType := EVENT_KEY_REPEAT; | |||
| result := TutlKeyEventArgs.Create( | |||
| (aSender as TControl), | |||
| aControl, | |||
| aType, | |||
| VKCodeToCharCode(aKey, fKeyboard.Modifiers), | |||
| aKey); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlWinControlEventManager.CreateWindowEventArgs(aSender: TObject; aType: TutlEventType): TutlWindowEventArgs; | |||
| function TutlWinControlEventManager.CreateWindowEventArgs( | |||
| aControl: TControl; | |||
| aType: TutlEventType): IutlEventArgs; | |||
| var | |||
| p0, p1: TPoint; | |||
| begin | |||
| with TControl(aSender) do begin | |||
| with aControl do begin | |||
| p0 := ClientToScreen(Point(0, 0)); | |||
| p1 := ClientToScreen(Point(Width, Height)); | |||
| end; | |||
| result := TutlWindowEventArgs.Create( | |||
| (aSender as TControl), | |||
| aControl, | |||
| aType, | |||
| Rect(p0.x, p0.y, p1.x, p1.y), | |||
| (aSender as TWinControl).ClientWidth, | |||
| (aSender as TWinControl).ClientHeight); | |||
| (aControl as TWinControl).ClientWidth, | |||
| (aControl as TWinControl).ClientHeight); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -1492,6 +1492,7 @@ end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| destructor TutlCustomMap.Destroy; | |||
| begin | |||
| Clear; | |||
| FreeAndNil(fKeyValuePairCollection); | |||
| FreeAndNil(fKeyCollection); | |||
| fHashSetRef := nil; | |||
| @@ -1510,7 +1511,6 @@ end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| destructor TutlMap.Destroy; | |||
| begin | |||
| Clear; | |||
| inherited Destroy; | |||
| FreeAndNil(fHashSetImpl); | |||
| end; | |||
| @@ -89,17 +89,27 @@ type | |||
| procedure DeleteSection(Name: string); | |||
| function ValueExists(Name: string): boolean; | |||
| function GetInt(Name: string; Default: Int64 = 0): Int64; overload; | |||
| function GetFloat(Name: string; Default: Double = 0): Double; overload; | |||
| function GetString(Name: string; Default: AnsiString = ''): AnsiString; overload; | |||
| function GetStringW(Name: string; Default: UnicodeString = ''): UnicodeString; overload; | |||
| function GetBool(Name: string; Default: Boolean = false): Boolean; overload; | |||
| procedure SetInt(Name: string; Value: Int64); overload; | |||
| procedure SetFloat(Name: string; Value: Double); overload; | |||
| procedure SetString(Name: string; Value: WideString); overload; | |||
| procedure SetString(Name: string; Value: AnsiString); overload; | |||
| procedure SetBool(Name: string; Value: Boolean); overload; | |||
| procedure UnsetValue(Name: string); | |||
| function GetValue (Name: String; Default: Variant): Variant; | |||
| function GetInt (Name: string; Default: Int64 = 0): Int64; overload; | |||
| function GetFloat (Name: string; Default: Double = 0): Double; overload; | |||
| function GetString (Name: string; Default: AnsiString = ''): AnsiString; overload; | |||
| function GetStringW (Name: string; Default: UnicodeString = ''): UnicodeString; overload; | |||
| function GetBool (Name: string; Default: Boolean = false): Boolean; overload; | |||
| function TryGetValue (aName: String; out aValue: Variant): Boolean; | |||
| function TryGetInt (aName: String; out aValue: Int64): Boolean; | |||
| function TryGetFloat (aName: String; out aValue: Double): Boolean; | |||
| function TryGetString (aName: String; out aValue: AnsiString): Boolean; | |||
| function TryGetStringW(aName: String; out aValue: UnicodeString): Boolean; | |||
| function TryGetBool (aName: String; out aValue: Boolean): Boolean; | |||
| procedure SetInt (Name: string; Value: Int64); overload; | |||
| procedure SetFloat (Name: string; Value: Double); overload; | |||
| procedure SetString (Name: string; Value: WideString); overload; | |||
| procedure SetString (Name: string; Value: AnsiString); overload; | |||
| procedure SetBool (Name: string; Value: Boolean); overload; | |||
| end; | |||
| { TutlMCFFile } | |||
| @@ -426,55 +436,107 @@ begin | |||
| Result:= FValues.IndexOf(Name) >= 0; | |||
| end; | |||
| function TutlMCFSection.GetInt(Name: string; Default: Int64): Int64; | |||
| procedure TutlMCFSection.UnsetValue(Name: string); | |||
| var | |||
| i: integer; | |||
| begin | |||
| i:= FValues.IndexOf(Name); | |||
| if i < 0 then | |||
| Result:= Default | |||
| else | |||
| Result:= TutlMCFValue(FValues.Objects[i]).Value; | |||
| if i >= 0 then begin | |||
| FValues.Objects[i].Free; | |||
| FValues.Delete(i); | |||
| end; | |||
| end; | |||
| function TutlMCFSection.GetValue(Name: String; Default: Variant): Variant; | |||
| begin | |||
| if not TryGetValue(Name, result) then | |||
| result := Default; | |||
| end; | |||
| function TutlMCFSection.GetInt(Name: string; Default: Int64): Int64; | |||
| begin | |||
| if not TryGetInt(Name, result) then | |||
| result := Default; | |||
| end; | |||
| function TutlMCFSection.GetFloat(Name: string; Default: Double): Double; | |||
| var | |||
| i: integer; | |||
| begin | |||
| i:= FValues.IndexOf(Name); | |||
| if i < 0 then | |||
| Result:= Default | |||
| else | |||
| Result:= TutlMCFValue(FValues.Objects[i]).Value; | |||
| if not TryGetFloat(Name, result) then | |||
| result := Default; | |||
| end; | |||
| function TutlMCFSection.GetStringW(Name: string; Default: UnicodeString): UnicodeString; | |||
| var | |||
| i: integer; | |||
| begin | |||
| i:= FValues.IndexOf(Name); | |||
| if i < 0 then | |||
| Result:= Default | |||
| else | |||
| Result:= TutlMCFValue(FValues.Objects[i]).Value; | |||
| if not TryGetStringW(Name, result) then | |||
| result := Default; | |||
| end; | |||
| function TutlMCFSection.GetString(Name: string; Default: AnsiString): AnsiString; | |||
| begin | |||
| Result := AnsiString(GetStringW(Name, UnicodeString(Default))); | |||
| if not TryGetString(Name, result) then | |||
| result := Default; | |||
| end; | |||
| function TutlMCFSection.GetBool(Name: string; Default: Boolean): Boolean; | |||
| begin | |||
| if not TryGetBool(Name, result) then | |||
| result := Default; | |||
| end; | |||
| function TutlMCFSection.TryGetValue(aName: String; out aValue: Variant): Boolean; | |||
| var | |||
| i: integer; | |||
| i: Integer; | |||
| begin | |||
| i:= FValues.IndexOf(Name); | |||
| if i < 0 then | |||
| Result:= Default | |||
| else | |||
| Result:= TutlMCFValue(FValues.Objects[i]).Value; | |||
| i := FValues.IndexOf(aName); | |||
| result := (i >= 0); | |||
| if result then | |||
| aValue := TutlMcfValue(FValues.Objects[i]).Value; | |||
| end; | |||
| function TutlMCFSection.TryGetInt(aName: String; out aValue: Int64): Boolean; | |||
| var | |||
| v: Variant; | |||
| begin | |||
| result := TryGetValue(aName, v); | |||
| if result then | |||
| aValue := v; | |||
| end; | |||
| function TutlMCFSection.TryGetFloat(aName: String; out aValue: Double): Boolean; | |||
| var | |||
| v: Variant; | |||
| begin | |||
| result := TryGetValue(aName, v); | |||
| if result then | |||
| aValue := v; | |||
| end; | |||
| function TutlMCFSection.TryGetString(aName: String; out aValue: AnsiString): Boolean; | |||
| var | |||
| v: Variant; | |||
| begin | |||
| result := TryGetValue(aName, v); | |||
| if result then | |||
| aValue := v; | |||
| end; | |||
| function TutlMCFSection.TryGetStringW(aName: String; out aValue: UnicodeString): Boolean; | |||
| var | |||
| v: Variant; | |||
| begin | |||
| result := TryGetValue(aName, v); | |||
| if result then | |||
| aValue := v; | |||
| end; | |||
| function TutlMCFSection.TryGetBool(aName: String; out aValue: Boolean): Boolean; | |||
| var | |||
| v: Variant; | |||
| begin | |||
| result := TryGetValue(aName, v); | |||
| if result then | |||
| aValue := v; | |||
| end; | |||
| procedure TutlMCFSection.AddValueChecked(Name: String; Val: TObject); | |||
| var | |||
| @@ -540,18 +602,6 @@ begin | |||
| TutlMCFValue(FValues.Objects[i]).Value:= Value; | |||
| end; | |||
| procedure TutlMCFSection.UnsetValue(Name: string); | |||
| var | |||
| i: integer; | |||
| begin | |||
| i:= FValues.IndexOf(Name); | |||
| if i >= 0 then begin | |||
| FValues.Objects[i].Free; | |||
| FValues.Delete(i); | |||
| end; | |||
| end; | |||
| procedure TutlMCFSection.LoadData(Data: TStream; LineEnds: TutlMCFLineEndMarkerMode; Depth: Integer); | |||
| var | |||
| reader: TutlStreamReader; | |||
| @@ -307,30 +307,46 @@ end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomList.DoAddItem(const aIndex: Integer; constref aItem: T); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TItemEventArgs.Create(oetAdd, aIndex, aItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TItemEventArgs.Create(oetAdd, aIndex, aItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomList.DoRemoveItem(const aIndex: Integer; constref aItem: T); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TItemEventArgs.Create(oetRemove, aIndex, aItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TItemEventArgs.Create(oetRemove, aIndex, aItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomList.DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TReplaceEventArgs.Create(oetReplace, aIndex, aOldItem, aNewItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TReplaceEventArgs.Create(oetReplace, aIndex, aOldItem, aNewItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomList.DoClear; | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TutlObservableEventArgs.Create(oetClear)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TutlObservableEventArgs.Create(oetClear); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -431,30 +447,46 @@ end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomHashSet.DoAddItem(const aIndex: Integer; constref aItem: T); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TItemEventArgs.Create(oetAdd, aIndex, aItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TItemEventArgs.Create(oetAdd, aIndex, aItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomHashSet.DoRemoveItem(const aIndex: Integer; constref aItem: T); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TItemEventArgs.Create(oetRemove, aIndex, aItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TItemEventArgs.Create(oetRemove, aIndex, aItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomHashSet.DoChangeItem(const aIndex: Integer; constref aOldItem: T; constref aNewItem: T); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TReplaceEventArgs.Create(oetReplace, aIndex, aOldItem, aNewItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TReplaceEventArgs.Create(oetReplace, aIndex, aOldItem, aNewItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomHashSet.DoClear; | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TutlObservableEventArgs.Create(oetClear)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TutlObservableEventArgs.Create(oetClear); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -528,7 +560,8 @@ end; | |||
| procedure TutlObservableCustomMap.TObservableHashSet.Clear; | |||
| begin | |||
| fOwner.DoClear; | |||
| inherited Clear; | |||
| while (Count > 0) do | |||
| Delete(Count - 1); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -576,9 +609,13 @@ procedure TutlObservableCustomMap.DoAddItem( | |||
| const aIndex: Integer; | |||
| constref aKey: TKey; | |||
| constref aItem: TValue); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TItemEventArgs.Create(oetAdd, aIndex, aKey, aItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TItemEventArgs.Create(oetAdd, aIndex, aKey, aItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -586,9 +623,13 @@ procedure TutlObservableCustomMap.DoRemoveItem( | |||
| const aIndex: Integer; | |||
| constref aKey: TKey; | |||
| constref aItem: TValue); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TItemEventArgs.Create(oetRemove, aIndex, aKey, aItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TItemEventArgs.Create(oetRemove, aIndex, aKey, aItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -597,16 +638,24 @@ procedure TutlObservableCustomMap.DoChangeItem( | |||
| constref aKey: TKey; | |||
| constref aOldItem: TValue; | |||
| constref aNewItem: TValue); | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TReplaceEventArgs.Create(oetReplace, aIndex, aKey, aOldItem, aNewItem)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TReplaceEventArgs.Create(oetReplace, aIndex, aKey, aOldItem, aNewItem); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TutlObservableCustomMap.DoClear; | |||
| var | |||
| e: IutlEventArgs; | |||
| begin | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then | |||
| fEventListener.DispatchEvent(self, TutlObservableEventArgs.Create(oetClear)); | |||
| if Assigned(fEventListener) and not fEventListener.IsEmpty then begin | |||
| e := TutlObservableEventArgs.Create(oetClear); | |||
| fEventListener.DispatchEvent(self, e); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -112,15 +112,21 @@ type | |||
| TInterfacedObject, | |||
| specialize IutlLock<T>) | |||
| public type | |||
| ILock = specialize IutlLock<T>; | |||
| private | |||
| fLock: IutlLockable; | |||
| fObject: T; | |||
| public | |||
| function LockedObject: T; inline; | |||
| constructor Create(constref aLock: IutlLockable; constref aObject: T); | |||
| destructor Destroy; override; | |||
| class function CreateLock(constref aLock: IutlLockable; constref aObject: T): ILock; | |||
| end; | |||
| implementation | |||
| @@ -359,5 +365,11 @@ begin | |||
| inherited Destroy; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlLock.CreateLock(constref aLock: IutlLockable; constref aObject: T): ILock; | |||
| begin | |||
| result := TutlLock.Create(aLock, aObject); | |||
| end; | |||
| end. | |||
| @@ -75,6 +75,14 @@ type | |||
| function GetAttribFloat (const aName: DOMString; const aDefault: Double): Double; | |||
| function GetAttribBool (const aName: DOMString; const aDefault: Boolean): Boolean; | |||
| // get value of attribute | |||
| function TryGetAttribString (const aName: DOMString; out aValue: String): Boolean; | |||
| function TryGetAttribStringW (const aName: DOMString; out aValue: WideString): Boolean; | |||
| function TryGetAttribStringU (const aName: DOMString; out aValue: UnicodeString): Boolean; | |||
| function TryGetAttribInt (const aName: DOMString; out aValue: Int64): Boolean; | |||
| function TryGetAttribFloat (const aName: DOMString; out aValue: Double): Boolean; | |||
| function TryGetAttribBool (const aName: DOMString; out aValue: Boolean): Boolean; | |||
| // node operations | |||
| function Nodes (const aName: DOMString): IutlNodeEnumerator; | |||
| function PrependNode (const aName: DOMString): TDOMElement; | |||
| @@ -109,43 +117,51 @@ type | |||
| function GetElement: TDOMElement; | |||
| // set value of current node | |||
| procedure SetString (const aValue: String); overload; | |||
| procedure SetString (const aValue: WideString); overload; | |||
| procedure SetString (const aValue: UnicodeString); overload; | |||
| procedure SetInt (const aValue: Integer); | |||
| procedure SetFloat (const aValue: Double); | |||
| procedure SetBool (const aValue: Boolean); | |||
| procedure SetString (const aValue: String); overload; | |||
| procedure SetString (const aValue: WideString); overload; | |||
| procedure SetString (const aValue: UnicodeString); overload; | |||
| procedure SetInt (const aValue: Integer); | |||
| procedure SetFloat (const aValue: Double); | |||
| procedure SetBool (const aValue: Boolean); | |||
| // get value of current node | |||
| function GetString (const aDefault: String): String; | |||
| function GetStringW (const aDefault: WideString): WideString; | |||
| function GetStringU (const aDefault: UnicodeString): UnicodeString; | |||
| function GetInt (const aDefault: Int64): Int64; | |||
| function GetFloat (const aDefault: Double): Double; | |||
| function GetBool (const aDefault: Boolean): Boolean; | |||
| function GetString (const aDefault: String): String; | |||
| function GetStringW (const aDefault: WideString): WideString; | |||
| function GetStringU (const aDefault: UnicodeString): UnicodeString; | |||
| function GetInt (const aDefault: Int64): Int64; | |||
| function GetFloat (const aDefault: Double): Double; | |||
| function GetBool (const aDefault: Boolean): Boolean; | |||
| // set value of attribute | |||
| procedure SetAttribString (const aName: DOMString; const aValue: String); overload; | |||
| procedure SetAttribString (const aName: DOMString; const aValue: WideString); overload; | |||
| procedure SetAttribString (const aName: DOMString; const aValue: UnicodeString); overload; | |||
| procedure SetAttribInt (const aName: DOMString; const aValue: Integer); | |||
| procedure SetAttribFloat (const aName: DOMString; const aValue: Double); | |||
| procedure SetAttribBool (const aName: DOMString; const aValue: Boolean); | |||
| procedure SetAttribString (const aName: DOMString; const aValue: String); overload; | |||
| procedure SetAttribString (const aName: DOMString; const aValue: WideString); overload; | |||
| procedure SetAttribString (const aName: DOMString; const aValue: UnicodeString); overload; | |||
| procedure SetAttribInt (const aName: DOMString; const aValue: Integer); | |||
| procedure SetAttribFloat (const aName: DOMString; const aValue: Double); | |||
| procedure SetAttribBool (const aName: DOMString; const aValue: Boolean); | |||
| // get value of attribute | |||
| function GetAttribString (const aName: DOMString; const aDefault: String): String; | |||
| function GetAttribStringW (const aName: DOMString; const aDefault: WideString): WideString; | |||
| function GetAttribStringU (const aName: DOMString; const aDefault: UnicodeString): UnicodeString; | |||
| function GetAttribInt (const aName: DOMString; const aDefault: Int64): Int64; | |||
| function GetAttribFloat (const aName: DOMString; const aDefault: Double): Double; | |||
| function GetAttribBool (const aName: DOMString; const aDefault: Boolean): Boolean; | |||
| function GetAttribString (const aName: DOMString; const aDefault: String): String; | |||
| function GetAttribStringW (const aName: DOMString; const aDefault: WideString): WideString; | |||
| function GetAttribStringU (const aName: DOMString; const aDefault: UnicodeString): UnicodeString; | |||
| function GetAttribInt (const aName: DOMString; const aDefault: Int64): Int64; | |||
| function GetAttribFloat (const aName: DOMString; const aDefault: Double): Double; | |||
| function GetAttribBool (const aName: DOMString; const aDefault: Boolean): Boolean; | |||
| // get value of attribute | |||
| function TryGetAttribString (const aName: DOMString; out aValue: String): Boolean; | |||
| function TryGetAttribStringW(const aName: DOMString; out aValue: WideString): Boolean; | |||
| function TryGetAttribStringU(const aName: DOMString; out aValue: UnicodeString): Boolean; | |||
| function TryGetAttribInt (const aName: DOMString; out aValue: Int64): Boolean; | |||
| function TryGetAttribFloat (const aName: DOMString; out aValue: Double): Boolean; | |||
| function TryGetAttribBool (const aName: DOMString; out aValue: Boolean): Boolean; | |||
| // node operations | |||
| function Nodes (const aName: DOMString): IutlNodeEnumerator; | |||
| function PrependNode (const aName: DOMString): TDOMElement; | |||
| function AppendNode (const aName: DOMString): TDOMElement; | |||
| procedure PrependText (const aText: DOMString); | |||
| procedure AppendText (const aText: DOMString); | |||
| function Nodes (const aName: DOMString): IutlNodeEnumerator; | |||
| function PrependNode (const aName: DOMString): TDOMElement; | |||
| function AppendNode (const aName: DOMString): TDOMElement; | |||
| procedure PrependText (const aText: DOMString); | |||
| procedure AppendText (const aText: DOMString); | |||
| private | |||
| {%H-}constructor Create; reintroduce; | |||
| @@ -155,25 +171,32 @@ type | |||
| class function Create(const aElement: TDOMElement): IutlXmlHelper; | |||
| public | |||
| class function SetString (const aNode: TDOMNode; const aValue: String): TDOMNode; overload; | |||
| class function SetString (const aNode: TDOMNode; const aValue: WideString): TDOMNode; overload; | |||
| class function SetString (const aNode: TDOMNode; const aValue: UnicodeString): TDOMNode; overload; | |||
| class function SetInt (const aNode: TDOMNode; const aValue: Integer): TDOMNode; | |||
| class function SetFloat (const aNode: TDOMNode; const aValue: Double): TDOMNode; | |||
| class function SetBool (const aNode: TDOMNode; const aValue: Boolean): TDOMNode; | |||
| class function GetString (const aNode: TDOMNode; const aDefault: String): String; | |||
| class function GetStringW (const aNode: TDOMNode; const aDefault: WideString): WideString; | |||
| class function GetStringU (const aNode: TDOMNode; const aDefault: UnicodeString): UnicodeString; | |||
| class function GetInt (const aNode: TDOMNode; const aDefault: Int64): Int64; | |||
| class function GetFloat (const aNode: TDOMNode; const aDefault: Double): Double; | |||
| class function GetBool (const aNode: TDOMNode; const aDefault: Boolean): Boolean; | |||
| class function Nodes (const aElement: TDOMElement; const aName: DOMString = ''): IutlNodeEnumerator; | |||
| class function PrependNode (const aElement: TDOMElement; const aName: DOMString): TDOMElement; | |||
| class function AppendNode (const aElement: TDOMElement; const aName: DOMString): TDOMElement; | |||
| class procedure PrependText (const aElement: TDOMElement; const aText: DOMString); | |||
| class procedure AppendText (const aElement: TDOMElement; const aText: DOMString); | |||
| class function SetString (const aNode: TDOMNode; const aValue: String): TDOMNode; overload; | |||
| class function SetString (const aNode: TDOMNode; const aValue: WideString): TDOMNode; overload; | |||
| class function SetString (const aNode: TDOMNode; const aValue: UnicodeString): TDOMNode; overload; | |||
| class function SetInt (const aNode: TDOMNode; const aValue: Integer): TDOMNode; | |||
| class function SetFloat (const aNode: TDOMNode; const aValue: Double): TDOMNode; | |||
| class function SetBool (const aNode: TDOMNode; const aValue: Boolean): TDOMNode; | |||
| class function GetString (const aNode: TDOMNode; const aDefault: String): String; | |||
| class function GetStringW (const aNode: TDOMNode; const aDefault: WideString): WideString; | |||
| class function GetStringU (const aNode: TDOMNode; const aDefault: UnicodeString): UnicodeString; | |||
| class function GetInt (const aNode: TDOMNode; const aDefault: Int64): Int64; | |||
| class function GetFloat (const aNode: TDOMNode; const aDefault: Double): Double; | |||
| class function GetBool (const aNode: TDOMNode; const aDefault: Boolean): Boolean; | |||
| class function TryGetString (const aNode: TDOMNode; out aValue: String): Boolean; | |||
| class function TryGetStringW(const aNode: TDOMNode; out aValue: WideString): Boolean; | |||
| class function TryGetStringU(const aNode: TDOMNode; out aValue: UnicodeString): Boolean; | |||
| class function TryGetInt (const aNode: TDOMNode; out aValue: Int64): Boolean; | |||
| class function TryGetFloat (const aNode: TDOMNode; out aValue: Double): Boolean; | |||
| class function TryGetBool (const aNode: TDOMNode; out aValue: Boolean): Boolean; | |||
| class function Nodes (const aElement: TDOMElement; const aName: DOMString = ''): IutlNodeEnumerator; | |||
| class function PrependNode (const aElement: TDOMElement; const aName: DOMString): TDOMElement; | |||
| class function AppendNode (const aElement: TDOMElement; const aName: DOMString): TDOMElement; | |||
| class procedure PrependText (const aElement: TDOMElement; const aText: DOMString); | |||
| class procedure AppendText (const aElement: TDOMElement; const aText: DOMString); | |||
| end; | |||
| implementation | |||
| @@ -382,6 +405,42 @@ begin | |||
| result := TutlXmlHelper.GetBool(fElement.Attributes.GetNamedItem(aName), aDefault); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlXmlHelper.TryGetAttribString(const aName: DOMString; out aValue: String): Boolean; | |||
| begin | |||
| result := TutlXmlHelper.TryGetString(fElement.Attributes.GetNamedItem(aName), aValue); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlXmlHelper.TryGetAttribStringW(const aName: DOMString; out aValue: WideString): Boolean; | |||
| begin | |||
| result := TutlXmlHelper.TryGetStringW(fElement.Attributes.GetNamedItem(aName), aValue); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlXmlHelper.TryGetAttribStringU(const aName: DOMString; out aValue: UnicodeString): Boolean; | |||
| begin | |||
| result := TutlXmlHelper.TryGetStringU(fElement.Attributes.GetNamedItem(aName), aValue); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlXmlHelper.TryGetAttribInt(const aName: DOMString; out aValue: Int64): Boolean; | |||
| begin | |||
| result := TutlXmlHelper.TryGetInt(fElement.Attributes.GetNamedItem(aName), aValue); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlXmlHelper.TryGetAttribFloat(const aName: DOMString; out aValue: Double): Boolean; | |||
| begin | |||
| result := TutlXmlHelper.TryGetFloat(fElement.Attributes.GetNamedItem(aName), aValue); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlXmlHelper.TryGetAttribBool(const aName: DOMString; out aValue: Boolean): Boolean; | |||
| begin | |||
| result := TutlXmlHelper.TryGetBool(fElement.Attributes.GetNamedItem(aName), aValue); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TutlXmlHelper.Nodes(const aName: DOMString): IutlNodeEnumerator; | |||
| begin | |||
| @@ -486,73 +545,104 @@ end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.GetString(const aNode: TDOMNode; const aDefault: String): String; | |||
| begin | |||
| if not Assigned(aNode) | |||
| or ( not aNode.HasChildNodes | |||
| and not (aNode is TDOMText)) | |||
| then result := aDefault | |||
| else result := String(aNode.TextContent); | |||
| if not TryGetString(aNode, result) then | |||
| result := aDefault; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.GetStringW(const aNode: TDOMNode; const aDefault: WideString): WideString; | |||
| begin | |||
| if not Assigned(aNode) | |||
| or ( not aNode.HasChildNodes | |||
| and not (aNode is TDOMText)) | |||
| then result := aDefault | |||
| else result := WideString(aNode.TextContent); | |||
| if not TryGetStringW(aNode, result) then | |||
| result := aDefault; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.GetStringU(const aNode: TDOMNode; const aDefault: UnicodeString): UnicodeString; | |||
| begin | |||
| if not Assigned(aNode) | |||
| or ( not aNode.HasChildNodes | |||
| and not (aNode is TDOMText)) | |||
| then result := aDefault | |||
| else result := UnicodeString(aNode.TextContent); | |||
| if not TryGetStringU(aNode, result) then | |||
| result := aDefault; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.GetInt(const aNode: TDOMNode; const aDefault: Int64): Int64; | |||
| begin | |||
| if not Assigned(aNode) | |||
| or ( not aNode.HasChildNodes | |||
| and not (aNode is TDOMText)) | |||
| or not TryStrToInt64(String(aNode.TextContent), result) then | |||
| if not TryGetInt(aNode, result) then | |||
| result := aDefault; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.GetFloat(const aNode: TDOMNode; const aDefault: Double): Double; | |||
| begin | |||
| if not Assigned(aNode) | |||
| or ( not aNode.HasChildNodes | |||
| and not (aNode is TDOMText)) | |||
| or not TryStrToFloat(String(aNode.TextContent), result) then | |||
| if not TryGetFloat(aNode, result) then | |||
| result := aDefault; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.GetBool(const aNode: TDOMNode; const aDefault: Boolean): Boolean; | |||
| begin | |||
| if not TryGetBool(aNode, result) then | |||
| result := aDefault; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.TryGetString(const aNode: TDOMNode; out aValue: String): Boolean; | |||
| begin | |||
| result := Assigned(aNode) | |||
| and ( aNode.HasChildNodes | |||
| or (aNode is TDOMText)); | |||
| if result then | |||
| aValue := String(aNode.TextContent); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.TryGetStringW(const aNode: TDOMNode; out aValue: WideString): Boolean; | |||
| begin | |||
| result := Assigned(aNode) | |||
| and ( aNode.HasChildNodes | |||
| or (aNode is TDOMText)); | |||
| if result then | |||
| aValue := WideString(aNode.TextContent); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.TryGetStringU(const aNode: TDOMNode; out aValue: UnicodeString): Boolean; | |||
| begin | |||
| result := Assigned(aNode) | |||
| and ( aNode.HasChildNodes | |||
| or (aNode is TDOMText)); | |||
| if result then | |||
| aValue := UnicodeString(aNode.TextContent); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.TryGetInt(const aNode: TDOMNode; out aValue: Int64): Boolean; | |||
| begin | |||
| result := Assigned(aNode) | |||
| and ( aNode.HasChildNodes | |||
| or (aNode is TDOMText)) | |||
| and TryStrToInt64(String(aNode.TextContent), aValue); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.TryGetFloat(const aNode: TDOMNode; out aValue: Double): Boolean; | |||
| begin | |||
| result := Assigned(aNode) | |||
| and ( aNode.HasChildNodes | |||
| or (aNode is TDOMText)) | |||
| and TryStrToFloat(String(aNode.TextContent), aValue); | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| class function TutlXmlHelper.TryGetBool(const aNode: TDOMNode; out aValue: Boolean): Boolean; | |||
| var | |||
| s: String; | |||
| begin | |||
| if not Assigned(aNode) | |||
| or ( not aNode.HasChildNodes | |||
| and not (aNode is TDOMText)) | |||
| then | |||
| begin | |||
| result := aDefault; | |||
| exit; | |||
| result := TryGetString(aNode, s); | |||
| if result then begin | |||
| if (s = 'true') or (s = 't') or (s = '1') | |||
| then aValue := true | |||
| else aValue := false; | |||
| end; | |||
| s := LowerCase(String(aNode.TextContent)); | |||
| if (s = 'true') or (s = 't') or (s = '1') then | |||
| result := true | |||
| else if (s = 'false') or (s = 'f') or (s = '0') then | |||
| result := false | |||
| else | |||
| result := aDefault; | |||
| end; | |||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||