home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 June / Chip_2002-06_cd1.bin / zkuste / delphi / kolekce / d6 / rxlibsetup.exe / {app} / units / MrgMngr.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-02-19  |  10.2 KB  |  381 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 2001,2002 SGB Software          }
  6. {         Copyright (c) 1997, 1998 Fedor Koshevnikov,   }
  7. {                        Igor Pavluk and Serge Korolev  }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11.  
  12. unit MrgMngr;
  13.  
  14. {$I RX.INC}
  15.  
  16. interface
  17.  
  18. uses Classes, Controls, Forms, VCLUtils;
  19.  
  20. type
  21.   TFormRequestEvent = procedure(Sender: TObject; CurrentForm: TCustomForm;
  22.     var NewForm: TCustomForm) of object;
  23.   TFormReorderEvent = procedure(Sender: TObject;
  24.     Activated, Deactivated: TCustomForm) of object;
  25.   TFormHistory = class;
  26.   TFormHistoryCommand = (hcNone, hcAdd, hcBack, hcForward, hcGoto);
  27.  
  28. { TMergeManager }
  29.  
  30.   TMergeManager = class(TComponent)
  31.   private
  32.     FMergeFrame: TWinControl;
  33.     FFormHistory: TFormHistory;
  34.     FHistoryCommand: TFormHistoryCommand;
  35.     FOnGetBackForm: TFormRequestEvent;
  36.     FOnGetForwardForm: TFormRequestEvent;
  37.     FOnChange: TNotifyEvent;
  38.     FOnReorder: TFormReorderEvent;
  39.     function IsForm: Boolean;
  40.     function NotIsForm: Boolean;
  41.     procedure ReadForm(Reader: TReader);
  42.     procedure WriteForm(Writer: TWriter);
  43.     procedure SetMergeFrame(Value: TWinControl);
  44.     function GetActiveForm: TCustomForm;
  45.     procedure SetActiveForm(Value: TCustomForm);
  46.   protected
  47.     procedure DefineProperties(Filer: TFiler); override;
  48.     function GetBackForm: TCustomForm; virtual;
  49.     function GetForwardForm: TCustomForm; virtual;
  50.     procedure Notification(AComponent: TComponent;
  51.       Operation: TOperation); override;
  52.     procedure DoChange; dynamic;
  53.     procedure DoReorder(Deactivated: TCustomForm); dynamic;
  54.   public
  55.     constructor Create(AOwner: TComponent); override;
  56.     destructor Destroy; override;
  57.     procedure Merge(AForm: TCustomForm; Show: Boolean);
  58.     function GotoForm(AForm: TCustomForm): Boolean;
  59.     function GotoFormClass(AFormClass: TFormClass): Boolean;
  60.     procedure GoBack;
  61.     procedure GoForward;
  62.     procedure GotoHistoryIndex(HistoryIndex: Integer);
  63.     property FormHistory: TFormHistory read FFormHistory;
  64.     property ActiveForm: TCustomForm read GetActiveForm write SetActiveForm;
  65.     property HistoryCommand: TFormHistoryCommand read FHistoryCommand
  66.       write FHistoryCommand;
  67.   published
  68.     property MergeFrame: TWinControl read FMergeFrame write SetMergeFrame
  69.       stored NotIsForm;
  70.     property OnGetBackForm: TFormRequestEvent read FOnGetBackForm
  71.       write FOnGetBackForm;
  72.     property OnGetForwardForm: TFormRequestEvent read FOnGetForwardForm
  73.       write FOnGetForwardForm;
  74.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  75.     property OnReorder: TFormReorderEvent read FOnReorder write FOnReorder;
  76.   end;
  77.  
  78. { TFormHistory }
  79.  
  80.   TFormHistory = class(TList)
  81.   private
  82.     FCurrent: Integer;
  83.     FHistoryCapacity: Integer;
  84.     procedure SetCurrent(Value: Integer);
  85.     procedure SetHistoryCapacity(Value: Integer);
  86.     function GetForm(Index: Integer): TCustomForm;
  87.   public
  88.     constructor Create;
  89.     destructor Destroy; override;
  90.     procedure AddForm(AForm: TCustomForm);
  91.     procedure DeleteHistoryItem(Index: Integer);
  92.     function RemoveItem(Item: TComponent): Boolean;
  93.     procedure ResetHistory;
  94.     property Current: Integer read FCurrent write SetCurrent;
  95.     property HistoryCapacity: Integer read FHistoryCapacity
  96.       write SetHistoryCapacity;
  97.     property Forms[Index: Integer]: TCustomForm read GetForm;
  98.   end;
  99.  
  100. implementation
  101.  
  102. { TMergeManager }
  103.  
  104. constructor TMergeManager.Create(AOwner: TComponent);
  105. begin
  106.   inherited Create(AOwner);
  107.   FFormHistory := TFormHistory.Create;
  108.   FHistoryCommand := hcAdd;
  109. end;
  110.  
  111. destructor TMergeManager.Destroy;
  112. begin
  113.   FFormHistory.Free;
  114.   inherited Destroy;
  115. end;
  116.  
  117. function TMergeManager.NotIsForm: Boolean;
  118. begin
  119.   Result := (MergeFrame <> nil) and not (MergeFrame is TCustomForm);
  120. end;
  121.  
  122. function TMergeManager.IsForm: Boolean;
  123. begin
  124.   Result := (MergeFrame <> nil) and ((MergeFrame = Owner) and
  125.     (Owner is TCustomForm));
  126. end;
  127.  
  128. procedure TMergeManager.ReadForm(Reader: TReader);
  129. begin
  130.   if Reader.ReadBoolean then
  131.     if Owner is TCustomForm then MergeFrame := TWinControl(Owner);
  132. end;
  133.  
  134. procedure TMergeManager.WriteForm(Writer: TWriter);
  135. begin
  136.   Writer.WriteBoolean(IsForm);
  137. end;
  138.  
  139. procedure TMergeManager.DefineProperties(Filer: TFiler);
  140. {$IFDEF WIN32}
  141.   function DoWrite: Boolean;
  142.   begin
  143.     if Assigned(Filer.Ancestor) then
  144.       Result := IsForm <> TMergeManager(Filer.Ancestor).IsForm
  145.     else Result := IsForm;
  146.   end;
  147. {$ENDIF}
  148. begin
  149.   inherited DefineProperties(Filer);
  150.   Filer.DefineProperty('IsForm', ReadForm, WriteForm,
  151.     {$IFDEF WIN32} DoWrite {$ELSE} IsForm {$ENDIF});
  152. end;
  153.  
  154. procedure TMergeManager.SetMergeFrame(Value: TWinControl);
  155. begin
  156.   if FMergeFrame <> Value then begin
  157.     FMergeFrame := Value;
  158. {$IFDEF WIN32}
  159.     if Value <> nil then Value.FreeNotification(Self);
  160. {$ENDIF}
  161.     FFormHistory.ResetHistory;
  162.   end;
  163. end;
  164.  
  165. function TMergeManager.GetActiveForm: TCustomForm;
  166. var
  167.   I: Integer;
  168. begin
  169.   if (MergeFrame <> nil) and (MergeFrame.ControlCount > 0) then begin
  170.     for I := MergeFrame.ControlCount - 1 downto 0 do begin
  171.       if MergeFrame.Controls[I] is TCustomForm then begin
  172.         Result := TCustomForm(MergeFrame.Controls[I]);
  173.         Exit;
  174.       end;
  175.     end;
  176.   end;
  177.   Result := nil;
  178. end;
  179.  
  180. procedure TMergeManager.SetActiveForm(Value: TCustomForm);
  181. begin
  182.   GotoForm(Value);
  183. end;
  184.  
  185. function TMergeManager.GetBackForm: TCustomForm;
  186. begin
  187.   if FormHistory.Current < 1 then
  188.     Result := nil
  189.   else
  190.     Result := FormHistory.Forms[FormHistory.Current - 1];
  191.   if Assigned(FOnGetBackForm) then FOnGetBackForm(Self, ActiveForm, Result);
  192. end;
  193.  
  194. function TMergeManager.GetForwardForm: TCustomForm;
  195. begin
  196.   if FormHistory.Current >= FormHistory.Count - 1 then
  197.     Result := nil
  198.   else
  199.     Result := FormHistory.Forms[FormHistory.Current + 1];
  200.   if Assigned(FOnGetForwardForm) then FOnGetForwardForm(Self, ActiveForm, Result);
  201. end;
  202.  
  203. procedure TMergeManager.Notification(AComponent: TComponent;
  204.   Operation: TOperation);
  205. begin
  206.   inherited Notification(AComponent, Operation);
  207.   if Operation = opRemove then begin
  208.     if AComponent = MergeFrame then MergeFrame := nil;
  209.     if FormHistory.RemoveItem(AComponent) then DoChange;
  210.   end;
  211. end;
  212.  
  213. procedure TMergeManager.DoChange;
  214. begin
  215.   if Assigned(FOnChange) then FOnChange(Self);
  216. end;
  217.  
  218. procedure TMergeManager.DoReorder(Deactivated: TCustomForm);
  219. begin
  220.   if Assigned(FOnReorder) then FOnReorder(Self, ActiveForm, Deactivated);
  221. end;
  222.  
  223. procedure TMergeManager.Merge(AForm: TCustomForm; Show: Boolean);
  224. begin
  225.   MergeForm(MergeFrame, TForm(AForm), alClient, Show);
  226.   GotoForm(AForm);
  227. end;
  228.  
  229. function TMergeManager.GotoForm(AForm: TCustomForm): Boolean;
  230. var
  231.   I: Integer;
  232.   OldActiveForm: TCustomForm;
  233. begin
  234.   Result := False;
  235.   OldActiveForm := ActiveForm;
  236.   if MergeFrame = nil then Exit;
  237.   for I := 0 to MergeFrame.ControlCount - 1 do begin
  238.     if MergeFrame.Controls[I] = AForm then begin
  239.       AForm.BringToFront;
  240.       case HistoryCommand of
  241.         hcNone: ;
  242.         hcAdd: FormHistory.AddForm(AForm);
  243.         hcBack: FormHistory.Current := FormHistory.Current - 1;
  244.         hcForward: FormHistory.Current := FormHistory.Current + 1;
  245.         hcGoto: ;
  246.       end;
  247.       HistoryCommand := hcAdd;
  248.       DoReorder(OldActiveForm);
  249.       DoChange;
  250.       Result := True;
  251.       Exit;
  252.     end;
  253.   end;
  254. end;
  255.  
  256. function TMergeManager.GotoFormClass(AFormClass: TFormClass): Boolean;
  257. var
  258.   I: Integer;
  259. begin
  260.   Result := False;
  261.   if MergeFrame = nil then Exit;
  262.   for I := 0 to MergeFrame.ControlCount - 1 do begin
  263.     if MergeFrame.Controls[I] is AFormClass then begin
  264.       Result := GotoForm(MergeFrame.Controls[I] as TCustomForm);     
  265.       Exit;
  266.     end;
  267.   end;
  268. end;
  269.  
  270. procedure TMergeManager.GoBack;
  271. begin
  272.   HistoryCommand := hcBack;
  273.   GotoForm(GetBackForm);
  274. end;
  275.  
  276. procedure TMergeManager.GoForward;
  277. begin
  278.   HistoryCommand := hcForward;
  279.   GotoForm(GetForwardForm);
  280. end;
  281.  
  282. procedure TMergeManager.GotoHistoryIndex(HistoryIndex: Integer);
  283. var
  284.   SaveCurrent: Integer;
  285. begin
  286.   SaveCurrent := FormHistory.Current;
  287.   FormHistory.Current := HistoryIndex;
  288.   try
  289.     HistoryCommand := hcGoto;
  290.     GotoForm(FormHistory.Forms[HistoryIndex]);
  291.   finally
  292.     if ActiveForm <> FormHistory.Forms[HistoryIndex] then
  293.       FormHistory.Current := SaveCurrent;
  294.   end;
  295. end;
  296.  
  297. { TFormHistory }
  298.  
  299. constructor TFormHistory.Create;
  300. begin
  301.   inherited Create;
  302.   FCurrent := -1;
  303.   FHistoryCapacity := 10;
  304. end;
  305.  
  306. destructor TFormHistory.Destroy;
  307. begin
  308.   inherited Destroy;
  309. end;
  310.  
  311. procedure TFormHistory.SetCurrent(Value: Integer);
  312. begin
  313.   if Value < 0 then Value := -1;
  314.   if Value > Count - 1 then Value := Count - 1;
  315.   if FCurrent <> Value then begin
  316.     FCurrent := Value;
  317.   end;
  318. end;
  319.  
  320. procedure TFormHistory.SetHistoryCapacity(Value: Integer);
  321. var
  322.   I: Integer;
  323. begin
  324.   if Value < FHistoryCapacity then begin
  325.     for I := 0 to Count - Value do begin
  326.       RemoveItem(Forms[0]);
  327.     end;
  328.   end;
  329.   FHistoryCapacity := Value;
  330. end;
  331.  
  332. function TFormHistory.GetForm(Index: Integer): TCustomForm;
  333. begin
  334.   Result := TCustomForm(Items[Index]);
  335. end;
  336.  
  337. procedure TFormHistory.AddForm(AForm: TCustomForm);
  338. var
  339.   I: Integer;
  340. begin
  341.   for I := Count - 1 downto Current + 1 do begin
  342.     DeleteHistoryItem(I);
  343.   end;
  344.   for I := 0 to Count - HistoryCapacity do begin
  345.     DeleteHistoryItem(0);
  346.   end;
  347.   if Count < HistoryCapacity then begin
  348.     Add(AForm);
  349.   end;
  350.   Current := Count - 1;
  351. end;
  352.  
  353. procedure TFormHistory.DeleteHistoryItem(Index: Integer);
  354. begin
  355.   if (Index >= 0) and (Index < Count) then begin
  356.     Delete(Index);
  357.     if Current > Count - 1 then Current := Count - 1;
  358.   end;
  359. end;
  360.  
  361. function TFormHistory.RemoveItem(Item: TComponent): Boolean;
  362. var
  363.   I: Integer;
  364. begin
  365.   Result := False;
  366.   for I := Count - 1 downto 0 do begin
  367.     if Items[I] = Item then begin
  368.       DeleteHistoryItem(I);
  369.       Result := True;
  370.     end;
  371.   end;
  372. end;
  373.  
  374. procedure TFormHistory.ResetHistory;
  375. begin
  376.   Clear;
  377.   Current := -1;
  378. end;
  379.  
  380. end.
  381.