Componentes.Terceros.DevExp.../internal/x.48/1/ExpressLibrary/Sources/cxPropEditors.pas
2010-01-18 18:37:26 +00:00

564 lines
18 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ Express Cross Platform Library classes }
{ }
{ Copyright (c) 2000-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSCROSSPLATFORMLIBRARY AND ALL }
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM }
{ ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{********************************************************************}
unit cxPropEditors;
interface
{$I cxVer.inc}
uses
{$IFDEF DELPHI6}
DesignIntf, DesignEditors, VCLEditors,
Types,
{$ELSE}
DsgnIntf,
{$ENDIF}
Windows, Messages, SysUtils, Classes, Graphics, Controls, TypInfo, cxContainer,
ImgList;
type
TcxNestedEventProperty = class(TMethodProperty)
protected
function GetInstance: TPersistent; virtual; abstract;
public
function GetAttributes: TPropertyAttributes; override;
function GetName: string; override;
procedure GetProperties(Proc: {$IFDEF DELPHI6}TGetPropProc{$ELSE}TGetPropEditProc{$ENDIF}); override;
function GetValue: string; override;
property Instance: TPersistent read GetInstance;
end;
TcxNestedParentElementEventProperty = class(TNestedProperty)
private
FOwner: TPersistent;
FPropInfo: PPropInfo;
FParent: TPropertyEditor;
function GetInstance: TPersistent;
protected
constructor Create(Parent: TPropertyEditor; AOwner: TPersistent; APropInfo: PPropInfo); reintroduce;
public
function GetAttributes: TPropertyAttributes; override;
procedure GetProperties(Proc: {$IFDEF DELPHI6}TGetPropProc{$ELSE}TGetPropEditProc{$ENDIF}); override;
function GetValue: string; override;
function GetName: string; override;
property Instance: TPersistent read GetInstance;
end;
TcxNestedElementEventProperty = class(TNestedProperty)
private
FParent: TPropertyEditor;
FPropInfo: PPropInfo;
function GetTrimmedEventName: string;
function GetPersistentClassNames: string;
function GetInstance: TPersistent;
protected
constructor Create(Parent: TPropertyEditor; APropInfo: PPropInfo); reintroduce;
function GetFormMethodName: string; virtual;
property Instance: TPersistent read GetInstance;
public
function AllEqual: Boolean; override;
procedure Edit; override;
function GetAttributes: TPropertyAttributes; override;
function GetEditLimit: Integer; override;
function GetName: string; override;
function GetValue: string; override;
procedure GetValues(Proc: TGetStrProc); override;
procedure SetValue(const AValue: string); override;
end;
{ TImageIndexProperty }
TImageIndexProperty = class(TIntegerProperty{$IFDEF DELPHI6}, ICustomPropertyListDrawing{$ENDIF})
public
function GetImages: TCustomImageList; virtual; abstract;
function GetAttributes: TPropertyAttributes; override;
function GetValue: string; override;
procedure GetValues(Proc: TGetStrProc); override;
procedure SetValue(const Value: string); override;
procedure ListMeasureHeight(const Value: string; ACanvas: TCanvas;
var AHeight: Integer); {$IFDEF DELPHI6}virtual{$ELSE}override{$ENDIF};
procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas;
var AWidth: Integer); {$IFDEF DELPHI6}virtual{$ELSE}override{$ENDIF};
procedure ListDrawValue(const Value: string; ACanvas: TCanvas;
const ARect: TRect; ASelected: Boolean); {$IFDEF DELPHI6}virtual{$ELSE}override{$ENDIF};
end;
{ TcxStyleControllerStyleProperty }
TcxStyleControllerStyleProperty = class(TClassProperty)
private
FProc: {$IFNDEF DELPHI6}TGetPropEditProc{$ELSE}TGetPropProc{$ENDIF};
procedure GetPropProc({$IFNDEF DELPHI6}Prop: TPropertyEditor{$ELSE}const Prop: IProperty{$ENDIF});
protected
function GetStyle: TcxContainerStyle; virtual;
function IsPropertyVisible(const APropertyName: string): Boolean; virtual;
public
procedure GetProperties(Proc: {$IFNDEF DELPHI6}TGetPropEditProc{$ELSE}TGetPropProc{$ENDIF}); override;
end;
procedure ObjectInspectorCollapseProperty;
implementation
uses
{$IFDEF DELPHI6}
DesignConst,
{$ELSE}
Consts,
{$ENDIF}
cxClasses, dxCore;
function EnumChildProc(WND: HWND; LParam: Integer): BOOL; stdcall
var
AName: array[0..255] of Char;
const
S: string = 'TPropSelection';
begin
Result := True;
if (GetClassName(WND, @AName[0], 255) <> 0) and (AName = S) then
begin
SendMessage(WND, WM_CHAR, $2D, $4A0001);
InvalidateRect(WND, nil, True);
SendMessage(GetParent(WND), WM_SIZE, 0, 0);
end;
end;
function EnumWnd(WND: HWND; LParam: Integer): BOOL; stdcall;
begin
Result := True;
EnumChildWindows(WND, @EnumChildProc, 0);
end;
procedure ObjectInspectorCollapseProperty;
begin
EnumWindows(@EnumWnd, 0);
end;
function cxNestedEventProperty_GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paSubProperties, paReadOnly, paRevertable];
end;
procedure cxNestedEventProperty_GetProperties(APropertyEditor: TPropertyEditor;
AInstance: TPersistent; Proc: {$IFDEF DELPHI6}TGetPropProc{$ELSE}TGetPropEditProc{$ENDIF});
var
APropList: TPropList;
I, ACount : Integer;
AClassType: TClass;
begin
if AInstance = nil then Exit;
ACount := GetPropList(AInstance.ClassInfo, [tkMethod], @APropList);
for I := 0 to ACount - 1 do
Proc(TcxNestedElementEventProperty.Create(APropertyEditor, APropList[I]));
ACount := GetPropList(AInstance.ClassInfo, [tkClass], @APropList);
for I := 0 to ACount - 1 do
begin
AClassType := GetTypeData(APropList[I].PropType^).ClassType;
if not AClassType.InheritsFrom(TComponent) and AClassType.InheritsFrom(TPersistent) and
(GetPropList(AClassType.ClassInfo, [tkMethod], nil) <> 0) then
Proc(TcxNestedParentElementEventProperty.Create(APropertyEditor, AInstance, APropList[I]));
end;
end;
function cxNestedEventProperty_GetValue(AInstance: TPersistent): string;
begin
if AInstance = nil then
Result := '(None)'
else
Result := '(' + AInstance.ClassName + ')';
end;
{ TcxNestedEventProperty }
function TcxNestedEventProperty.GetAttributes: TPropertyAttributes;
begin
Result := cxNestedEventProperty_GetAttributes;
end;
function TcxNestedEventProperty.GetName: string;
begin
Result := inherited GetName;
Result := Copy(Result, 1, Pos('Events', Result) - 1);
end;
procedure TcxNestedEventProperty.GetProperties(Proc: {$IFDEF DELPHI6}TGetPropProc{$ELSE}TGetPropEditProc{$ENDIF});
begin
cxNestedEventProperty_GetProperties(Self, Instance, Proc);
end;
function TcxNestedEventProperty.GetValue: string;
begin
Result := cxNestedEventProperty_GetValue(Instance);
end;
{ TcxNestedParentElementEventProperty }
constructor TcxNestedParentElementEventProperty.Create(Parent: TPropertyEditor;
AOwner: TPersistent; APropInfo: PPropInfo);
begin
inherited Create(Parent);
FParent := Parent;
FOwner := AOwner;
FPropInfo := APropInfo;
end;
function TcxNestedParentElementEventProperty.GetInstance: TPersistent;
begin
{$IFNDEF DELPHI5}
Result := TPersistent(GetOrdProp(FOwner, FPropInfo))
{$ELSE}
Result := TPersistent(GetObjectProp(FOwner, FPropInfo));
{$ENDIF}
end;
function TcxNestedParentElementEventProperty.GetAttributes: TPropertyAttributes;
begin
Result := cxNestedEventProperty_GetAttributes;
end;
procedure TcxNestedParentElementEventProperty.GetProperties(Proc: {$IFDEF DELPHI6}TGetPropProc{$ELSE}TGetPropEditProc{$ENDIF});
begin
cxNestedEventProperty_GetProperties(Self, Instance, Proc);
end;
function TcxNestedParentElementEventProperty.GetValue: string;
begin
Result := cxNestedEventProperty_GetValue(Instance);
end;
function TcxNestedParentElementEventProperty.GetName: string;
begin
Result := dxShortStringToString(FPropInfo.Name);
end;
{ TNestedElementEventProperty }
constructor TcxNestedElementEventProperty.Create(Parent: TPropertyEditor; APropInfo: PPropInfo);
begin
inherited Create(Parent);
FPropInfo := APropInfo;
FParent := Parent;
end;
function TcxNestedElementEventProperty.AllEqual: Boolean;
var
I: Integer;
V, T: TMethod;
begin
Result := False;
if PropCount > 1 then
begin
V := GetMethodValue;
for I := 1 to PropCount - 1 do
begin
T := GetMethodValueAt(I);
if (T.Code <> V.Code) or (T.Data <> V.Data) then Exit;
end;
end;
Result := True;
end;
procedure TcxNestedElementEventProperty.Edit;
var
FormMethodName: string;
begin
FormMethodName := GetValue;
if (FormMethodName = '') or
Designer.MethodFromAncestor(GetMethodValue) then
begin
if FormMethodName = '' then
FormMethodName := GetFormMethodName;
if FormMethodName = '' then
raise EPropertyError.Create(SCannotCreateName);
SetValue(FormMethodName);
end;
Designer.ShowMethod(FormMethodName);
end;
function TcxNestedElementEventProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paValueList, paSortList, paRevertable];
end;
function TcxNestedElementEventProperty.GetEditLimit: Integer;
begin
Result := MaxIdentLength;
end;
function TcxNestedElementEventProperty.GetName: string;
begin
Result := dxShortStringToString(FPropInfo.Name);
end;
function TcxNestedElementEventProperty.GetValue: string;
begin
Result := Designer.GetMethodName(GetMethodProp(Instance, FPropInfo));
end;
procedure TcxNestedElementEventProperty.GetValues(Proc: TGetStrProc);
begin
Designer.GetMethods(GetTypeData(FPropInfo.PropType^), Proc);
end;
procedure TcxNestedElementEventProperty.SetValue(const AValue: string);
{$IFDEF DELPHI5}
procedure CheckChainCall(const MethodName: string; Method: TMethod);
var
Persistent: TPersistent;
Component: TComponent;
InstanceMethod: string;
Instance: TComponent;
begin
Persistent := GetComponent(0);
if Persistent is TComponent then
begin
Component := TComponent(Persistent);
if (Component.Name <> '') and (Method.Data <> Designer.GetRoot) and
(TObject(Method.Data) is TComponent) then
begin
Instance := TComponent(Method.Data);
InstanceMethod := Instance.MethodName(Method.Code);
if InstanceMethod <> '' then
Designer.ChainCall(MethodName, Instance.Name, InstanceMethod,
GetTypeData(GetPropType));
end;
end;
end;
{$ENDIF}
var
NewMethod: Boolean;
CurValue: string;
OldMethod: TMethod;
begin
CurValue:= GetValue;
if (CurValue <> '') and (AValue <> '') and ((CompareText(CurValue, AValue) = 0) or
not Designer.MethodExists(AValue)) and not Designer.MethodFromAncestor(GetMethodValue) then
Designer.RenameMethod(CurValue, AValue)
else
begin
NewMethod := (AValue <> '') and not Designer.MethodExists(AValue);
OldMethod := GetMethodValue;
SetMethodProp(Instance, FPropInfo,
Designer.CreateMethod(AValue, GetTypeData(FPropInfo.PropType^)));
if NewMethod then
begin
{$IFDEF DELPHI5}
if (PropCount = 1) and (OldMethod.Data <> nil) and (OldMethod.Code <> nil) then
CheckChainCall(AValue, OldMethod);
{$ENDIF}
Designer.ShowMethod(AValue);
end;
Designer.Modified;
end;
end;
function TcxNestedElementEventProperty.GetFormMethodName: string;
var
I: Integer;
begin
if GetComponent(0) = Designer.GetRoot then
begin
{$IFNDEF DELPHI5}
if Designer.GetRoot <> nil then
Result := Designer.GetRoot.ClassName
else Result := '';
{$ELSE}
Result := Designer.GetRootClassName;
{$ENDIF}
if (Result <> '') and (Result[1] = 'T') then
Delete(Result, 1, 1);
end
else
begin
Result := Designer.GetObjectName(GetComponent(0));
for I := Length(Result) downto 1 do
if dxCharInSet(Result[I], ['.','[',']','-','>']) then
Delete(Result, I, 1);
end;
if Result = '' then
raise EPropertyError.Create(SCannotCreateName);
Result := Result + GetPersistentClassNames + GetTrimmedEventName;
end;
function TcxNestedElementEventProperty.GetTrimmedEventName: string;
begin
Result := GetName;
if (Length(Result) >= 2) and dxCharInSet(Result[1], ['O', 'o']) and
dxCharInSet(Result[2], ['N', 'n']) then
Delete(Result, 1, 2);
end;
function TcxNestedElementEventProperty.GetPersistentClassNames: string;
var
APropertyEditor: TPropertyEditor;
begin
Result := '';
APropertyEditor := self;
while APropertyEditor <> nil do
begin
if APropertyEditor is TcxNestedParentElementEventProperty then
APropertyEditor := TcxNestedParentElementEventProperty(APropertyEditor).FParent
else
if APropertyEditor is TcxNestedElementEventProperty then
APropertyEditor := TcxNestedElementEventProperty(APropertyEditor).FParent
else APropertyEditor := nil;
if APropertyEditor <> nil then
Result := APropertyEditor.GetName + Result;
end;
end;
function TcxNestedElementEventProperty.GetInstance: TPersistent;
begin
Result := nil;
if FParent is TcxNestedEventProperty then
Result := TcxNestedEventProperty(FParent).Instance;
if FParent is TcxNestedParentElementEventProperty then
Result := TcxNestedParentElementEventProperty(FParent).Instance;
end;
{ TImageIndexProperty }
function TImageIndexProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paValueList, paRevertable];
end;
function TImageIndexProperty.GetValue: string;
begin
Result := IntToStr(GetOrdValue);
end;
procedure TImageIndexProperty.GetValues(Proc: TGetStrProc);
var
I: Integer;
begin
Proc('-1');
if GetImages <> nil then
for I := 0 to GetImages.Count - 1 do Proc(IntToStr(I));
end;
procedure TImageIndexProperty.ListDrawValue(const Value: string;
ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean);
var
AImageWidth: Integer;
begin
with ACanvas do
begin
if GetImages <> nil then
begin
FillRect(ARect);
if ASelected then DrawFocusRect(ARect);
AImageWidth := GetImages.Width + 2 * 2;
GetImages.Draw(ACanvas, ARect.Left + 2,
(ARect.Top + ARect.Bottom - GetImages.Height) div 2, StrToInt(Value));
end
else
AImageWidth := 0;
TextOut(ARect.Left + AImageWidth + 2,
(ARect.Top + ARect.Bottom - TextHeight(Value)) div 2, Value);
end;
end;
procedure TImageIndexProperty.ListMeasureHeight(const Value: string;
ACanvas: TCanvas; var AHeight: Integer);
var
AImageHeight, AStringHeight: Integer;
begin
if GetImages <> nil then
AImageHeight := GetImages.Height + 2 * 2
else
AImageHeight := 0;
AStringHeight := ACanvas.TextHeight(Value);
if AStringHeight > AImageHeight then
AHeight := AStringHeight
else
AHeight := AImageHeight;
end;
procedure TImageIndexProperty.ListMeasureWidth(const Value: string;
ACanvas: TCanvas; var AWidth: Integer);
var
AImageWidth, AStringWidth: Integer;
begin
if GetImages <> nil then
AImageWidth := GetImages.Width + 2 * 2
else
AImageWidth := 0;
AStringWidth := ACanvas.TextWidth(Value) + 2 * 2;
AWidth := AImageWidth + AStringWidth;
end;
procedure TImageIndexProperty.SetValue(const Value: string);
begin
SetOrdValue(StrToInt(Value));
end;
{ TcxStyleControllerStyleProperty }
procedure TcxStyleControllerStyleProperty.GetProperties(
Proc: {$IFNDEF DELPHI6}TGetPropEditProc{$ELSE}TGetPropProc{$ENDIF});
begin
FProc := Proc;
inherited GetProperties(GetPropProc);
end;
function TcxStyleControllerStyleProperty.GetStyle: TcxContainerStyle;
begin
Result := TcxStyleController(GetComponent(0)).Styles[csNormal];
end;
function TcxStyleControllerStyleProperty.IsPropertyVisible(
const APropertyName: string): Boolean;
begin
Result := not((GetName <> 'Style') and
not GetStyle.IsExtendedStylePropertyPublished(APropertyName));
end;
procedure TcxStyleControllerStyleProperty.GetPropProc(
{$IFNDEF DELPHI6}Prop: TPropertyEditor{$ELSE}const Prop: IProperty{$ENDIF});
begin
if IsPropertyVisible(Prop.GetName) then
FProc(Prop);
end;
end.