| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- unit ListSort;
- {
- Description
- ===========
- Contains the classes TSortedList and TBatchWork. You will find more
- details in the help-files.
- Disclaimer
- ==========
- The author disclaims all warranties, expressed or implied, including,
- without limitation, the warranties of merchantability and of fitness
- for any purpose. The author assumes no liability for damages, direct or
- consequential, which may result from the use of this component/units.
- Restrictions on Using the Unit / Component
- ==========================================
- This archive and its contents is copyright 1998,99 by Dieter Steinwedel.
- ALL RIGHTS ARE RESERVED BY DIETER STEINWEDEL. You are allowed to use it
- freely subject to the following restrictions:
- • You are not allowed delete or alter the author's name and
- copyright in any manner
- • You are not allowed to publish a copy, modified version or
- compilation neither for payment in any kind nor freely if the
- author has not agreed
- • You are allowed to create a link to the download in the WWW
- These restrictions and terms apply to you as long as you use this
- archive. I won't change these conditions when I have published the
- archive. But I reserve the right to alter these conditions for a
- newer archive version. The archive version is the archive's date.
- Changes can found on my homepage.
- Contact
- =======
- homepage: http://godard.oec.uni-osnabrueck.de/student_home/dsteinwe/delphi/DietersDelphiSite.htm
- }
- interface
- uses Classes, SysUtils;
- type
- TCompareFunction = function (Sender: TObject; Item1, Item2: Pointer): integer of object;
- TOnListEvent = procedure (Sender: TObject; Item: Pointer) of object;
- TBatchControlEvent = procedure(Sender: TObject; Item:pointer) of object;
- TSortedList = class(TList)
- private
- FCompare:TCompareFunction;
- FOnAdd:TOnListEvent;
- FOnModify:TOnListEvent;
- FOnErase:TOnListEvent;
- FAllowDuplicates: boolean;
- public
- constructor Create;
- function Add(Item: Pointer): integer;
- procedure Clear; {MP}reintroduce;{/MP}
- procedure Delete(Index:integer);
- function FindObject(Item : Pointer) : integer;
- function Insert(Index: Integer; Item: Pointer): integer;
- function Rearrange(Item: Pointer):integer;
- procedure Remove(Item:Pointer);
- procedure Sort;
- property AllowDuplicates: boolean read FAllowDuplicates write FAllowDuplicates;
- property OnAdd: TOnListEvent read FOnAdd write FOnAdd;
- property OnCompare: TCompareFunction read FCompare write FCompare;
- property OnModify: TOnListEvent read FOnModify write FOnModify;
- property OnErase: TOnListEvent read FOnErase write FOnErase;
- end;
- TBatchControl = class(TComponent)
- private
- FOnProcess: TBatchControlEvent;
- FList: TSortedList;
- public
- property List: TSortedList read FList write FList;
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Execute;
- published
- property OnProcess: TBatchControlEvent read FOnProcess write FOnProcess;
- end;
- procedure Register;
- implementation
- procedure Register;
- begin
- {MP}RegisterComponents({'Misc'}'DragDrop', [TBatchControl]);
- end;
- { SortedList ------------------------------------------------------ }
- constructor TSortedList.Create;
- begin
- inherited Create;
- FAllowDuplicates := true;
- end;
- function TSortedList.Add(Item : Pointer) : integer;
- var
- nCount : integer;
- bFound : Boolean;
- begin
- nCount := 0;
- bFound := False;
- if Assigned(FCompare) then
- begin
- { search the list of objects until we find the
- correct position for the new object we are adding }
- while (not bFound) and (nCount < Count) do
- begin
- if (FCompare(self,Items[nCount],Item) >= 0) then bFound := True
- else inc(nCount);
- end;
- if bFound then
- begin
- if FAllowDuplicates or (FCompare(self,Items[nCount],Item)<>0) then
- begin
- inherited Insert(nCount,Item);
- Result := nCount;
- end
- else Result := -1;
- end else Result := inherited Add(Item);
- end
- else Result:=inherited Add(Item);
- if Assigned(FOnAdd) then FOnAdd(self,Item);
- end;
- function TSortedList.Insert(Index: Integer; Item: Pointer):integer;
- var
- nCount : integer;
- bFound : Boolean;
- begin
- nCount := 0;
- bFound := False;
- if Assigned(FCompare) then
- begin
- { search the list of objects until we find the
- correct position for the new object we are adding }
- while (not bFound) and (nCount < Count) do
- begin
- if (FCompare(self,Items[nCount],Item) >= 0) then bFound := True
- else inc(nCount);
- end;
- if bFound then
- begin
- if FAllowDuplicates or (FCompare(self,Items[nCount],Item)<>0) then
- begin
- inherited Insert(nCount,Item);
- Result := nCount;
- end
- else Result := -1;
- end else Result := inherited Add(Item);
- end
- else
- begin
- inherited Insert(Index,Item);
- Result:=Index;
- end;
- if Assigned(FOnAdd) then FOnAdd(self,Item);
- end;
- function TSortedList.FindObject(Item : Pointer) : integer;
- { Find the object using the compare method and
- a binary chop search }
- var
- nResult : integer;
- nLow : integer;
- nHigh : integer;
- nCompare : integer;
- nCheckPos : integer;
- begin
- nLow := 0;
- nHigh := Count-1;
- nResult := -1;
- { keep searching until found or no more items to search }
- while (nResult = -1) and (nLow <= nHigh) do
- begin
- nCheckPos := (nLow + nHigh) div 2;
- nCompare := FCompare(self, Item,Items[nCheckPos]);
- if (nCompare = -1) then nHigh := nCheckPos - 1 { less than }
- else if (nCompare = 1) then nLow := nCheckPos + 1 { greater than }
- else nResult := nCheckPos; { equal to }
- end;
- FindObject := nResult;
- end;
- procedure TSortedList.Sort;
- procedure QuickSort(ILo, IHi:integer);
- var Lo, Hi:integer;
- MidItem: pointer;
- begin
- Lo:=ILo;
- Hi:=IHi;
- MidItem:=Items[(Lo+Hi) div 2];
- repeat
- while FCompare(self,Items[Lo],MidItem)=-1 do inc(Lo);
- while FCompare(self,Items[Hi],MidItem)=1 do dec(Hi);
- if Lo<=Hi then
- begin
- Exchange(Lo,Hi);
- inc(Lo);
- dec(Hi);
- end;
- until Lo>Hi;
- if Hi>ILo then QuickSort(ILo,Hi);
- if Lo<IHi then Quicksort(Lo,IHi);
- end;
- var i:integer;
- begin
- if Assigned(FCompare) then
- begin
- if Count>0 then
- begin
- Quicksort(0,Count-1);
- if (FAllowDuplicates=false) and (count>=2) then
- begin
- for i:=count-1 downto 1 do
- if FCompare(self,Items[i],Items[i-1])=0 then
- delete(i);
- end;
- end;
- end
- else raise Exception.Create('Compare methode is not assigned!')
- end;
- procedure TSortedList.Clear;
- begin
- while Count>0 do Delete(Count-1);
- end;
- function TSortedList.Rearrange(Item: Pointer):integer;
- begin
- Remove(Item);
- Result:=Add(Item);
- if Assigned(FOnModify) then FOnModify(self,Item);
- end;
- procedure TSortedList.Delete(Index:integer);
- begin
- if Assigned(FOnErase) then FOnErase(self,Items[Index]);
- inherited Delete(Index);
- end;
- procedure TSortedList.Remove(Item:Pointer);
- begin
- if Assigned(FOnErase) then FOnErase(self,Item);
- inherited Remove(Item);
- end;
- { BatchControl ------------------------------------------------------ }
- constructor TBatchControl.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FList:=TSortedList.Create;
- end;
- destructor TBatchControl.Destroy;
- begin
- FList.free;
- inherited Destroy;
- end;
- procedure TBatchControl.Execute;
- begin
- if Assigned(FOnProcess) then
- begin
- while (FList.Count>0) do
- begin
- FOnProcess(self,FList.Items[FList.Count-1]);
- if (FList.Items[FList.Count-1]<>nil) then
- FList.Delete(FList.Count-1);
- end;
- end
- else raise Exception.Create('No OnProcess-method defined!');
- end;
- end.
|