Componentes.Terceros.jvcl/official/3.32/run/JvMergeManager.pas

446 lines
12 KiB
ObjectPascal

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvMrgMngr.PAS, released on 2002-07-04.
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 2001,2002 SGB Software
All Rights Reserved.
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvMergeManager.pas 10612 2006-05-19 19:04:09Z jfudickar $
unit JvMergeManager;
{$I jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
Classes, Controls, Forms,
JvJVCLUtils, JvComponentBase;
type
TFormRequestEvent = procedure(Sender: TObject; CurrentForm: TCustomForm;
var NewForm: TCustomForm) of object;
TFormReorderEvent = procedure(Sender: TObject;
Activated, Deactivated: TCustomForm) of object;
TJvFormHistory = class;
TFormHistoryCommand = (hcNone, hcAdd, hcBack, hcForward, hcGoto);
TJvMergeManager = class(TJvComponent)
private
FMergeFrame: TWinControl;
FFormHistory: TJvFormHistory;
FHistoryCommand: TFormHistoryCommand;
FOnGetBackForm: TFormRequestEvent;
FOnGetForwardForm: TFormRequestEvent;
FOnChange: TNotifyEvent;
FOnReorder: TFormReorderEvent;
function IsForm: Boolean;
function MergeFrameStored: Boolean;
procedure ReadForm(Reader: TReader);
procedure WriteForm(Writer: TWriter);
procedure SetMergeFrame(Value: TWinControl);
function GetActiveForm: TCustomForm;
procedure SetActiveForm(Value: TCustomForm);
protected
procedure DefineProperties(Filer: TFiler); override;
function GetBackForm: TCustomForm; virtual;
function GetForwardForm: TCustomForm; virtual;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure DoChange; dynamic;
procedure DoReorder(Deactivated: TCustomForm); dynamic;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Merge(AForm: TCustomForm; Show: Boolean);
procedure UnmergeMainMenu(AForm: TCustomForm);
procedure MergeMainMenu(AForm: TCustomForm; Force: Boolean);
function GotoForm(AForm: TCustomForm): Boolean;
function GotoFormClass(AFormClass: TFormClass): Boolean;
procedure GoBack;
procedure GoForward;
procedure GotoHistoryIndex(HistoryIndex: Integer);
property FormHistory: TJvFormHistory read FFormHistory;
property ActiveForm: TCustomForm read GetActiveForm write SetActiveForm;
property HistoryCommand: TFormHistoryCommand read FHistoryCommand write FHistoryCommand;
published
property MergeFrame: TWinControl read FMergeFrame write SetMergeFrame stored MergeFrameStored;
property OnGetBackForm: TFormRequestEvent read FOnGetBackForm write FOnGetBackForm;
property OnGetForwardForm: TFormRequestEvent read FOnGetForwardForm write FOnGetForwardForm;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnReorder: TFormReorderEvent read FOnReorder write FOnReorder;
end;
TJvFormHistory = class(TList)
private
FCurrent: Integer;
FHistoryCapacity: Integer;
procedure SetCurrent(Value: Integer);
procedure SetHistoryCapacity(Value: Integer);
function GetForm(Index: Integer): TCustomForm;
public
constructor Create;
procedure AddForm(AForm: TCustomForm);
procedure DeleteHistoryItem(Index: Integer);
function RemoveItem(Item: TComponent): Boolean;
procedure ResetHistory;
property Current: Integer read FCurrent write SetCurrent;
property HistoryCapacity: Integer read FHistoryCapacity write SetHistoryCapacity;
property Forms[Index: Integer]: TCustomForm read GetForm;
end;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$URL: https://jvcl.svn.sourceforge.net/svnroot/jvcl/tags/JVCL3_32/run/JvMergeManager.pas $';
Revision: '$Revision: 10612 $';
Date: '$Date: 2006-05-19 21:04:09 +0200 (ven., 19 mai 2006) $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
implementation
//=== { TJvMergeManager } ====================================================
constructor TJvMergeManager.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FFormHistory := TJvFormHistory.Create;
FHistoryCommand := hcAdd;
end;
destructor TJvMergeManager.Destroy;
begin
inherited Destroy;
// (ahuser) FFormHistory must be freed after inherited Destroy to avoid AVs
// in design mode.
FFormHistory.Free;
end;
function TJvMergeManager.MergeFrameStored: Boolean;
begin
Result := (MergeFrame <> nil) and not (MergeFrame is TCustomForm);
end;
function TJvMergeManager.IsForm: Boolean;
begin
Result := (MergeFrame <> nil) and ((MergeFrame = Owner) and (Owner is TCustomForm));
end;
procedure TJvMergeManager.ReadForm(Reader: TReader);
begin
if Reader.ReadBoolean then
if Owner is TCustomForm then
MergeFrame := TWinControl(Owner);
end;
procedure TJvMergeManager.WriteForm(Writer: TWriter);
begin
Writer.WriteBoolean(IsForm);
end;
procedure TJvMergeManager.DefineProperties(Filer: TFiler);
function DoWrite: Boolean;
begin
if Assigned(Filer.Ancestor) then
Result := IsForm <> TJvMergeManager(Filer.Ancestor).IsForm
else
Result := IsForm;
end;
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('IsForm', ReadForm, WriteForm, DoWrite);
end;
procedure TJvMergeManager.SetMergeFrame(Value: TWinControl);
begin
if FMergeFrame <> Value then
begin
FMergeFrame := Value;
if Value <> nil then
Value.FreeNotification(Self);
FFormHistory.ResetHistory;
end;
end;
function TJvMergeManager.GetActiveForm: TCustomForm;
var
I: Integer;
begin
Result := nil;
if (MergeFrame <> nil) and (MergeFrame.ControlCount > 0) then
for I := MergeFrame.ControlCount - 1 downto 0 do
begin
if MergeFrame.Controls[I] is TCustomForm then
begin
Result := TCustomForm(MergeFrame.Controls[I]);
Break;
end;
end;
end;
procedure TJvMergeManager.SetActiveForm(Value: TCustomForm);
begin
GotoForm(Value);
end;
function TJvMergeManager.GetBackForm: TCustomForm;
begin
if FormHistory.Current < 1 then
Result := nil
else
Result := FormHistory.Forms[FormHistory.Current - 1];
if Assigned(FOnGetBackForm) then
FOnGetBackForm(Self, ActiveForm, Result);
end;
function TJvMergeManager.GetForwardForm: TCustomForm;
begin
if FormHistory.Current >= FormHistory.Count - 1 then
Result := nil
else
Result := FormHistory.Forms[FormHistory.Current + 1];
if Assigned(FOnGetForwardForm) then
FOnGetForwardForm(Self, ActiveForm, Result);
end;
procedure TJvMergeManager.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if Operation = opRemove then
begin
if AComponent = MergeFrame then
MergeFrame := nil;
if FormHistory.RemoveItem(AComponent) then
DoChange;
end;
end;
procedure TJvMergeManager.DoChange;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TJvMergeManager.DoReorder(Deactivated: TCustomForm);
begin
if Assigned(FOnReorder) then
FOnReorder(Self, ActiveForm, Deactivated);
end;
procedure TJvMergeManager.Merge(AForm: TCustomForm; Show: Boolean);
begin
MergeForm(MergeFrame, TForm(AForm), alClient, Show);
GotoForm(AForm);
end;
function TJvMergeManager.GotoForm(AForm: TCustomForm): Boolean;
var
I: Integer;
OldActiveForm: TCustomForm;
begin
Result := False;
OldActiveForm := ActiveForm;
if MergeFrame = nil then
Exit;
UnmergeMainMenu(OldActiveForm);
for I := 0 to MergeFrame.ControlCount - 1 do
begin
if MergeFrame.Controls[I] = AForm then
begin
AForm.BringToFront;
MergeMainMenu(AForm, False);
case HistoryCommand of
hcNone:
;
hcAdd:
FormHistory.AddForm(AForm);
hcBack:
FormHistory.Current := FormHistory.Current - 1;
hcForward:
FormHistory.Current := FormHistory.Current + 1;
hcGoto:
;
end;
HistoryCommand := hcAdd;
DoReorder(OldActiveForm);
DoChange;
Result := True;
Exit;
end;
end;
end;
function TJvMergeManager.GotoFormClass(AFormClass: TFormClass): Boolean;
var
I: Integer;
begin
Result := False;
if MergeFrame = nil then
Exit;
for I := 0 to MergeFrame.ControlCount - 1 do
begin
if MergeFrame.Controls[I] is AFormClass then
begin
Result := GotoForm(MergeFrame.Controls[I] as TCustomForm);
Exit;
end;
end;
end;
procedure TJvMergeManager.GoBack;
begin
HistoryCommand := hcBack;
GotoForm(GetBackForm);
end;
procedure TJvMergeManager.GoForward;
begin
HistoryCommand := hcForward;
GotoForm(GetForwardForm);
end;
procedure TJvMergeManager.GotoHistoryIndex(HistoryIndex: Integer);
var
SaveCurrent: Integer;
begin
SaveCurrent := FormHistory.Current;
FormHistory.Current := HistoryIndex;
try
HistoryCommand := hcGoto;
GotoForm(FormHistory.Forms[HistoryIndex]);
finally
if ActiveForm <> FormHistory.Forms[HistoryIndex] then
FormHistory.Current := SaveCurrent;
end;
end;
//=== { TJvFormHistory } =====================================================
constructor TJvFormHistory.Create;
begin
inherited Create;
FCurrent := -1;
FHistoryCapacity := 10;
end;
procedure TJvFormHistory.SetCurrent(Value: Integer);
begin
if Value < 0 then
Value := -1;
if Value > Count - 1 then
Value := Count - 1;
FCurrent := Value;
end;
procedure TJvFormHistory.SetHistoryCapacity(Value: Integer);
var
I: Integer;
begin
if Value < FHistoryCapacity then
for I := 0 to Count - Value do
RemoveItem(Forms[0]);
FHistoryCapacity := Value;
end;
function TJvFormHistory.GetForm(Index: Integer): TCustomForm;
begin
Result := TCustomForm(Items[Index]);
end;
procedure TJvFormHistory.AddForm(AForm: TCustomForm);
var
I: Integer;
begin
for I := Count - 1 downto Current + 1 do
DeleteHistoryItem(I);
for I := 0 to Count - HistoryCapacity do
DeleteHistoryItem(0);
if Count < HistoryCapacity then
Add(AForm);
Current := Count - 1;
end;
procedure TJvFormHistory.DeleteHistoryItem(Index: Integer);
begin
if (Index >= 0) and (Index < Count) then
begin
Delete(Index);
if Current > Count - 1 then
Current := Count - 1;
end;
end;
function TJvFormHistory.RemoveItem(Item: TComponent): Boolean;
var
I: Integer;
begin
Result := False;
for I := Count - 1 downto 0 do
if Items[I] = Item then
begin
DeleteHistoryItem(I);
Result := True;
end;
end;
procedure TJvFormHistory.ResetHistory;
begin
Clear;
Current := -1;
end;
procedure TJvMergeManager.MergeMainMenu(AForm: TCustomForm; Force: Boolean);
var
F: TCustomForm;
begin
F := GetParentForm(MergeFrame);
if (F <> nil) and (F.Menu <> nil) and (AForm <> nil) and
(AForm.Menu <> nil) and (Force or AForm.Menu.AutoMerge) then
F.Menu.Merge(AForm.Menu);
end;
procedure TJvMergeManager.UnmergeMainMenu(AForm: TCustomForm);
var
F: TCustomForm;
begin
F := GetParentForm(MergeFrame);
if (F <> nil) and (F.Menu <> nil) and (AForm <> nil) and (AForm.Menu <> nil) then
F.Menu.Unmerge(AForm.Menu);
end;
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.