446 lines
12 KiB
ObjectPascal
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.
|
|
|