| [459] | 1 | unit ORClasses; | 
|---|
|  | 2 |  | 
|---|
|  | 3 | interface | 
|---|
|  | 4 |  | 
|---|
|  | 5 | uses | 
|---|
|  | 6 | SysUtils, Classes, Controls, ComCtrls, ExtCtrls, StdCtrls, Forms, ORFn; | 
|---|
|  | 7 |  | 
|---|
|  | 8 | type | 
|---|
|  | 9 | TNotifyProc = procedure(Sender: TObject); | 
|---|
|  | 10 |  | 
|---|
|  | 11 | TORNotifyList = class(TObject) | 
|---|
|  | 12 | private | 
|---|
|  | 13 | FCode: TList; | 
|---|
|  | 14 | FData: TList; | 
|---|
|  | 15 | protected | 
|---|
|  | 16 | function GetItems(index: integer): TNotifyEvent; | 
|---|
|  | 17 | procedure SetItems(index: integer; const Value: TNotifyEvent); | 
|---|
|  | 18 | function GetIsProc(index: integer): boolean; | 
|---|
|  | 19 | function GetProcs(index: integer): TNotifyProc; | 
|---|
|  | 20 | procedure SetProcs(index: integer; const Value: TNotifyProc); | 
|---|
|  | 21 | public | 
|---|
|  | 22 | constructor Create; | 
|---|
|  | 23 | destructor Destroy; override; | 
|---|
|  | 24 | function IndexOf(const NotifyProc: TNotifyEvent): integer; overload; | 
|---|
|  | 25 | function IndexOf(const NotifyProc: TNotifyProc): integer; overload; | 
|---|
|  | 26 | procedure Add(const NotifyProc: TNotifyEvent); overload; | 
|---|
|  | 27 | procedure Add(const NotifyProc: TNotifyProc); overload; | 
|---|
|  | 28 | procedure Clear; | 
|---|
|  | 29 | function Count: integer; | 
|---|
|  | 30 | procedure Delete(index: integer); | 
|---|
|  | 31 | procedure Remove(const NotifyProc: TNotifyEvent); overload; | 
|---|
|  | 32 | procedure Remove(const NotifyProc: TNotifyProc); overload; | 
|---|
|  | 33 | procedure Notify(Sender: TObject); | 
|---|
|  | 34 | property Items[index: integer]: TNotifyEvent read GetItems write SetItems; default; | 
|---|
|  | 35 | property Procs[index: integer]: TNotifyProc read GetProcs write SetProcs; | 
|---|
|  | 36 | property IsProc[index: integer]: boolean read GetIsProc; | 
|---|
|  | 37 | end; | 
|---|
|  | 38 |  | 
|---|
|  | 39 | TCanNotifyEvent = procedure(Sender: TObject; var CanNotify: boolean) of object; | 
|---|
|  | 40 |  | 
|---|
|  | 41 | IORNotifier = interface(IUnknown) | 
|---|
|  | 42 | function GetOnNotify: TCanNotifyEvent; | 
|---|
|  | 43 | procedure SetOnNotify(Value: TCanNotifyEvent); | 
|---|
|  | 44 | procedure BeginUpdate; | 
|---|
|  | 45 | procedure EndUpdate(DoNotify: boolean = FALSE); | 
|---|
|  | 46 | procedure NotifyWhenChanged(Event: TNotifyEvent); overload; | 
|---|
|  | 47 | procedure NotifyWhenChanged(Event: TNotifyProc); overload; | 
|---|
|  | 48 | procedure RemoveNotify(Event: TNotifyEvent); overload; | 
|---|
|  | 49 | procedure RemoveNotify(Event: TNotifyProc); overload; | 
|---|
|  | 50 | procedure Notify; overload; | 
|---|
|  | 51 | procedure Notify(Sender: TObject); overload; | 
|---|
|  | 52 | function NotifyMethod: TNotifyEvent; | 
|---|
|  | 53 | property OnNotify: TCanNotifyEvent read GetOnNotify Write SetOnNotify; | 
|---|
|  | 54 | end; | 
|---|
|  | 55 |  | 
|---|
|  | 56 | TORNotifier = class(TInterfacedObject, IORNotifier) | 
|---|
|  | 57 | private | 
|---|
|  | 58 | FNotifyList: TORNotifyList; | 
|---|
|  | 59 | FUpdateCount: integer; | 
|---|
|  | 60 | FOwner: TObject; | 
|---|
|  | 61 | FOnNotify: TCanNotifyEvent; | 
|---|
|  | 62 | protected | 
|---|
|  | 63 | procedure DoNotify(Sender: TObject); | 
|---|
|  | 64 | public | 
|---|
|  | 65 | constructor Create(Owner: TObject = nil; SingleInstance: boolean = FALSE); | 
|---|
|  | 66 | destructor Destroy; override; | 
|---|
|  | 67 | function GetOnNotify: TCanNotifyEvent; | 
|---|
|  | 68 | procedure SetOnNotify(Value: TCanNotifyEvent); | 
|---|
|  | 69 | procedure BeginUpdate; | 
|---|
|  | 70 | procedure EndUpdate(DoNotify: boolean = FALSE); | 
|---|
|  | 71 | procedure NotifyWhenChanged(Event: TNotifyEvent); overload; | 
|---|
|  | 72 | procedure NotifyWhenChanged(Event: TNotifyProc); overload; | 
|---|
|  | 73 | procedure RemoveNotify(Event: TNotifyEvent); overload; | 
|---|
|  | 74 | procedure RemoveNotify(Event: TNotifyProc); overload; | 
|---|
|  | 75 | procedure Notify; overload; | 
|---|
|  | 76 | procedure Notify(Sender: TObject); overload; | 
|---|
|  | 77 | function NotifyMethod: TNotifyEvent; | 
|---|
|  | 78 | property OnNotify: TCanNotifyEvent read GetOnNotify Write SetOnNotify; | 
|---|
|  | 79 | end; | 
|---|
|  | 80 |  | 
|---|
|  | 81 | TORStringList = class(TStringList, IORNotifier) | 
|---|
|  | 82 | private | 
|---|
|  | 83 | FNotifier: IORNotifier; | 
|---|
|  | 84 | protected | 
|---|
|  | 85 | function GetNotifier: IORNotifier; | 
|---|
|  | 86 | procedure Changed; override; | 
|---|
|  | 87 | public | 
|---|
|  | 88 | destructor Destroy; override; | 
|---|
|  | 89 | procedure KillObjects; | 
|---|
|  | 90 | // IndexOfPiece starts looking at StartIdx+1 | 
|---|
|  | 91 | function CaseInsensitiveIndexOfPiece(Value: string; Delim: Char = '^'; | 
|---|
|  | 92 | PieceNum: integer = 1; | 
|---|
|  | 93 | StartIdx: integer = -1): integer; | 
|---|
|  | 94 | function IndexOfPiece(Value: string; Delim: Char = '^'; | 
|---|
|  | 95 | PieceNum: integer = 1; | 
|---|
|  | 96 | StartIdx: integer = -1): integer; | 
|---|
|  | 97 | function IndexOfPieces(const Values: array of string; const Delim: Char; | 
|---|
|  | 98 | const Pieces: array of integer; | 
|---|
|  | 99 | StartIdx: integer = -1): integer; overload; | 
|---|
|  | 100 | function IndexOfPieces(const Values: array of string): integer; overload; | 
|---|
|  | 101 | function IndexOfPieces(const Values: array of string; StartIdx: integer): integer; overload; | 
|---|
|  | 102 | function PiecesEqual(const Index: integer; | 
|---|
|  | 103 | const Values: array of string): boolean; overload; | 
|---|
|  | 104 | function PiecesEqual(const Index: integer; | 
|---|
|  | 105 | const Values: array of string; | 
|---|
|  | 106 | const Pieces: array of integer): boolean; overload; | 
|---|
|  | 107 | function PiecesEqual(const Index: integer; | 
|---|
|  | 108 | const Values: array of string; | 
|---|
|  | 109 | const Pieces: array of integer; | 
|---|
|  | 110 | const Delim: Char): boolean; overload; | 
|---|
|  | 111 | procedure SetStrPiece(Index, PieceNum: integer; Delim: Char; const NewValue: string); overload; | 
|---|
|  | 112 | procedure SetStrPiece(Index, PieceNum: integer; const NewValue: string); overload; | 
|---|
|  | 113 | procedure SortByPiece(PieceNum: integer; Delim: Char = '^'); | 
|---|
|  | 114 | procedure SortByPieces(Pieces: array of integer; Delim: Char = '^'); | 
|---|
|  | 115 | procedure RemoveDuplicates(CaseSensitive: boolean = TRUE); | 
|---|
|  | 116 | property Notifier: IORNotifier read GetNotifier implements IORNotifier; | 
|---|
|  | 117 | end; | 
|---|
|  | 118 |  | 
|---|
|  | 119 | { Do NOT add ANTHING to the ORExposed Classes except to change the scope | 
|---|
|  | 120 | of a property.  If you do, existing code could generate Access Violations } | 
|---|
|  | 121 | TORExposedCustomEdit = class(TCustomEdit) | 
|---|
|  | 122 | public | 
|---|
|  | 123 | property ReadOnly; | 
|---|
|  | 124 | end; | 
|---|
|  | 125 |  | 
|---|
|  | 126 | TORExposedAnimate = class(TAnimate) | 
|---|
|  | 127 | public | 
|---|
|  | 128 | property OnMouseUp; | 
|---|
|  | 129 | property OnMouseDown; | 
|---|
|  | 130 | end; | 
|---|
|  | 131 |  | 
|---|
|  | 132 | TORExposedControl = class(TControl) | 
|---|
|  | 133 | public | 
|---|
|  | 134 | property Font; | 
|---|
|  | 135 | property Text; | 
|---|
|  | 136 | end; | 
|---|
|  | 137 |  | 
|---|
|  | 138 | { AddToNotifyWhenCreated allows you to add an event handler before the object that | 
|---|
|  | 139 | calls that event handler is created.  This only works when there is only one | 
|---|
|  | 140 | instance of a given object created (like TPatient or TEncounter).  For an object | 
|---|
|  | 141 | to make use of this feature, it must call ObjectCreated in the constructor, | 
|---|
|  | 142 | which will return the TORNotifyList that was created for that object. } | 
|---|
|  | 143 | procedure AddToNotifyWhenCreated(ProcToAdd: TNotifyEvent; CreatedClass: TClass); overload; | 
|---|
|  | 144 | procedure AddToNotifyWhenCreated(ProcToAdd: TNotifyProc; CreatedClass: TClass); overload; | 
|---|
|  | 145 | procedure ObjectCreated(CreatedClass: TClass; var NotifyList: TORNotifyList); | 
|---|
|  | 146 |  | 
|---|
|  | 147 | type | 
|---|
|  | 148 | TORInterfaceList = class(TList) | 
|---|
|  | 149 | private | 
|---|
|  | 150 | function GetItem(Index: Integer): IUnknown; | 
|---|
|  | 151 | procedure SetItem(Index: Integer; const Value: IUnknown); | 
|---|
|  | 152 | protected | 
|---|
|  | 153 | procedure Notify(Ptr: Pointer; Action: TListNotification); override; | 
|---|
|  | 154 | public | 
|---|
|  | 155 | function Add(Item: IUnknown): Integer; | 
|---|
|  | 156 | function Extract(Item: IUnknown): IUnknown; | 
|---|
|  | 157 | function First: IUnknown; | 
|---|
|  | 158 | function IndexOf(Item: IUnknown): Integer; | 
|---|
|  | 159 | procedure Insert(Index: Integer; Item: IUnknown); | 
|---|
|  | 160 | function Last: IUnknown; | 
|---|
|  | 161 | function Remove(Item: IUnknown): Integer; | 
|---|
|  | 162 | property Items[Index: Integer]: IUnknown read GetItem write SetItem; default; | 
|---|
|  | 163 | end; | 
|---|
|  | 164 |  | 
|---|
|  | 165 | implementation | 
|---|
|  | 166 |  | 
|---|
|  | 167 | var | 
|---|
|  | 168 | NotifyLists: TStringList = nil; | 
|---|
|  | 169 |  | 
|---|
|  | 170 | function IndexOfClass(CreatedClass: TClass): integer; | 
|---|
|  | 171 | begin | 
|---|
|  | 172 | if(not assigned(NotifyLists)) then | 
|---|
|  | 173 | NotifyLists := TStringList.Create; | 
|---|
|  | 174 | Result := NotifyLists.IndexOf(CreatedClass.ClassName); | 
|---|
|  | 175 | if(Result < 0) then | 
|---|
|  | 176 | Result := NotifyLists.AddObject(CreatedClass.ClassName, TORNotifyList.Create); | 
|---|
|  | 177 | end; | 
|---|
|  | 178 |  | 
|---|
|  | 179 | procedure AddToNotifyWhenCreated(ProcToAdd: TNotifyEvent; CreatedClass: TClass); overload; | 
|---|
|  | 180 | var | 
|---|
|  | 181 | idx: integer; | 
|---|
|  | 182 |  | 
|---|
|  | 183 | begin | 
|---|
|  | 184 | idx := IndexOfClass(CreatedClass); | 
|---|
|  | 185 | TORNotifyList(NotifyLists.Objects[idx]).Add(ProcToAdd); | 
|---|
|  | 186 | end; | 
|---|
|  | 187 |  | 
|---|
|  | 188 | procedure AddToNotifyWhenCreated(ProcToAdd: TNotifyProc; CreatedClass: TClass); overload; | 
|---|
|  | 189 | var | 
|---|
|  | 190 | idx: integer; | 
|---|
|  | 191 |  | 
|---|
|  | 192 | begin | 
|---|
|  | 193 | idx := IndexOfClass(CreatedClass); | 
|---|
|  | 194 | TORNotifyList(NotifyLists.Objects[idx]).Add(ProcToAdd); | 
|---|
|  | 195 | end; | 
|---|
|  | 196 |  | 
|---|
|  | 197 | procedure ObjectCreated(CreatedClass: TClass; var NotifyList: TORNotifyList); | 
|---|
|  | 198 | var | 
|---|
|  | 199 | idx: integer; | 
|---|
|  | 200 |  | 
|---|
|  | 201 | begin | 
|---|
|  | 202 | if(assigned(NotifyLists)) then | 
|---|
|  | 203 | begin | 
|---|
|  | 204 | idx := IndexOfClass(CreatedClass); | 
|---|
|  | 205 | if(idx < 0) then | 
|---|
|  | 206 | NotifyList := nil | 
|---|
|  | 207 | else | 
|---|
|  | 208 | begin | 
|---|
|  | 209 | NotifyList := (NotifyLists.Objects[idx] as TORNotifyList); | 
|---|
|  | 210 | NotifyLists.Delete(idx); | 
|---|
|  | 211 | if(NotifyLists.Count <= 0) then | 
|---|
|  | 212 | KillObj(@NotifyLists); | 
|---|
|  | 213 | end; | 
|---|
|  | 214 | end; | 
|---|
|  | 215 | end; | 
|---|
|  | 216 |  | 
|---|
|  | 217 | { TORNotifyList } | 
|---|
|  | 218 |  | 
|---|
|  | 219 | constructor TORNotifyList.Create; | 
|---|
|  | 220 | begin | 
|---|
|  | 221 | inherited; | 
|---|
|  | 222 | FCode := TList.Create; | 
|---|
|  | 223 | FData := TList.Create; | 
|---|
|  | 224 | end; | 
|---|
|  | 225 |  | 
|---|
|  | 226 | destructor TORNotifyList.Destroy; | 
|---|
|  | 227 | begin | 
|---|
|  | 228 | KillObj(@FCode); | 
|---|
|  | 229 | KillObj(@FData); | 
|---|
|  | 230 | inherited | 
|---|
|  | 231 | end; | 
|---|
|  | 232 |  | 
|---|
|  | 233 | function TORNotifyList.IndexOf(const NotifyProc: TNotifyEvent): integer; | 
|---|
|  | 234 | var | 
|---|
|  | 235 | m: TMethod; | 
|---|
|  | 236 |  | 
|---|
|  | 237 | begin | 
|---|
|  | 238 | if(assigned(NotifyProc) and (FCode.Count > 0)) then | 
|---|
|  | 239 | begin | 
|---|
|  | 240 | m := TMethod(NotifyProc); | 
|---|
|  | 241 | Result := 0; | 
|---|
|  | 242 | while((Result < FCode.Count) and ((FCode[Result] <> m.Code) or | 
|---|
|  | 243 | (FData[Result] <> m.Data))) do inc(Result); | 
|---|
|  | 244 | if Result >= FCode.Count then Result := -1; | 
|---|
|  | 245 | end | 
|---|
|  | 246 | else | 
|---|
|  | 247 | Result := -1; | 
|---|
|  | 248 | end; | 
|---|
|  | 249 |  | 
|---|
|  | 250 | procedure TORNotifyList.Add(const NotifyProc: TNotifyEvent); | 
|---|
|  | 251 | var | 
|---|
|  | 252 | m: TMethod; | 
|---|
|  | 253 |  | 
|---|
|  | 254 | begin | 
|---|
|  | 255 | if(assigned(NotifyProc) and (IndexOf(NotifyProc) < 0)) then | 
|---|
|  | 256 | begin | 
|---|
|  | 257 | m := TMethod(NotifyProc); | 
|---|
|  | 258 | FCode.Add(m.Code); | 
|---|
|  | 259 | FData.Add(m.Data); | 
|---|
|  | 260 | end; | 
|---|
|  | 261 | end; | 
|---|
|  | 262 |  | 
|---|
|  | 263 | procedure TORNotifyList.Remove(const NotifyProc: TNotifyEvent); | 
|---|
|  | 264 | var | 
|---|
|  | 265 | idx: integer; | 
|---|
|  | 266 |  | 
|---|
|  | 267 | begin | 
|---|
|  | 268 | idx := IndexOf(NotifyProc); | 
|---|
|  | 269 | if(idx >= 0) then | 
|---|
|  | 270 | begin | 
|---|
|  | 271 | FCode.Delete(idx); | 
|---|
|  | 272 | FData.Delete(idx); | 
|---|
|  | 273 | end; | 
|---|
|  | 274 | end; | 
|---|
|  | 275 |  | 
|---|
|  | 276 | function TORNotifyList.GetItems(index: integer): TNotifyEvent; | 
|---|
|  | 277 | begin | 
|---|
|  | 278 | TMethod(Result).Code := FCode[index]; | 
|---|
|  | 279 | TMethod(Result).Data := FData[index]; | 
|---|
|  | 280 | end; | 
|---|
|  | 281 |  | 
|---|
|  | 282 | procedure TORNotifyList.SetItems(index: integer; const Value: TNotifyEvent); | 
|---|
|  | 283 | begin | 
|---|
|  | 284 | FCode[index] := TMethod(Value).Code; | 
|---|
|  | 285 | FData[index] := TMethod(Value).Data; | 
|---|
|  | 286 | end; | 
|---|
|  | 287 |  | 
|---|
|  | 288 | procedure TORNotifyList.Notify(Sender: TObject); | 
|---|
|  | 289 | var | 
|---|
|  | 290 | i: integer; | 
|---|
|  | 291 | evnt: TNotifyEvent; | 
|---|
|  | 292 | proc: TNotifyProc; | 
|---|
|  | 293 |  | 
|---|
|  | 294 | begin | 
|---|
|  | 295 | for i := 0 to FCode.Count-1 do | 
|---|
|  | 296 | begin | 
|---|
|  | 297 | if(FData[i] = nil) then | 
|---|
|  | 298 | begin | 
|---|
|  | 299 | proc := FCode[i]; | 
|---|
|  | 300 | if(assigned(proc)) then proc(Sender); | 
|---|
|  | 301 | end | 
|---|
|  | 302 | else | 
|---|
|  | 303 | begin | 
|---|
|  | 304 | TMethod(evnt).Code := FCode[i]; | 
|---|
|  | 305 | TMethod(evnt).Data := FData[i]; | 
|---|
|  | 306 | if(assigned(evnt)) then evnt(Sender); | 
|---|
|  | 307 | end; | 
|---|
|  | 308 | end; | 
|---|
|  | 309 | end; | 
|---|
|  | 310 |  | 
|---|
|  | 311 | procedure TORNotifyList.Clear; | 
|---|
|  | 312 | begin | 
|---|
|  | 313 | FCode.Clear; | 
|---|
|  | 314 | FData.Clear; | 
|---|
|  | 315 | end; | 
|---|
|  | 316 |  | 
|---|
|  | 317 | function TORNotifyList.Count: integer; | 
|---|
|  | 318 | begin | 
|---|
|  | 319 | Result := FCode.Count; | 
|---|
|  | 320 | end; | 
|---|
|  | 321 |  | 
|---|
|  | 322 | procedure TORNotifyList.Delete(index: integer); | 
|---|
|  | 323 | begin | 
|---|
|  | 324 | FCode.Delete(index); | 
|---|
|  | 325 | FData.Delete(index); | 
|---|
|  | 326 | end; | 
|---|
|  | 327 |  | 
|---|
|  | 328 | procedure TORNotifyList.Add(const NotifyProc: TNotifyProc); | 
|---|
|  | 329 | begin | 
|---|
|  | 330 | if(assigned(NotifyProc) and (IndexOf(NotifyProc) < 0)) then | 
|---|
|  | 331 | begin | 
|---|
|  | 332 | FCode.Add(@NotifyProc); | 
|---|
|  | 333 | FData.Add(nil); | 
|---|
|  | 334 | end; | 
|---|
|  | 335 | end; | 
|---|
|  | 336 |  | 
|---|
|  | 337 | function TORNotifyList.IndexOf(const NotifyProc: TNotifyProc): integer; | 
|---|
|  | 338 | var | 
|---|
|  | 339 | prt: ^TNotifyProc; | 
|---|
|  | 340 |  | 
|---|
|  | 341 | begin | 
|---|
|  | 342 | prt := @NotifyProc; | 
|---|
|  | 343 | if(assigned(NotifyProc) and (FCode.Count > 0)) then | 
|---|
|  | 344 | begin | 
|---|
|  | 345 | Result := 0; | 
|---|
|  | 346 | while((Result < FCode.Count) and ((FCode[Result] <> prt) or | 
|---|
|  | 347 | (FData[Result] <> nil))) do inc(Result); | 
|---|
|  | 348 | if Result >= FCode.Count then Result := -1; | 
|---|
|  | 349 | end | 
|---|
|  | 350 | else | 
|---|
|  | 351 | Result := -1; | 
|---|
|  | 352 | end; | 
|---|
|  | 353 |  | 
|---|
|  | 354 | procedure TORNotifyList.Remove(const NotifyProc: TNotifyProc); | 
|---|
|  | 355 | var | 
|---|
|  | 356 | idx: integer; | 
|---|
|  | 357 |  | 
|---|
|  | 358 | begin | 
|---|
|  | 359 | idx := IndexOf(NotifyProc); | 
|---|
|  | 360 | if(idx >= 0) then | 
|---|
|  | 361 | begin | 
|---|
|  | 362 | FCode.Delete(idx); | 
|---|
|  | 363 | FData.Delete(idx); | 
|---|
|  | 364 | end; | 
|---|
|  | 365 | end; | 
|---|
|  | 366 |  | 
|---|
|  | 367 | function TORNotifyList.GetIsProc(index: integer): boolean; | 
|---|
|  | 368 | begin | 
|---|
|  | 369 | Result := (not assigned(FData[index])); | 
|---|
|  | 370 | end; | 
|---|
|  | 371 |  | 
|---|
|  | 372 | function TORNotifyList.GetProcs(index: integer): TNotifyProc; | 
|---|
|  | 373 | begin | 
|---|
|  | 374 | Result := FCode[index]; | 
|---|
|  | 375 | end; | 
|---|
|  | 376 |  | 
|---|
|  | 377 | procedure TORNotifyList.SetProcs(index: integer; const Value: TNotifyProc); | 
|---|
|  | 378 | begin | 
|---|
|  | 379 | FCode[index] := @Value; | 
|---|
|  | 380 | FData[index] := nil; | 
|---|
|  | 381 | end; | 
|---|
|  | 382 |  | 
|---|
|  | 383 | { TORNotifier } | 
|---|
|  | 384 |  | 
|---|
|  | 385 | constructor TORNotifier.Create(Owner: TObject = nil; SingleInstance: boolean = FALSE); | 
|---|
|  | 386 | begin | 
|---|
|  | 387 | FOwner := Owner; | 
|---|
|  | 388 | if(assigned(Owner) and SingleInstance) then | 
|---|
|  | 389 | ObjectCreated(Owner.ClassType, FNotifyList); | 
|---|
|  | 390 | end; | 
|---|
|  | 391 |  | 
|---|
|  | 392 | destructor TORNotifier.Destroy; | 
|---|
|  | 393 | begin | 
|---|
|  | 394 | KillObj(@FNotifyList); | 
|---|
|  | 395 | inherited; | 
|---|
|  | 396 | end; | 
|---|
|  | 397 |  | 
|---|
|  | 398 | procedure TORNotifier.BeginUpdate; | 
|---|
|  | 399 | begin | 
|---|
|  | 400 | inc(FUpdateCount); | 
|---|
|  | 401 | end; | 
|---|
|  | 402 |  | 
|---|
|  | 403 | procedure TORNotifier.EndUpdate(DoNotify: boolean = FALSE); | 
|---|
|  | 404 | begin | 
|---|
|  | 405 | if(FUpdateCount > 0) then | 
|---|
|  | 406 | begin | 
|---|
|  | 407 | dec(FUpdateCount); | 
|---|
|  | 408 | if(DoNotify and (FUpdateCount = 0)) then Notify(FOwner); | 
|---|
|  | 409 | end; | 
|---|
|  | 410 | end; | 
|---|
|  | 411 |  | 
|---|
|  | 412 | procedure TORNotifier.Notify(Sender: TObject); | 
|---|
|  | 413 | begin | 
|---|
|  | 414 | if((FUpdateCount = 0) and assigned(FNotifyList) and (FNotifyList.Count > 0)) then | 
|---|
|  | 415 | DoNotify(Sender); | 
|---|
|  | 416 | end; | 
|---|
|  | 417 |  | 
|---|
|  | 418 | procedure TORNotifier.Notify; | 
|---|
|  | 419 | begin | 
|---|
|  | 420 | if((FUpdateCount = 0) and assigned(FNotifyList) and (FNotifyList.Count > 0)) then | 
|---|
|  | 421 | DoNotify(FOwner); | 
|---|
|  | 422 | end; | 
|---|
|  | 423 |  | 
|---|
|  | 424 | procedure TORNotifier.NotifyWhenChanged(Event: TNotifyEvent); | 
|---|
|  | 425 | begin | 
|---|
|  | 426 | if(not assigned(FNotifyList)) then | 
|---|
|  | 427 | FNotifyList := TORNotifyList.Create; | 
|---|
|  | 428 | FNotifyList.Add(Event); | 
|---|
|  | 429 | end; | 
|---|
|  | 430 |  | 
|---|
|  | 431 | procedure TORNotifier.NotifyWhenChanged(Event: TNotifyProc); | 
|---|
|  | 432 | begin | 
|---|
|  | 433 | if(not assigned(FNotifyList)) then | 
|---|
|  | 434 | FNotifyList := TORNotifyList.Create; | 
|---|
|  | 435 | FNotifyList.Add(Event); | 
|---|
|  | 436 | end; | 
|---|
|  | 437 |  | 
|---|
|  | 438 | procedure TORNotifier.RemoveNotify(Event: TNotifyEvent); | 
|---|
|  | 439 | begin | 
|---|
|  | 440 | if(assigned(FNotifyList)) then | 
|---|
|  | 441 | FNotifyList.Remove(Event); | 
|---|
|  | 442 | end; | 
|---|
|  | 443 |  | 
|---|
|  | 444 | procedure TORNotifier.RemoveNotify(Event: TNotifyProc); | 
|---|
|  | 445 | begin | 
|---|
|  | 446 | if(assigned(FNotifyList)) then | 
|---|
|  | 447 | FNotifyList.Remove(Event); | 
|---|
|  | 448 | end; | 
|---|
|  | 449 |  | 
|---|
|  | 450 | function TORNotifier.NotifyMethod: TNotifyEvent; | 
|---|
|  | 451 | begin | 
|---|
|  | 452 | Result := Notify; | 
|---|
|  | 453 | end; | 
|---|
|  | 454 |  | 
|---|
|  | 455 | function TORNotifier.GetOnNotify: TCanNotifyEvent; | 
|---|
|  | 456 | begin | 
|---|
|  | 457 | Result := FOnNotify; | 
|---|
|  | 458 | end; | 
|---|
|  | 459 |  | 
|---|
|  | 460 | procedure TORNotifier.SetOnNotify(Value: TCanNotifyEvent); | 
|---|
|  | 461 | begin | 
|---|
|  | 462 | FOnNotify := Value; | 
|---|
|  | 463 | end; | 
|---|
|  | 464 |  | 
|---|
|  | 465 | procedure TORNotifier.DoNotify(Sender: TObject); | 
|---|
|  | 466 | var | 
|---|
|  | 467 | CanNotify: boolean; | 
|---|
|  | 468 |  | 
|---|
|  | 469 | begin | 
|---|
|  | 470 | CanNotify := TRUE; | 
|---|
|  | 471 | if(assigned(FOnNotify)) then | 
|---|
|  | 472 | FOnNotify(Sender, CanNotify); | 
|---|
|  | 473 | if(CanNotify) then | 
|---|
|  | 474 | FNotifyList.Notify(Sender); | 
|---|
|  | 475 | end; | 
|---|
|  | 476 |  | 
|---|
|  | 477 | { TORStringList } | 
|---|
|  | 478 |  | 
|---|
|  | 479 | destructor TORStringList.Destroy; | 
|---|
|  | 480 | begin | 
|---|
|  | 481 | FNotifier := nil; // Frees instance | 
|---|
|  | 482 | inherited; | 
|---|
|  | 483 | end; | 
|---|
|  | 484 |  | 
|---|
|  | 485 | procedure TORStringList.Changed; | 
|---|
|  | 486 | var | 
|---|
|  | 487 | OldEvnt: TNotifyEvent; | 
|---|
|  | 488 |  | 
|---|
|  | 489 | begin | 
|---|
|  | 490 | { We redirect the OnChange event handler, rather than calling | 
|---|
|  | 491 | FNotifyList.Notify directly, because inherited may not call | 
|---|
|  | 492 | OnChange, and we don't have access to the private variables | 
|---|
|  | 493 | inherited uses to determine if OnChange should be called    } | 
|---|
|  | 494 |  | 
|---|
|  | 495 | if(assigned(FNotifier)) then | 
|---|
|  | 496 | begin | 
|---|
|  | 497 | OldEvnt := OnChange; | 
|---|
|  | 498 | try | 
|---|
|  | 499 | OnChange := FNotifier.NotifyMethod; | 
|---|
|  | 500 | inherited; // Conditionally Calls FNotifier.Notify | 
|---|
|  | 501 | finally | 
|---|
|  | 502 | OnChange := OldEvnt; | 
|---|
|  | 503 | end; | 
|---|
|  | 504 | end; | 
|---|
|  | 505 | inherited; // Conditionally Calls the old OnChange event handler | 
|---|
|  | 506 | end; | 
|---|
|  | 507 |  | 
|---|
|  | 508 | function TORStringList.IndexOfPiece(Value: string; Delim: Char; | 
|---|
|  | 509 | PieceNum: integer; | 
|---|
|  | 510 | StartIdx: integer): integer; | 
|---|
|  | 511 | begin | 
|---|
|  | 512 | Result := StartIdx; | 
|---|
|  | 513 | inc(Result); | 
|---|
|  | 514 | while((Result >= 0) and (Result < Count) and | 
|---|
|  | 515 | (Piece(Strings[Result], Delim, PieceNum) <> Value)) do | 
|---|
|  | 516 | inc(Result); | 
|---|
|  | 517 | if(Result < 0) or (Result >= Count) then Result := -1; | 
|---|
|  | 518 | end; | 
|---|
|  | 519 |  | 
|---|
|  | 520 | function TORStringList.IndexOfPieces(const Values: array of string; const Delim: Char; | 
|---|
|  | 521 | const Pieces: array of integer; | 
|---|
|  | 522 | StartIdx: integer = -1): integer; | 
|---|
|  | 523 | var | 
|---|
|  | 524 | Done: boolean; | 
|---|
|  | 525 |  | 
|---|
|  | 526 | begin | 
|---|
|  | 527 | Result := StartIdx; | 
|---|
|  | 528 | repeat | 
|---|
|  | 529 | inc(Result); | 
|---|
|  | 530 | if(Result >= 0) and (Result < Count) then | 
|---|
|  | 531 | Done := PiecesEqual(Result, Values, Pieces, Delim) | 
|---|
|  | 532 | else | 
|---|
|  | 533 | Done := TRUE; | 
|---|
|  | 534 | until(Done); | 
|---|
|  | 535 | if(Result < 0) or (Result >= Count) then Result := -1; | 
|---|
|  | 536 | end; | 
|---|
|  | 537 |  | 
|---|
|  | 538 | function TORStringList.IndexOfPieces(const Values: array of string): integer; | 
|---|
|  | 539 | begin | 
|---|
|  | 540 | Result := IndexOfPieces(Values, U, [], -1); | 
|---|
|  | 541 | end; | 
|---|
|  | 542 |  | 
|---|
|  | 543 | function TORStringList.IndexOfPieces(const Values: array of string; | 
|---|
|  | 544 | StartIdx: integer): integer; | 
|---|
|  | 545 | begin | 
|---|
|  | 546 | Result := IndexOfPieces(Values, U, [], StartIdx); | 
|---|
|  | 547 | end; | 
|---|
|  | 548 |  | 
|---|
|  | 549 | function TORStringList.GetNotifier: IORNotifier; | 
|---|
|  | 550 | begin | 
|---|
|  | 551 | if(not assigned(FNotifier)) then | 
|---|
|  | 552 | FNotifier := TORNotifier.Create(Self); | 
|---|
|  | 553 | Result := FNotifier; | 
|---|
|  | 554 | end; | 
|---|
|  | 555 |  | 
|---|
|  | 556 | procedure TORStringList.KillObjects; | 
|---|
|  | 557 | var | 
|---|
|  | 558 | i: integer; | 
|---|
|  | 559 |  | 
|---|
|  | 560 | begin | 
|---|
|  | 561 | for i := 0 to Count-1 do | 
|---|
|  | 562 | begin | 
|---|
|  | 563 | if(assigned(Objects[i])) then | 
|---|
|  | 564 | begin | 
|---|
|  | 565 | Objects[i].Free; | 
|---|
|  | 566 | Objects[i] := nil; | 
|---|
|  | 567 | end; | 
|---|
|  | 568 | end; | 
|---|
|  | 569 | end; | 
|---|
|  | 570 |  | 
|---|
|  | 571 | function TORStringList.PiecesEqual(const Index: integer; | 
|---|
|  | 572 | const Values: array of string): boolean; | 
|---|
|  | 573 | begin | 
|---|
|  | 574 | Result := PiecesEqual(Index, Values, [], U); | 
|---|
|  | 575 | end; | 
|---|
|  | 576 |  | 
|---|
|  | 577 | function TORStringList.PiecesEqual(const Index: integer; | 
|---|
|  | 578 | const Values: array of string; | 
|---|
|  | 579 | const Pieces: array of integer): boolean; | 
|---|
|  | 580 | begin | 
|---|
|  | 581 | Result := PiecesEqual(Index, Values, Pieces, U); | 
|---|
|  | 582 | end; | 
|---|
|  | 583 |  | 
|---|
|  | 584 | function TORStringList.PiecesEqual(const Index: integer; | 
|---|
|  | 585 | const Values: array of string; | 
|---|
|  | 586 | const Pieces: array of integer; | 
|---|
|  | 587 | const Delim: Char): boolean; | 
|---|
|  | 588 | var | 
|---|
|  | 589 | i, cnt, p: integer; | 
|---|
|  | 590 |  | 
|---|
|  | 591 | begin | 
|---|
|  | 592 | cnt := 0; | 
|---|
|  | 593 | Result := TRUE; | 
|---|
|  | 594 | for i := low(Values) to high(Values) do | 
|---|
|  | 595 | begin | 
|---|
|  | 596 | inc(cnt); | 
|---|
|  | 597 | if(i >= low(Pieces)) and (i <= high(Pieces)) then | 
|---|
|  | 598 | p := Pieces[i] | 
|---|
|  | 599 | else | 
|---|
|  | 600 | p := cnt; | 
|---|
|  | 601 | if(Piece(Strings[Index], Delim, p) <> Values[i]) then | 
|---|
|  | 602 | begin | 
|---|
|  | 603 | Result := FALSE; | 
|---|
|  | 604 | break; | 
|---|
|  | 605 | end; | 
|---|
|  | 606 | end; | 
|---|
|  | 607 | end; | 
|---|
|  | 608 |  | 
|---|
|  | 609 | procedure TORStringList.SortByPiece(PieceNum: integer; Delim: Char = '^'); | 
|---|
|  | 610 | begin | 
|---|
|  | 611 | SortByPieces([PieceNum], Delim); | 
|---|
|  | 612 | end; | 
|---|
|  | 613 |  | 
|---|
|  | 614 | procedure TORStringList.RemoveDuplicates(CaseSensitive: boolean = TRUE); | 
|---|
|  | 615 | var | 
|---|
|  | 616 | i: integer; | 
|---|
|  | 617 | Kill: boolean; | 
|---|
|  | 618 |  | 
|---|
|  | 619 | begin | 
|---|
|  | 620 | i := 1; | 
|---|
|  | 621 | while (i < Count) do | 
|---|
|  | 622 | begin | 
|---|
|  | 623 | if(CaseSensitive) then | 
|---|
|  | 624 | Kill := (Strings[i] = Strings[i-1]) | 
|---|
|  | 625 | else | 
|---|
|  | 626 | Kill := (CompareText(Strings[i],Strings[i-1]) = 0); | 
|---|
|  | 627 | if(Kill) then | 
|---|
|  | 628 | Delete(i) | 
|---|
|  | 629 | else | 
|---|
|  | 630 | inc(i); | 
|---|
|  | 631 | end; | 
|---|
|  | 632 | end; | 
|---|
|  | 633 |  | 
|---|
|  | 634 | function TORStringList.CaseInsensitiveIndexOfPiece(Value: string; Delim: Char = '^'; | 
|---|
|  | 635 | PieceNum: integer = 1; StartIdx: integer = -1): integer; | 
|---|
|  | 636 | begin | 
|---|
|  | 637 | Result := StartIdx; | 
|---|
|  | 638 | inc(Result); | 
|---|
|  | 639 | while((Result >= 0) and (Result < Count) and | 
|---|
|  | 640 | (CompareText(Piece(Strings[Result], Delim, PieceNum), Value) <> 0)) do | 
|---|
|  | 641 | inc(Result); | 
|---|
|  | 642 | if(Result < 0) or (Result >= Count) then Result := -1; | 
|---|
|  | 643 | end; | 
|---|
|  | 644 |  | 
|---|
|  | 645 | procedure TORStringList.SortByPieces(Pieces: array of integer; | 
|---|
|  | 646 | Delim: Char = '^'); | 
|---|
|  | 647 |  | 
|---|
|  | 648 | procedure QSort(L, R: Integer); | 
|---|
|  | 649 | var | 
|---|
|  | 650 | I, J: Integer; | 
|---|
|  | 651 | P: string; | 
|---|
|  | 652 |  | 
|---|
|  | 653 | begin | 
|---|
|  | 654 | repeat | 
|---|
|  | 655 | I := L; | 
|---|
|  | 656 | J := R; | 
|---|
|  | 657 | P := Strings[(L + R) shr 1]; | 
|---|
|  | 658 | repeat | 
|---|
|  | 659 | while ComparePieces(Strings[I], P, Pieces, Delim, TRUE) < 0 do Inc(I); | 
|---|
|  | 660 | while ComparePieces(Strings[J], P, Pieces, Delim, TRUE) > 0 do Dec(J); | 
|---|
|  | 661 | if I <= J then | 
|---|
|  | 662 | begin | 
|---|
|  | 663 | Exchange(I, J); | 
|---|
|  | 664 | Inc(I); | 
|---|
|  | 665 | Dec(J); | 
|---|
|  | 666 | end; | 
|---|
|  | 667 | until I > J; | 
|---|
|  | 668 | if L < J then QSort(L, J); | 
|---|
|  | 669 | L := I; | 
|---|
|  | 670 | until I >= R; | 
|---|
|  | 671 | end; | 
|---|
|  | 672 |  | 
|---|
|  | 673 | begin | 
|---|
|  | 674 | if not Sorted and (Count > 1) then | 
|---|
|  | 675 | begin | 
|---|
|  | 676 | Changing; | 
|---|
|  | 677 | QSort(0, Count - 1); | 
|---|
|  | 678 | Changed; | 
|---|
|  | 679 | end; | 
|---|
|  | 680 | end; | 
|---|
|  | 681 |  | 
|---|
|  | 682 |  | 
|---|
|  | 683 | procedure TORStringList.SetStrPiece(Index, PieceNum: integer; Delim: Char; | 
|---|
|  | 684 | const NewValue: string); | 
|---|
|  | 685 | var | 
|---|
|  | 686 | tmp: string; | 
|---|
|  | 687 |  | 
|---|
|  | 688 | begin | 
|---|
|  | 689 | tmp := Strings[Index]; | 
|---|
|  | 690 | ORFn.SetPiece(tmp,Delim,PieceNum,NewValue); | 
|---|
|  | 691 | Strings[Index] := tmp; | 
|---|
|  | 692 | end; | 
|---|
|  | 693 |  | 
|---|
|  | 694 | procedure TORStringList.SetStrPiece(Index, PieceNum: integer; | 
|---|
|  | 695 | const NewValue: string); | 
|---|
|  | 696 | begin | 
|---|
|  | 697 | SetStrPiece(Index, PieceNum, '^', NewValue); | 
|---|
|  | 698 | end; | 
|---|
|  | 699 |  | 
|---|
|  | 700 | { TORInterfaceList } | 
|---|
|  | 701 |  | 
|---|
|  | 702 | function TORInterfaceList.Add(Item: IUnknown): Integer; | 
|---|
|  | 703 | begin | 
|---|
|  | 704 | Result := inherited Add(Pointer(Item)); | 
|---|
|  | 705 | end; | 
|---|
|  | 706 |  | 
|---|
|  | 707 | function TORInterfaceList.Extract(Item: IUnknown): IUnknown; | 
|---|
|  | 708 | begin | 
|---|
|  | 709 | Result := IUnknown(inherited Extract(Pointer(Item))); | 
|---|
|  | 710 | end; | 
|---|
|  | 711 |  | 
|---|
|  | 712 | function TORInterfaceList.First: IUnknown; | 
|---|
|  | 713 | begin | 
|---|
|  | 714 | Result := IUnknown(inherited First); | 
|---|
|  | 715 | end; | 
|---|
|  | 716 |  | 
|---|
|  | 717 | function TORInterfaceList.GetItem(Index: Integer): IUnknown; | 
|---|
|  | 718 | begin | 
|---|
|  | 719 | Result := IUnknown(inherited Get(Index)); | 
|---|
|  | 720 | end; | 
|---|
|  | 721 |  | 
|---|
|  | 722 | function TORInterfaceList.IndexOf(Item: IUnknown): Integer; | 
|---|
|  | 723 | begin | 
|---|
|  | 724 | Result := inherited IndexOf(Pointer(Item)); | 
|---|
|  | 725 | end; | 
|---|
|  | 726 |  | 
|---|
|  | 727 | procedure TORInterfaceList.Insert(Index: Integer; Item: IUnknown); | 
|---|
|  | 728 | begin | 
|---|
|  | 729 | inherited Insert(Index, Pointer(Item)); | 
|---|
|  | 730 | end; | 
|---|
|  | 731 |  | 
|---|
|  | 732 | function TORInterfaceList.Last: IUnknown; | 
|---|
|  | 733 | begin | 
|---|
|  | 734 | Result := IUnknown(inherited Last); | 
|---|
|  | 735 | end; | 
|---|
|  | 736 |  | 
|---|
|  | 737 | procedure TORInterfaceList.Notify(Ptr: Pointer; Action: TListNotification); | 
|---|
|  | 738 | begin | 
|---|
|  | 739 | case Action of | 
|---|
|  | 740 | lnAdded:                IUnknown(Ptr)._AddRef; | 
|---|
|  | 741 | lnDeleted, lnExtracted: IUnknown(Ptr)._Release; | 
|---|
|  | 742 | end; | 
|---|
|  | 743 | end; | 
|---|
|  | 744 |  | 
|---|
|  | 745 | function TORInterfaceList.Remove(Item: IUnknown): Integer; | 
|---|
|  | 746 | begin | 
|---|
|  | 747 | Result := inherited Remove(Pointer(Item)); | 
|---|
|  | 748 | end; | 
|---|
|  | 749 |  | 
|---|
|  | 750 | procedure TORInterfaceList.SetItem(Index: Integer; const Value: IUnknown); | 
|---|
|  | 751 | begin | 
|---|
|  | 752 | inherited Put(Index, Pointer(Value)); | 
|---|
|  | 753 | end; | 
|---|
|  | 754 |  | 
|---|
|  | 755 |  | 
|---|
|  | 756 | initialization | 
|---|
|  | 757 |  | 
|---|
|  | 758 | finalization | 
|---|
|  | 759 | KillObj(@NotifyLists, TRUE); | 
|---|
|  | 760 |  | 
|---|
|  | 761 | end. | 
|---|