You've already forked lazarus-ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6661 8e941d3f-bd1b-0410-a28a-d453659cc2b4
284 lines
8.4 KiB
ObjectPascal
284 lines
8.4 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: JvLinkedControls.PAS, released on 2004-01-26.
|
|
|
|
The Initial Developer of the Original Code is Peter Thörnqvist
|
|
Portions created by Peter Thörnqvist are Copyright (C) 2004 Peter Thörnqvist.
|
|
All Rights Reserved.
|
|
|
|
Contributor(s):
|
|
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|
located at http://jvcl.delphi-jedi.org
|
|
|
|
Known Issues:
|
|
-----------------------------------------------------------------------------}
|
|
// $Id$
|
|
|
|
unit JvLinkedControls;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, Controls, Classes;
|
|
|
|
type
|
|
TJvLinkedControlsOption = (loLinkChecked, loLinkEnabled, loInvertChecked, loInvertEnabled, loForceFocus);
|
|
TJvLinkedControlsOptions = set of TJvLinkedControlsOption;
|
|
|
|
TJvLinkedControl = class(TCollectionItem)
|
|
private
|
|
FOwnerControl, FControl: TControl;
|
|
FOptions: TJvLinkedControlsOptions;
|
|
FOriginalEnabled: Boolean;
|
|
procedure SetControl(const Value: TControl);
|
|
procedure SetOptions(const Value: TJvLinkedControlsOptions);
|
|
protected
|
|
function GetDisplayName: string; override;
|
|
public
|
|
constructor Create(ACollection: TCollection); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Control: TControl read FControl write SetControl;
|
|
property Options: TJvLinkedControlsOptions read FOptions write SetOptions default [loLinkChecked, loLinkEnabled];
|
|
end;
|
|
|
|
TJvLinkedControls = class(TOwnedCollection)
|
|
private
|
|
FControl: TControl;
|
|
FOnChange: TNotifyEvent;
|
|
FRestoreEnabled: Boolean;
|
|
function GetItems(Index: Integer): TJvLinkedControl;
|
|
procedure SetItems(Index: Integer; const Value: TJvLinkedControl);
|
|
protected
|
|
procedure Update(Item: TCollectionItem); override;
|
|
public
|
|
// You must call Notification in the Owning controls overridden Notification
|
|
// or hell will break loose when linked controls are removed!!!
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;
|
|
constructor Create(AControl: TControl);
|
|
function Add: TJvLinkedControl;
|
|
procedure Assign(Source: TPersistent); override;
|
|
// If RestoreEnabled is True, TJvLinkedControls will try to restore the Enabled state
|
|
// of linked controls when an item is changed or removed
|
|
property Items[Index: Integer]: TJvLinkedControl read GetItems write SetItems; default;
|
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
published
|
|
property RestoreEnabled: Boolean read FRestoreEnabled write FRestoreEnabled default True;
|
|
end;
|
|
|
|
function CheckLinkControlEnabled(Enabled, Checked: Boolean; Options: TJvLinkedControlsOptions): Boolean;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
const
|
|
UnitVersioning: TUnitVersionInfo = (
|
|
RCSfile: '$URL$';
|
|
Revision: '$Revision$';
|
|
Date: '$Date$';
|
|
LogPath: 'JVCL\run'
|
|
);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
implementation
|
|
|
|
uses
|
|
JvResources;
|
|
|
|
function CheckLinkControlEnabled(Enabled, Checked: Boolean; Options: TJvLinkedControlsOptions): Boolean;
|
|
var
|
|
IsChecked, IsEnabled: Boolean;
|
|
begin
|
|
if loInvertChecked in Options then
|
|
IsChecked := not Checked
|
|
else
|
|
IsChecked := Checked;
|
|
|
|
if loInvertEnabled in Options then
|
|
IsEnabled := not Enabled
|
|
else
|
|
IsEnabled := Enabled;
|
|
|
|
if (loLinkChecked in Options) and (loLinkEnabled in Options) then
|
|
Result := IsChecked and IsEnabled
|
|
else
|
|
Result := ((loLinkChecked in Options) and IsChecked) or ((loLinkEnabled in Options) and IsEnabled);
|
|
|
|
// Result := ((loLinkChecked in Options) and ((not Checked and (loInvertChecked in Options) or (Checked and not (loInvertChecked in Options))))) or
|
|
// ((loLinkEnabled in Options) and (not Enabled and (loInvertEnabled in Options)) or (Enabled and not (loInvertEnabled in Options)));
|
|
end;
|
|
|
|
//=== { TJvLinkedControl } ===================================================
|
|
|
|
constructor TJvLinkedControl.Create(ACollection: TCollection);
|
|
begin
|
|
inherited Create(ACollection);
|
|
if (ACollection is TJvLinkedControls) then
|
|
FOwnerControl := TJvLinkedControls(ACollection).FControl;
|
|
FOptions := [loLinkChecked, loLinkEnabled];
|
|
end;
|
|
|
|
destructor TJvLinkedControl.Destroy;
|
|
begin
|
|
if (FControl <> nil) and not (csDestroying in FControl.ComponentState) and
|
|
(Collection is TJvLinkedControls) and TJvLinkedControls(Collection).RestoreEnabled then
|
|
FControl.Enabled := FOriginalEnabled;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TJvLinkedControl.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TJvLinkedControl then
|
|
begin
|
|
if Source <> Self then
|
|
begin
|
|
Control := TJvLinkedControl(Source).Control;
|
|
Options := TJvLinkedControl(Source).Options;
|
|
Changed(False);
|
|
end;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TJvLinkedControl.GetDisplayName: string;
|
|
begin
|
|
if Control <> nil then
|
|
Result := Control.Name
|
|
else
|
|
Result := inherited GetDisplayName;
|
|
end;
|
|
|
|
procedure TJvLinkedControl.SetControl(const Value: TControl);
|
|
begin
|
|
if FControl <> Value then
|
|
begin
|
|
if (FOwnerControl = nil) and (Collection is TJvLinkedControls) then
|
|
FOwnerControl := TJvLinkedControls(Collection).FControl;
|
|
if (Value = FOwnerControl) and (FOwnerControl <> nil) then
|
|
raise Exception.CreateRes(@RsEOwnerLinkError);
|
|
if Assigned(FControl) then
|
|
begin
|
|
if Assigned(FOwnerControl) then
|
|
FControl.RemoveFreeNotification(FOwnerControl);
|
|
if (Collection is TJvLinkedControls) and TJvLinkedControls(Collection).RestoreEnabled and
|
|
not (csDestroying in FControl.ComponentState) then
|
|
FControl.Enabled := FOriginalEnabled;
|
|
end;
|
|
if (FOwnerControl <> nil) and (csDestroying in FOwnerControl.ComponentState) then
|
|
FControl := nil
|
|
else
|
|
FControl := Value;
|
|
if Assigned(FControl) then
|
|
begin
|
|
FOriginalEnabled := FControl.Enabled;
|
|
if Assigned(FOwnerControl) then
|
|
FControl.FreeNotification(FOwnerControl);
|
|
end;
|
|
Changed(False);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvLinkedControl.SetOptions(const Value: TJvLinkedControlsOptions);
|
|
begin
|
|
if FOptions <> Value then
|
|
begin
|
|
FOptions := Value;
|
|
Changed(False);
|
|
end;
|
|
end;
|
|
|
|
//=== { TJvLinkedControls } ==================================================
|
|
|
|
constructor TJvLinkedControls.Create(AControl: TControl);
|
|
begin
|
|
inherited Create(AControl, TJvLinkedControl);
|
|
FControl := AControl;
|
|
FRestoreEnabled := True;
|
|
end;
|
|
|
|
function TJvLinkedControls.Add: TJvLinkedControl;
|
|
begin
|
|
Result := TJvLinkedControl(inherited Add);
|
|
Result.FOwnerControl := FControl;
|
|
end;
|
|
|
|
procedure TJvLinkedControls.Assign(Source: TPersistent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Source is TJvLinkedControls then
|
|
begin
|
|
if Source <> Self then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
Clear;
|
|
for I := 0 to TJvLinkedControls(Source).Count - 1 do
|
|
Add.Assign(TJvLinkedControls(Source)[I]);
|
|
RestoreEnabled := TJvLinkedControls(Source).RestoreEnabled;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TJvLinkedControls.GetItems(Index: Integer): TJvLinkedControl;
|
|
begin
|
|
Result := TJvLinkedControl(inherited Items[Index]);
|
|
end;
|
|
|
|
procedure TJvLinkedControls.Notification(AComponent: TComponent; Operation: TOperation);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (Operation = opRemove) and (AComponent is TControl) then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
for I := 0 to Count - 1 do
|
|
if Items[I].Control = AComponent then
|
|
Items[I].Control := nil;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvLinkedControls.SetItems(Index: Integer; const Value: TJvLinkedControl);
|
|
begin
|
|
inherited Items[Index] := Value;
|
|
end;
|
|
|
|
procedure TJvLinkedControls.Update(Item: TCollectionItem);
|
|
begin
|
|
inherited Update(Item);
|
|
if Item <> nil then
|
|
TJvLinkedControl(Item).FOwnerControl := FControl;
|
|
if Assigned(FOnChange) then
|
|
FOnChange(Self);
|
|
end;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
initialization
|
|
RegisterUnitVersion(HInstance, UnitVersioning);
|
|
|
|
finalization
|
|
UnregisterUnitVersion(HInstance);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
end.
|