mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-28 04:33:48 +02:00
1299 lines
37 KiB
ObjectPascal
1299 lines
37 KiB
ObjectPascal
{
|
|
*****************************************************************************
|
|
* *
|
|
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
|
* for details about the copyright. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* *
|
|
*****************************************************************************
|
|
|
|
Author: Mattias Gaertner
|
|
|
|
Abstract:
|
|
This units defines the component editors used by the designer.
|
|
A Component Editor is a plugin used by the designer to add special
|
|
functions for component classes.
|
|
For more information see the big comment part below.
|
|
}
|
|
unit ComponentEditors;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LResources, TypInfo, LCLProc, Forms, Controls, Menus,
|
|
ExtCtrls, CustomTimer, StdCtrls, Graphics, Grids, CheckLst, Buttons, ComCtrls, Dialogs,
|
|
LazStringGridEdit, CheckListboxEditorDlg, CheckGroupEditorDlg, GraphType,
|
|
PropEdits, PropEditUtils,
|
|
ObjInspStrConsts;
|
|
|
|
type
|
|
{ TComponentEditorDesigner }
|
|
|
|
TComponentPasteSelectionFlag = (
|
|
cpsfReplace,
|
|
cpsfFindUniquePositions
|
|
);
|
|
TComponentPasteSelectionFlags = set of TComponentPasteSelectionFlag;
|
|
TComponentEditorDesignerHookType = (
|
|
cedhtModified
|
|
);
|
|
|
|
TComponentEditorDesigner = class(TIDesigner)
|
|
private
|
|
FChangeStamp: int64;
|
|
protected
|
|
FForm: TCustomForm;
|
|
FHandlers: array[TComponentEditorDesignerHookType] of TMethodList;
|
|
function GetPropertyEditorHook: TPropertyEditorHook; virtual; abstract;
|
|
function GetHandlerCount(HookType: TComponentEditorDesignerHookType): integer;
|
|
procedure AddHandler(HookType: TComponentEditorDesignerHookType; const Handler: TMethod);
|
|
procedure RemoveHandler(HookType: TComponentEditorDesignerHookType; const Handler: TMethod);
|
|
public
|
|
destructor Destroy; override;
|
|
procedure Modified; override;
|
|
function CopySelection: boolean; virtual; abstract;
|
|
function CutSelection: boolean; virtual; abstract;
|
|
function CanPaste: boolean; virtual; abstract;
|
|
function PasteSelection(Flags: TComponentPasteSelectionFlags): boolean; virtual; abstract;
|
|
function DeleteSelection: boolean; virtual; abstract;
|
|
function CopySelectionToStream(s: TStream): boolean; virtual; abstract;
|
|
function InsertFromStream(s: TStream; Parent: TWinControl;
|
|
Flags: TComponentPasteSelectionFlags
|
|
): Boolean; virtual; abstract;
|
|
function InvokeComponentEditor(AComponent: TComponent;
|
|
MenuIndex: integer): boolean; virtual; abstract;
|
|
|
|
procedure DrawDesignerItems(OnlyIfNeeded: boolean); virtual; abstract;
|
|
function CreateUniqueComponentName(const AClassName: string
|
|
): string; virtual; abstract;
|
|
property PropertyEditorHook: TPropertyEditorHook read GetPropertyEditorHook;
|
|
property Form: TCustomForm read FForm;
|
|
property ChangeStamp: int64 read FChangeStamp;// increased on calling Modified
|
|
public
|
|
// Handlers
|
|
procedure RemoveAllHandlersForObject(const HandlerObject: TObject);
|
|
procedure AddHandlerModified(const OnModified: TNotifyEvent);
|
|
procedure RemoveHandlerModified(const OnModified: TNotifyEvent);
|
|
end;
|
|
|
|
|
|
{ Component Editor Types }
|
|
|
|
type
|
|
|
|
{ TComponentEditor
|
|
A component editor is created for each component that is selected in the
|
|
form designer based on the component's type (see GetComponentEditor and
|
|
RegisterComponentEditor). When the component is double-clicked the Edit
|
|
method is called. When the context menu for the component is invoked the
|
|
GetVerbCount and GetVerb methods are called to build the menu. If one
|
|
of the verbs are selected, ExecuteVerb is called. Paste is called whenever
|
|
the component is pasted to the clipboard. You only need to create a
|
|
component editor if you wish to add verbs to the context menu, change
|
|
the default double-click behavior, or paste an additional clipboard format.
|
|
The default component editor (TDefaultEditor) implements Edit to searches the
|
|
properties of the component and generates (or navigates to) the OnCreate,
|
|
OnChanged, or OnClick event (whichever it finds first). Whenever the
|
|
component editor modifies the component, it *must* call Designer.Modified to
|
|
inform the designer that the form has been modified. (Or else the user can not
|
|
save the changes).
|
|
|
|
Edit
|
|
Called when the user double-clicks the component. The component editor can
|
|
bring up a dialog in response to this method, for example, or some kind
|
|
of design expert. If GetVerbCount is greater than zero, edit will execute
|
|
the first verb in the list (ExecuteVerb(0)).
|
|
|
|
ExecuteVerb(Index)
|
|
The Index'ed verb was selected by the use off the context menu. The
|
|
meaning of this is determined by component editor.
|
|
|
|
GetVerb
|
|
The component editor should return a string that will be displayed in the
|
|
context menu. It is the responsibility of the component editor to place
|
|
the & character and the '...' characters as appropriate.
|
|
|
|
GetVerbCount
|
|
The number of valid indices to GetVerb and Execute verb. The index is
|
|
assumed to be zero based (i.e. 0..GetVerbCount - 1).
|
|
|
|
PrepareItem
|
|
While constructing the context menu PrepareItem will be called for
|
|
each verb. It will be passed the menu item that will be used to represent
|
|
the verb. The component editor can customize the menu item as it sees fit,
|
|
including adding subitems. If you don't want that particular menu item
|
|
to be shown, don't free it, simply set its Visible property to False.
|
|
|
|
Copy
|
|
Called when the component is being copied to the clipboard. The
|
|
component's filed image is already on the clipboard. This gives the
|
|
component editor a chance to paste a different type of format which is
|
|
ignored by the designer but might be recognized by another application.
|
|
|
|
IsInInlined
|
|
Determines whether Component is in the Designer which owns it.
|
|
Essentially, Components should not be able to be added to a Frame
|
|
instance (collections are fine though) so this function checks to
|
|
determine whether the currently selected component is within a Frame
|
|
instance or not.
|
|
|
|
GetComponent
|
|
Returns the edited component.
|
|
|
|
GetDesigner
|
|
Returns the current Designer for the form owning the component.
|
|
}
|
|
|
|
{ TComponentEditor
|
|
All component editors are assumed derived from TBaseComponentEditor.
|
|
|
|
Create(AComponent, ADesigner)
|
|
Called to create the component editor. AComponent is the component to
|
|
be edited by the editor. ADesigner is an interface to the designer to
|
|
find controls and create methods (this is not used often). If a component
|
|
editor modifies the component in any way it *must* call
|
|
ADesigner.Modified. }
|
|
|
|
TBaseComponentEditor = class
|
|
protected
|
|
public
|
|
constructor Create(AComponent: TComponent;
|
|
ADesigner: TComponentEditorDesigner); virtual;
|
|
procedure Edit; virtual; abstract;
|
|
procedure ExecuteVerb(Index: Integer); virtual; abstract;
|
|
function GetVerb(Index: Integer): string; virtual; abstract;
|
|
function GetVerbCount: Integer; virtual; abstract;
|
|
procedure PrepareItem(Index: Integer; const AnItem: TMenuItem); virtual; abstract;
|
|
procedure Copy; virtual; abstract;
|
|
function IsInInlined: Boolean; virtual; abstract;
|
|
function GetComponent: TComponent; virtual; abstract;
|
|
function GetDesigner: TComponentEditorDesigner; virtual; abstract;
|
|
function GetHook(out Hook: TPropertyEditorHook): boolean; virtual; abstract;
|
|
procedure Modified; virtual; abstract;
|
|
end;
|
|
|
|
TComponentEditorClass = class of TBaseComponentEditor;
|
|
|
|
|
|
{ TComponentEditor
|
|
This class provides a default implementation for the IComponentEditor
|
|
interface. There is no assumption by the designer that you use this class
|
|
only that your class derive from TBaseComponentEditor and implement
|
|
IComponentEditor. This class is provided to help you implement a class
|
|
that meets those requirements. }
|
|
TComponentEditor = class(TBaseComponentEditor)
|
|
private
|
|
FComponent: TComponent;
|
|
FDesigner: TComponentEditorDesigner;
|
|
public
|
|
constructor Create(AComponent: TComponent;
|
|
ADesigner: TComponentEditorDesigner); override;
|
|
procedure Edit; override;
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
function GetComponent: TComponent; override;
|
|
function GetDesigner: TComponentEditorDesigner; override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
function GetVerbCount: Integer; override;
|
|
function IsInInlined: Boolean; override;
|
|
procedure Copy; override;
|
|
procedure PrepareItem(Index: Integer; const AnItem: TMenuItem); override;
|
|
property Component: TComponent read FComponent;
|
|
property Designer: TComponentEditorDesigner read GetDesigner;
|
|
function GetHook(out Hook: TPropertyEditorHook): boolean; override;
|
|
function HasHook: boolean;
|
|
procedure Modified; override;
|
|
end;
|
|
|
|
|
|
{ TDefaultComponentEditor
|
|
An editor that provides default behavior for the double-click that will
|
|
iterate through the properties looking for the most appropriate method
|
|
property to edit }
|
|
TDefaultComponentEditor = class(TComponentEditor)
|
|
private
|
|
FBestEditEvent: string;
|
|
FFirst: TPropertyEditor;
|
|
FBest: TPropertyEditor;
|
|
FContinue: Boolean;
|
|
FPropEditCandidates: TList; // list of TPropertyEditor
|
|
procedure CheckEdit(Prop: TPropertyEditor);
|
|
protected
|
|
procedure EditProperty(const Prop: TPropertyEditor;
|
|
var Continue: Boolean); virtual;
|
|
procedure ClearPropEditorCandidates;
|
|
public
|
|
constructor Create(AComponent: TComponent;
|
|
ADesigner: TComponentEditorDesigner); override;
|
|
destructor Destroy; override;
|
|
procedure Edit; override;
|
|
function GetVerbCount: Integer; override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
property BestEditEvent: string read FBestEditEvent write FBestEditEvent;
|
|
end;
|
|
|
|
// to be "compatible" with delphi i've added the next line.
|
|
// we're not 100% the same, but it might help some ppl.
|
|
TDefaultEditor = TDefaultComponentEditor;
|
|
|
|
{ TNotebookComponentEditor
|
|
The default component editor for TCustomNotebook. }
|
|
TNotebookComponentEditor = class(TDefaultComponentEditor)
|
|
protected
|
|
procedure AddNewPageToDesigner(Index: integer); virtual;
|
|
procedure DoAddPage; virtual;
|
|
procedure DoInsertPage; virtual;
|
|
procedure DoDeletePage; virtual;
|
|
procedure DoMoveActivePageLeft; virtual;
|
|
procedure DoMoveActivePageRight; virtual;
|
|
procedure DoMovePage(CurIndex, NewIndex: Integer); virtual;
|
|
procedure AddMenuItemsForPages(ParentMenuItem: TMenuItem); virtual;
|
|
procedure ShowPageMenuItemClick(Sender: TObject);
|
|
public
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
function GetVerbCount: Integer; override;
|
|
procedure PrepareItem(Index: Integer; const AnItem: TMenuItem); override;
|
|
function Notebook: TCustomNotebook; virtual;
|
|
end;
|
|
|
|
|
|
{ TPageComponentEditor
|
|
The default component editor for TCustomPage. }
|
|
TPageComponentEditor = class(TNotebookComponentEditor)
|
|
protected
|
|
public
|
|
function Notebook: TCustomNotebook; override;
|
|
function Page: TCustomPage; virtual;
|
|
end;
|
|
|
|
|
|
{ TTabControlComponentEditor
|
|
The default component editor for TCustomTabControl. }
|
|
TTabControlComponentEditor = class(TDefaultComponentEditor)
|
|
protected
|
|
procedure DoAddTab; virtual;
|
|
procedure DoInsertTab; virtual;
|
|
procedure DoDeleteTab; virtual;
|
|
procedure DoMoveActiveTabLeft; virtual;
|
|
procedure DoMoveActiveTabRight; virtual;
|
|
procedure DoMoveTab(CurIndex, NewIndex: Integer); virtual;
|
|
procedure AddMenuItemsForTabs(ParentMenuItem: TMenuItem); virtual;
|
|
procedure ShowTabMenuItemClick(Sender: TObject);
|
|
function CreateNewTabCaption: string;
|
|
public
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
function GetVerbCount: Integer; override;
|
|
procedure PrepareItem(Index: Integer; const AnItem: TMenuItem); override;
|
|
function TabControl: TCustomTabControl; virtual;
|
|
end;
|
|
|
|
|
|
{ TStringGridComponentEditor
|
|
The default componenteditor for TStringGrid }
|
|
|
|
TStringGridComponentEditor = class(TComponentEditor)
|
|
public
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
function GetVerbCount: Integer; override;
|
|
end;
|
|
|
|
{ TCheckListBoxComponentEditor
|
|
The default componenteditor for TCheckListBox }
|
|
|
|
TCheckListBoxComponentEditor = class(TComponentEditor)
|
|
protected
|
|
procedure DoShowEditor;
|
|
public
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
function GetVerbCount: Integer; override;
|
|
end;
|
|
|
|
|
|
{ TCheckGroupComponentEditor
|
|
The default componenteditor for TCheckGroup }
|
|
|
|
TCheckGroupComponentEditor = class(TDefaultComponentEditor)
|
|
protected
|
|
procedure DoShowEditor;
|
|
public
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
function GetVerbCount: Integer; override;
|
|
end;
|
|
|
|
|
|
{ TToolBarComponentEditor
|
|
The default componenteditor for TToolBar }
|
|
|
|
TToolBarComponentEditor = class(TDefaultComponentEditor)
|
|
protected
|
|
public
|
|
procedure ExecuteVerb(Index: Integer); override;
|
|
function GetVerb(Index: Integer): string; override;
|
|
function GetVerbCount: Integer; override;
|
|
function ToolBar: TToolBar; virtual;
|
|
end;
|
|
|
|
|
|
{ TFileDialogComponentEditor
|
|
The default componenteditor for TFileDialog }
|
|
|
|
TCommonDialogComponentEditor = class(TComponentEditor)
|
|
private
|
|
procedure TestDialog;
|
|
public
|
|
function GetVerbCount:integer;override;
|
|
function GetVerb(Index:integer):string;override;
|
|
procedure ExecuteVerb(Index:integer);override;
|
|
end;
|
|
|
|
{ TTimerComponentEditor }
|
|
|
|
TTimerComponentEditor = class(TDefaultComponentEditor)
|
|
public
|
|
constructor Create(AComponent: TComponent;
|
|
ADesigner: TComponentEditorDesigner); override;
|
|
end;
|
|
|
|
|
|
{ Register a component editor }
|
|
type
|
|
TRegisterComponentEditorProc =
|
|
procedure (ComponentClass: TComponentClass;
|
|
ComponentEditor: TComponentEditorClass);
|
|
|
|
var
|
|
RegisterComponentEditorProc: TRegisterComponentEditorProc;
|
|
|
|
|
|
procedure RegisterComponentEditor(ComponentClass: TComponentClass;
|
|
ComponentEditor: TComponentEditorClass);
|
|
function GetComponentEditor(Component: TComponent;
|
|
const Designer: TComponentEditorDesigner): TBaseComponentEditor;
|
|
|
|
type
|
|
TPropertyEditorFilterFunc =
|
|
function(const ATestEditor: TPropertyEditor): Boolean of object;
|
|
|
|
|
|
implementation
|
|
|
|
{ RegisterComponentEditor }
|
|
type
|
|
PComponentClassRec = ^TComponentClassRec;
|
|
TComponentClassRec = record
|
|
Group: Integer;
|
|
ComponentClass: TComponentClass;
|
|
EditorClass: TComponentEditorClass;
|
|
end;
|
|
|
|
const
|
|
ComponentClassList: TList = nil;
|
|
|
|
procedure DefaultRegisterComponentEditorProc(ComponentClass: TComponentClass;
|
|
ComponentEditor: TComponentEditorClass);
|
|
var
|
|
P: PComponentClassRec;
|
|
begin
|
|
if ComponentClassList = nil then
|
|
ComponentClassList := TList.Create;
|
|
New(P);
|
|
P^.Group := -1;//CurrentGroup;
|
|
P^.ComponentClass := ComponentClass;
|
|
P^.EditorClass := ComponentEditor;
|
|
ComponentClassList.Insert(0, P);
|
|
end;
|
|
|
|
procedure RegisterComponentEditor(ComponentClass: TComponentClass;
|
|
ComponentEditor: TComponentEditorClass);
|
|
begin
|
|
if Assigned(RegisterComponentEditorProc) then
|
|
RegisterComponentEditorProc(ComponentClass, ComponentEditor);
|
|
end;
|
|
|
|
function GetComponentEditor(Component: TComponent;
|
|
const Designer: TComponentEditorDesigner): TBaseComponentEditor;
|
|
var
|
|
P: PComponentClassRec;
|
|
I: Integer;
|
|
ComponentClass: TComponentClass;
|
|
EditorClass: TComponentEditorClass;
|
|
begin
|
|
ComponentClass := TComponentClass(TPersistent);
|
|
EditorClass := TDefaultComponentEditor;
|
|
if ComponentClassList <> nil then
|
|
for I := 0 to ComponentClassList.Count-1 do
|
|
begin
|
|
P := PComponentClassRec(ComponentClassList[I]);
|
|
//DebugLn('GetComponentEditor Component=',dbgsName(Component),' ',dbgsName(P^.ComponentClass),' ',dbgsName(P^.EditorClass));
|
|
if (Component is P^.ComponentClass) and
|
|
(P^.ComponentClass <> ComponentClass) and
|
|
(P^.ComponentClass.InheritsFrom(ComponentClass)) then
|
|
begin
|
|
EditorClass := P^.EditorClass;
|
|
ComponentClass := P^.ComponentClass;
|
|
end;
|
|
end;
|
|
Result := EditorClass.Create(Component, Designer);
|
|
end;
|
|
|
|
{ Component Editors -----------------------------------------------------------}
|
|
|
|
|
|
{ TBaseComponentEditor }
|
|
|
|
constructor TBaseComponentEditor.Create(AComponent: TComponent;
|
|
ADesigner: TComponentEditorDesigner);
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
{ TComponentEditor }
|
|
|
|
constructor TComponentEditor.Create(AComponent: TComponent;
|
|
ADesigner: TComponentEditorDesigner);
|
|
begin
|
|
inherited Create(AComponent, ADesigner);
|
|
FComponent := AComponent;
|
|
FDesigner := ADesigner;
|
|
end;
|
|
|
|
procedure TComponentEditor.Edit;
|
|
begin
|
|
if GetVerbCount > 0 then ExecuteVerb(0);
|
|
end;
|
|
|
|
function TComponentEditor.GetComponent: TComponent;
|
|
begin
|
|
Result := FComponent;
|
|
end;
|
|
|
|
function TComponentEditor.GetDesigner: TComponentEditorDesigner;
|
|
begin
|
|
Result := FDesigner;
|
|
end;
|
|
|
|
function TComponentEditor.GetVerbCount: Integer;
|
|
begin
|
|
// Intended for descendents to implement
|
|
Result := 0;
|
|
end;
|
|
|
|
function TComponentEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
// Intended for descendents to implement
|
|
Result:=ClassName+IntToStr(Index);
|
|
end;
|
|
|
|
procedure TComponentEditor.ExecuteVerb(Index: Integer);
|
|
begin
|
|
// Intended for descendents to implement
|
|
DebugLn(Classname+'.ExecuteVerb: ',IntToStr(Index));
|
|
end;
|
|
|
|
procedure TComponentEditor.Copy;
|
|
begin
|
|
// Intended for descendents to implement
|
|
end;
|
|
|
|
function TComponentEditor.IsInInlined: Boolean;
|
|
begin
|
|
Result := csInline in Component.Owner.ComponentState;
|
|
end;
|
|
|
|
procedure TComponentEditor.PrepareItem(Index: Integer;
|
|
const AnItem: TMenuItem);
|
|
begin
|
|
// Intended for descendents to implement
|
|
end;
|
|
|
|
function TComponentEditor.GetHook(out Hook: TPropertyEditorHook): boolean;
|
|
begin
|
|
Result:=false;
|
|
Hook:=nil;
|
|
if GetDesigner=nil then exit;
|
|
Hook:=GetDesigner.PropertyEditorHook;
|
|
Result:=Hook<>nil;
|
|
end;
|
|
|
|
function TComponentEditor.HasHook: boolean;
|
|
var
|
|
Hook: TPropertyEditorHook;
|
|
begin
|
|
Result:=GetHook(Hook) and (Hook<>nil);
|
|
end;
|
|
|
|
procedure TComponentEditor.Modified;
|
|
begin
|
|
GetDesigner.Modified;
|
|
end;
|
|
|
|
{ TDefaultComponentEditor }
|
|
|
|
procedure TDefaultComponentEditor.CheckEdit(Prop: TPropertyEditor);
|
|
begin
|
|
if FContinue then
|
|
EditProperty(Prop, FContinue);
|
|
if FPropEditCandidates=nil then
|
|
FPropEditCandidates:=TList.Create;
|
|
FPropEditCandidates.Add(Prop);
|
|
end;
|
|
|
|
procedure TDefaultComponentEditor.EditProperty(const Prop: TPropertyEditor;
|
|
var Continue: Boolean);
|
|
var
|
|
PropName: string;
|
|
BestName: string;
|
|
|
|
procedure ReplaceBest;
|
|
begin
|
|
FBest := Prop;
|
|
if FFirst = FBest then
|
|
FFirst := nil;
|
|
end;
|
|
|
|
begin
|
|
if not Assigned(FFirst) and (Prop is TMethodPropertyEditor) then
|
|
FFirst := Prop;
|
|
PropName := Prop.GetName;
|
|
BestName := '';
|
|
if Assigned(FBest) then
|
|
BestName := FBest.GetName;
|
|
// event priority is hardcoded:
|
|
// first priority has OnCreate, then OnClick and OnChange is the last
|
|
if CompareText(PropName, FBestEditEvent) = 0 then
|
|
ReplaceBest
|
|
else
|
|
if CompareText(BestName, FBestEditEvent) <> 0 then
|
|
if CompareText(PropName, 'ONCHANGE') = 0 then
|
|
ReplaceBest
|
|
else
|
|
if CompareText(BestName, 'ONCHANGE') <> 0 then
|
|
if CompareText(PropName, 'ONCLICK') = 0 then
|
|
ReplaceBest;
|
|
end;
|
|
|
|
procedure TDefaultComponentEditor.ClearPropEditorCandidates;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if FPropEditCandidates=nil then exit;
|
|
for i:=0 to FPropEditCandidates.Count-1 do
|
|
TObject(FPropEditCandidates[i]).Free;
|
|
FPropEditCandidates.Free;
|
|
FPropEditCandidates:=nil;
|
|
end;
|
|
|
|
constructor TDefaultComponentEditor.Create(AComponent: TComponent;
|
|
ADesigner: TComponentEditorDesigner);
|
|
begin
|
|
inherited Create(AComponent, ADesigner);
|
|
FBestEditEvent:='OnCreate';
|
|
end;
|
|
|
|
destructor TDefaultComponentEditor.Destroy;
|
|
begin
|
|
ClearPropEditorCandidates;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TDefaultComponentEditor.Edit;
|
|
var
|
|
PropertyEditorHook: TPropertyEditorHook;
|
|
NewLookupRoot: TPersistent;
|
|
begin
|
|
PropertyEditorHook:=nil;
|
|
if not GetHook(PropertyEditorHook) then exit;
|
|
NewLookupRoot:=GetLookupRootForComponent(Component);
|
|
if not (NewLookupRoot is TComponent) then exit;
|
|
if NewLookupRoot<>PropertyEditorHook.LookupRoot then
|
|
GetDesigner.SelectOnlyThisComponent(Component);
|
|
FContinue := True;
|
|
FFirst := nil;
|
|
FBest := nil;
|
|
try
|
|
GetPersistentProperties(Component,tkAny,PropertyEditorHook,@CheckEdit,nil);
|
|
if FContinue
|
|
then begin
|
|
if Assigned(FBest) then
|
|
FBest.Edit
|
|
else if Assigned(FFirst) then
|
|
FFirst.Edit;
|
|
end;
|
|
finally
|
|
FFirst := nil;
|
|
FBest := nil;
|
|
ClearPropEditorCandidates;
|
|
end;
|
|
end;
|
|
|
|
function TDefaultComponentEditor.GetVerbCount: Integer;
|
|
begin
|
|
Result:=1;
|
|
end;
|
|
|
|
function TDefaultComponentEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
Result:=oisCreateDefaultEvent;
|
|
end;
|
|
|
|
procedure TDefaultComponentEditor.ExecuteVerb(Index: Integer);
|
|
begin
|
|
Edit;
|
|
end;
|
|
|
|
|
|
{ TNotebookComponentEditor }
|
|
|
|
const
|
|
nbvAddPage = 0;
|
|
nbvInsertPage = 1;
|
|
nbvDeletePage = 2;
|
|
nbvMovePageLeft = 3;
|
|
nbvMovePageRight = 4;
|
|
nbvShowPage = 5;
|
|
|
|
procedure TNotebookComponentEditor.ShowPageMenuItemClick(Sender: TObject);
|
|
var
|
|
AMenuItem: TMenuItem;
|
|
NewPageIndex: integer;
|
|
begin
|
|
AMenuItem:=TMenuItem(Sender);
|
|
if (AMenuItem=nil) or (not (AMenuItem is TMenuItem)) then exit;
|
|
NewPageIndex:=AMenuItem.MenuIndex;
|
|
if (NewPageIndex<0) or (NewPageIndex>=Notebook.PageCount) then exit;
|
|
NoteBook.PageIndex:=NewPageIndex;
|
|
GetDesigner.SelectOnlyThisComponent(NoteBook.CustomPage(NoteBook.PageIndex));
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.AddNewPageToDesigner(Index: integer);
|
|
var
|
|
Hook: TPropertyEditorHook;
|
|
NewPage: TCustomPage;
|
|
NewName: string;
|
|
begin
|
|
Hook:=nil;
|
|
if not GetHook(Hook) then exit;
|
|
NewPage:=NoteBook.CustomPage(Index);
|
|
NewName:=GetDesigner.CreateUniqueComponentName(NewPage.ClassName);
|
|
NewPage.Caption:=NewName;
|
|
NewPage.Name:=NewName;
|
|
NoteBook.PageIndex:=Index;
|
|
Hook.PersistentAdded(NewPage,true);
|
|
Modified;
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.DoAddPage;
|
|
begin
|
|
if not HasHook then exit;
|
|
NoteBook.Pages.Add('');
|
|
AddNewPageToDesigner(NoteBook.PageCount-1);
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.DoInsertPage;
|
|
var
|
|
NewIndex: integer;
|
|
begin
|
|
if not HasHook then exit;
|
|
NewIndex:=Notebook.PageIndex;
|
|
if NewIndex<0 then NewIndex:=0;
|
|
Notebook.Pages.Insert(NewIndex,'');
|
|
AddNewPageToDesigner(NewIndex);
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.DoDeletePage;
|
|
var
|
|
Hook: TPropertyEditorHook;
|
|
OldIndex: integer;
|
|
PageComponent: TPersistent;
|
|
begin
|
|
OldIndex:=Notebook.PageIndex;
|
|
if (OldIndex>=0) and (OldIndex<Notebook.PageCount) then begin
|
|
if not GetHook(Hook) then exit;
|
|
PageComponent := TPersistent(NoteBook.Pages.Objects[OldIndex]);
|
|
Hook.DeletePersistent(PageComponent);
|
|
end;
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.DoMoveActivePageLeft;
|
|
var
|
|
Index: integer;
|
|
begin
|
|
Index:=NoteBook.PageIndex;
|
|
if (Index<0) then exit;
|
|
DoMovePage(Index,Index-1);
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.DoMoveActivePageRight;
|
|
var
|
|
Index: integer;
|
|
begin
|
|
Index:=NoteBook.PageIndex;
|
|
if (Index>=0)
|
|
and (Index>=NoteBook.PageCount-1) then exit;
|
|
DoMovePage(Index,Index+1);
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.DoMovePage(
|
|
CurIndex, NewIndex: Integer);
|
|
begin
|
|
NoteBook.Pages.Move(CurIndex,NewIndex);
|
|
Modified;
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.AddMenuItemsForPages(
|
|
ParentMenuItem: TMenuItem);
|
|
var
|
|
i: integer;
|
|
NewMenuItem: TMenuItem;
|
|
begin
|
|
ParentMenuItem.Enabled:=NoteBook.PageCount>0;
|
|
for i:=0 to NoteBook.PageCount-1 do begin
|
|
NewMenuItem:=TMenuItem.Create(ParentMenuItem);
|
|
NewMenuItem.Name:='ShowPage'+IntToStr(i);
|
|
NewMenuItem.Caption:=Notebook.CustomPage(i).Name+' "'+Notebook.Pages[i]+'"';
|
|
NewMenuItem.OnClick:=@ShowPageMenuItemClick;
|
|
ParentMenuItem.Add(NewMenuItem);
|
|
end;
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.ExecuteVerb(Index: Integer);
|
|
begin
|
|
case Index of
|
|
nbvAddPage: DoAddPage;
|
|
nbvInsertPage: DoInsertPage;
|
|
nbvDeletePage: DoDeletePage; // beware: this can free the editor itself
|
|
nbvMovePageLeft: DoMoveActivePageLeft;
|
|
nbvMovePageRight: DoMoveActivePageRight;
|
|
end;
|
|
end;
|
|
|
|
function TNotebookComponentEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
case Index of
|
|
nbvAddPage: Result:=nbcesAddPage;
|
|
nbvInsertPage: Result:=nbcesInsertPage;
|
|
nbvDeletePage: Result:=nbcesDeletePage;
|
|
nbvMovePageLeft: Result:=nbcesMovePageLeft;
|
|
nbvMovePageRight: Result:=nbcesMovePageRight;
|
|
nbvShowPage: Result:=nbcesShowPage;
|
|
else
|
|
Result:='';
|
|
end;
|
|
end;
|
|
|
|
function TNotebookComponentEditor.GetVerbCount: Integer;
|
|
begin
|
|
Result:=6;
|
|
end;
|
|
|
|
procedure TNotebookComponentEditor.PrepareItem(Index: Integer;
|
|
const AnItem: TMenuItem);
|
|
begin
|
|
inherited PrepareItem(Index, AnItem);
|
|
case Index of
|
|
nbvAddPage: ;
|
|
nbvInsertPage: AnItem.Enabled:=Notebook.PageIndex>=0;
|
|
nbvDeletePage: AnItem.Enabled:=Notebook.PageIndex>=0;
|
|
nbvMovePageLeft: AnItem.Enabled:=Notebook.PageIndex>0;
|
|
nbvMovePageRight: AnItem.Enabled:=Notebook.PageIndex<Notebook.PageCount-1;
|
|
nbvShowPage: AddMenuItemsForPages(AnItem);
|
|
end;
|
|
end;
|
|
|
|
function TNotebookComponentEditor.Notebook: TCustomNotebook;
|
|
begin
|
|
Result:=TCustomNotebook(GetComponent);
|
|
end;
|
|
|
|
{ TPageComponentEditor }
|
|
|
|
function TPageComponentEditor.Notebook: TCustomNotebook;
|
|
var
|
|
APage: TCustomPage;
|
|
begin
|
|
APage:=Page;
|
|
if (APage.Parent<>nil) and (APage.Parent is TCustomNoteBook) then
|
|
Result:=TCustomNoteBook(APage.Parent);
|
|
end;
|
|
|
|
function TPageComponentEditor.Page: TCustomPage;
|
|
begin
|
|
Result:=TCustomPage(GetComponent);
|
|
end;
|
|
|
|
|
|
function EditStringGrid(AStringGrid: TStringGrid): Boolean;
|
|
var
|
|
StringGridEditorDlg: TStringGridEditorDlg;
|
|
begin
|
|
StringGridEditorDlg := TStringGridEditorDlg.Create(Application);
|
|
try
|
|
StringGridEditorDlg.LoadFromGrid(AStringGrid);
|
|
if StringGridEditorDlg.ShowModal = mrOk then
|
|
begin
|
|
StringGridEditorDlg.SaveToGrid;
|
|
end;
|
|
Result := StringGridEditorDlg.Modified;
|
|
finally
|
|
StringGridEditorDlg.Free;
|
|
end;
|
|
end;
|
|
|
|
{ TStringGridComponentEditor }
|
|
|
|
procedure TStringGridComponentEditor.ExecuteVerb(Index: Integer);
|
|
var
|
|
Hook: TPropertyEditorHook;
|
|
begin
|
|
if Index = 0 then
|
|
begin
|
|
GetHook(Hook);
|
|
if EditStringGrid(GetComponent as TStringGrid) then
|
|
if Assigned(Hook) then
|
|
Hook.Modified(Self);
|
|
end;
|
|
end;
|
|
|
|
function TStringGridComponentEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
if Index = 0 then Result := sccsSGEdt
|
|
else Result := '';
|
|
end;
|
|
|
|
function TStringGridComponentEditor.GetVerbCount: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
{ TCheckListBoxComponentEditor }
|
|
|
|
procedure TCheckListBoxComponentEditor.DoShowEditor;
|
|
var
|
|
Dlg: TCheckListBoxEditorDlg;
|
|
begin
|
|
Dlg := TCheckListBoxEditorDlg.Create(nil);
|
|
try
|
|
if GetComponent is TCheckListBox then
|
|
begin
|
|
Dlg.aCheck := TCheckListBox(GetComponent);
|
|
if not HasHook then exit;
|
|
|
|
AssignCheckList(Dlg.FCheck, Dlg.aCheck);
|
|
|
|
//ShowEditor
|
|
if Dlg.ShowModal=mrOK then
|
|
begin
|
|
AssignCheckList(Dlg.aCheck, Dlg.FCheck);
|
|
Modified;
|
|
end;
|
|
if Dlg.Modified then
|
|
Modified;
|
|
end;
|
|
finally
|
|
Dlg.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCheckListBoxComponentEditor.ExecuteVerb(Index: Integer);
|
|
begin
|
|
DoShowEditor;
|
|
end;
|
|
|
|
function TCheckListBoxComponentEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
Result:=clbCheckListBoxEditor+'...';
|
|
end;
|
|
|
|
function TCheckListBoxComponentEditor.GetVerbCount: Integer;
|
|
begin
|
|
Result:=1;
|
|
end;
|
|
|
|
{ TCheckGroupEditorDlg }
|
|
|
|
procedure TCheckGroupComponentEditor.DoShowEditor;
|
|
var
|
|
Dlg: TCheckGroupEditorDlg;
|
|
begin
|
|
Dlg := TCheckGroupEditorDlg.Create(nil);
|
|
try
|
|
if GetComponent is TCheckGroup then
|
|
begin
|
|
Dlg.aCheck := TCheckGroup(GetComponent);
|
|
if not HasHook then exit;
|
|
|
|
AssignCheckGroup(Dlg.FCheck, Dlg.aCheck);
|
|
Dlg.ColumnsUpDown.Position := Dlg.aCheck.Columns;
|
|
//ShowEditor
|
|
if Dlg.ShowModal = mrOK then
|
|
begin
|
|
AssignCheckGroup(Dlg.aCheck, Dlg.FCheck);
|
|
Modified;
|
|
end;
|
|
if Dlg.Modified then
|
|
Modified;
|
|
end;
|
|
finally
|
|
Dlg.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCheckGroupComponentEditor.ExecuteVerb(Index: Integer);
|
|
begin
|
|
DoShowEditor;
|
|
end;
|
|
|
|
function TCheckGroupComponentEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
Result:=cgCheckGroupEditor+'...';
|
|
end;
|
|
|
|
function TCheckGroupComponentEditor.GetVerbCount: Integer;
|
|
begin
|
|
Result:=1;
|
|
end;
|
|
|
|
{ TToolBarComponentEditor }
|
|
|
|
procedure TToolBarComponentEditor.ExecuteVerb(Index: Integer);
|
|
var
|
|
NewStyle: TToolButtonStyle;
|
|
Hook: TPropertyEditorHook;
|
|
NewToolButton: TToolButton;
|
|
NewName: string;
|
|
CurToolBar: TToolBar;
|
|
SiblingButton: TToolButton;
|
|
begin
|
|
Hook:=nil;
|
|
if not GetHook(Hook) then exit;
|
|
case Index of
|
|
0: NewStyle := tbsButton;
|
|
1: NewStyle := tbsCheck;
|
|
2: NewStyle := tbsSeparator;
|
|
3: NewStyle := tbsDivider;
|
|
else
|
|
exit;
|
|
end;
|
|
CurToolBar := ToolBar;
|
|
NewToolButton := TToolButton.Create(CurToolBar.Owner);
|
|
NewName := GetDesigner.CreateUniqueComponentName(NewToolButton.ClassName);
|
|
NewToolButton.Caption := NewName;
|
|
NewToolButton.Name := NewName;
|
|
NewToolButton.Style := NewStyle;
|
|
if NewStyle = tbsDivider then
|
|
NewToolButton.Width := 3;
|
|
// position the button next to the last button
|
|
if CurToolBar.ButtonCount > 0 then
|
|
begin
|
|
SiblingButton := CurToolBar.Buttons[CurToolBar.ButtonCount - 1];
|
|
NewToolButton.SetBounds(SiblingButton.Left + SiblingButton.Width,
|
|
SiblingButton.Top, NewToolButton.Width, NewToolButton.Height);
|
|
end;
|
|
NewToolButton.Parent := CurToolBar;
|
|
Hook.PersistentAdded(NewToolButton, True);
|
|
Modified;
|
|
end;
|
|
|
|
function TToolBarComponentEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
case Index of
|
|
0: Result := 'New Button';
|
|
1: Result := 'New Checkbutton';
|
|
2: Result := 'New Separator';
|
|
3: Result := 'New Divider';
|
|
else
|
|
Result := '';
|
|
end;
|
|
end;
|
|
|
|
function TToolBarComponentEditor.GetVerbCount: Integer;
|
|
begin
|
|
Result := 4;
|
|
end;
|
|
|
|
function TToolBarComponentEditor.ToolBar: TToolBar;
|
|
begin
|
|
Result := TToolBar(GetComponent);
|
|
end;
|
|
|
|
{ TCommonDialogComponentEditor }
|
|
|
|
procedure TCommonDialogComponentEditor.TestDialog;
|
|
begin
|
|
with Component as TCommonDialog do Execute;
|
|
end;
|
|
|
|
function TCommonDialogComponentEditor.GetVerbCount: integer;
|
|
begin
|
|
Result:=1;
|
|
end;
|
|
|
|
function TCommonDialogComponentEditor.GetVerb(Index: integer): string;
|
|
begin
|
|
case Index of
|
|
0:Result:=oisTestDialog;
|
|
else
|
|
Result:=inherited GetVerb(Index);
|
|
end;
|
|
end;
|
|
|
|
procedure TCommonDialogComponentEditor.ExecuteVerb(Index: integer);
|
|
begin
|
|
case Index of
|
|
0:TestDialog;
|
|
else
|
|
inherited ExecuteVerb(Index);
|
|
end;
|
|
end;
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
procedure InternalFinal;
|
|
var
|
|
p: PComponentClassRec;
|
|
i: integer;
|
|
begin
|
|
if ComponentClassList<>nil then begin
|
|
for i:=0 to ComponentClassList.Count-1 do begin
|
|
p:=PComponentClassRec(ComponentClassList[i]);
|
|
Dispose(p);
|
|
end;
|
|
ComponentClassList.Free;
|
|
end;
|
|
end;
|
|
|
|
{ TTabControlComponentEditor }
|
|
|
|
const
|
|
tcvAddTab = 0;
|
|
tcvInsertTab = 1;
|
|
tcvDeleteTab = 2;
|
|
tcvMoveTabLeft = 3;
|
|
tcvMoveTabRight = 4;
|
|
|
|
procedure TTabControlComponentEditor.DoAddTab;
|
|
begin
|
|
TabControl.Tabs.Add(CreateNewTabCaption);
|
|
Modified;
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.DoInsertTab;
|
|
begin
|
|
TabControl.Tabs.Insert(TabControl.TabIndex,CreateNewTabCaption);
|
|
Modified;
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.DoDeleteTab;
|
|
begin
|
|
if (TabControl.Tabs.Count=0) then exit;
|
|
TabControl.Tabs.Delete(TabControl.TabIndex);
|
|
Modified;
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.DoMoveActiveTabLeft;
|
|
var
|
|
Index: integer;
|
|
begin
|
|
Index:=TabControl.TabIndex;
|
|
if (Index<0) then exit;
|
|
DoMoveTab(Index,Index-1);
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.DoMoveActiveTabRight;
|
|
var
|
|
Index: integer;
|
|
begin
|
|
Index:=TabControl.TabIndex;
|
|
if (Index>=TabControl.Tabs.Count-1) then exit;
|
|
DoMoveTab(Index,Index+1);
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.DoMoveTab(CurIndex, NewIndex: Integer);
|
|
begin
|
|
TabControl.Tabs.Move(CurIndex,NewIndex);
|
|
Modified;
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.AddMenuItemsForTabs(
|
|
ParentMenuItem: TMenuItem);
|
|
var
|
|
i: integer;
|
|
NewMenuItem: TMenuItem;
|
|
begin
|
|
ParentMenuItem.Enabled:=TabControl.Tabs.Count>0;
|
|
for i:=0 to TabControl.Tabs.Count-1 do begin
|
|
NewMenuItem:=TMenuItem.Create(ParentMenuItem);
|
|
NewMenuItem.Name:='ShowTab'+IntToStr(i);
|
|
NewMenuItem.Caption:='"'+TabControl.Tabs[i]+'"';
|
|
NewMenuItem.OnClick:=@ShowTabMenuItemClick;
|
|
ParentMenuItem.Add(NewMenuItem);
|
|
end;
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.ShowTabMenuItemClick(Sender: TObject);
|
|
var
|
|
AMenuItem: TMenuItem;
|
|
NewTabIndex: LongInt;
|
|
begin
|
|
AMenuItem:=TMenuItem(Sender);
|
|
if (AMenuItem=nil) or (not (AMenuItem is TMenuItem)) then exit;
|
|
NewTabIndex:=AMenuItem.MenuIndex;
|
|
if (NewTabIndex<0) or (NewTabIndex>=TabControl.Tabs.Count) then exit;
|
|
TabControl.TabIndex:=NewTabIndex;
|
|
Modified;
|
|
end;
|
|
|
|
function TTabControlComponentEditor.CreateNewTabCaption: string;
|
|
begin
|
|
Result:='New Tab';
|
|
while TabControl.IndexOfTabWithCaption(Result)>=0 do
|
|
Result:=CreateNextIdentifier(Result);
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.ExecuteVerb(Index: Integer);
|
|
begin
|
|
case Index of
|
|
tcvAddTab: DoAddTab;
|
|
tcvInsertTab: DoInsertTab;
|
|
tcvDeleteTab: DoDeleteTab; // beware: this can free the editor itself
|
|
tcvMoveTabLeft: DoMoveActiveTabLeft;
|
|
tcvMoveTabRight: DoMoveActiveTabRight;
|
|
end;
|
|
end;
|
|
|
|
function TTabControlComponentEditor.GetVerb(Index: Integer): string;
|
|
begin
|
|
case Index of
|
|
tcvAddTab: Result:=tccesAddTab;
|
|
tcvInsertTab: Result:=tccesInsertTab;
|
|
tcvDeleteTab: Result:=tccesDeleteTab;
|
|
tcvMoveTabLeft: Result:=tccesMoveTabLeft;
|
|
tcvMoveTabRight: Result:=tccesMoveTabRight;
|
|
else
|
|
Result:='';
|
|
end;
|
|
end;
|
|
|
|
function TTabControlComponentEditor.GetVerbCount: Integer;
|
|
begin
|
|
Result:=5;
|
|
end;
|
|
|
|
procedure TTabControlComponentEditor.PrepareItem(Index: Integer;
|
|
const AnItem: TMenuItem);
|
|
begin
|
|
inherited PrepareItem(Index, AnItem);
|
|
case Index of
|
|
tcvAddTab: ;
|
|
tcvInsertTab: AnItem.Enabled:=TabControl.TabIndex>=0;
|
|
tcvDeleteTab: AnItem.Enabled:=TabControl.TabIndex>=0;
|
|
tcvMoveTabLeft: AnItem.Enabled:=TabControl.TabIndex>0;
|
|
tcvMoveTabRight: AnItem.Enabled:=TabControl.TabIndex<TabControl.Tabs.Count-1;
|
|
end;
|
|
end;
|
|
|
|
function TTabControlComponentEditor.TabControl: TCustomTabControl;
|
|
begin
|
|
Result:=TCustomTabControl(GetComponent);
|
|
end;
|
|
|
|
{ TTimerComponentEditor }
|
|
|
|
constructor TTimerComponentEditor.Create(AComponent: TComponent;
|
|
ADesigner: TComponentEditorDesigner);
|
|
begin
|
|
inherited Create(AComponent, ADesigner);
|
|
BestEditEvent := 'ONTIMER';
|
|
end;
|
|
|
|
{ TComponentEditorDesigner }
|
|
|
|
function TComponentEditorDesigner.GetHandlerCount(
|
|
HookType: TComponentEditorDesignerHookType): integer;
|
|
begin
|
|
Result:=FHandlers[HookType].Count;
|
|
end;
|
|
|
|
procedure TComponentEditorDesigner.AddHandler(
|
|
HookType: TComponentEditorDesignerHookType; const Handler: TMethod);
|
|
begin
|
|
if Handler.Code=nil then RaiseGDBException('TComponentEditorDesigner.AddHandler');
|
|
if FHandlers[HookType]=nil then
|
|
FHandlers[HookType]:=TMethodList.Create;
|
|
FHandlers[HookType].Add(Handler);
|
|
end;
|
|
|
|
procedure TComponentEditorDesigner.RemoveHandler(
|
|
HookType: TComponentEditorDesignerHookType; const Handler: TMethod);
|
|
begin
|
|
FHandlers[HookType].Remove(Handler);
|
|
end;
|
|
|
|
destructor TComponentEditorDesigner.Destroy;
|
|
var
|
|
HookType: TComponentEditorDesignerHookType;
|
|
begin
|
|
for HookType:=Low(FHandlers) to High(FHandlers) do
|
|
FreeThenNil(FHandlers[HookType]);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TComponentEditorDesigner.Modified;
|
|
begin
|
|
if FChangeStamp<High(FChangeStamp) then
|
|
inc(FChangeStamp)
|
|
else
|
|
FChangeStamp:=Low(FChangeStamp);
|
|
FHandlers[cedhtModified].CallNotifyEvents(Self);
|
|
end;
|
|
|
|
procedure TComponentEditorDesigner.RemoveAllHandlersForObject(
|
|
const HandlerObject: TObject);
|
|
var
|
|
HookType: TComponentEditorDesignerHookType;
|
|
begin
|
|
for HookType:=Low(FHandlers) to High(FHandlers) do
|
|
if FHandlers[HookType]<>nil then
|
|
FHandlers[HookType].RemoveAllMethodsOfObject(HandlerObject);
|
|
end;
|
|
|
|
procedure TComponentEditorDesigner.AddHandlerModified(
|
|
const OnModified: TNotifyEvent);
|
|
begin
|
|
AddHandler(cedhtModified,TMethod(OnModified));
|
|
end;
|
|
|
|
procedure TComponentEditorDesigner.RemoveHandlerModified(
|
|
const OnModified: TNotifyEvent);
|
|
begin
|
|
RemoveHandler(cedhtModified,TMethod(OnModified));
|
|
end;
|
|
|
|
initialization
|
|
RegisterComponentEditorProc := @DefaultRegisterComponentEditorProc;
|
|
RegisterComponentEditor(TCustomNotebook, TNotebookComponentEditor);
|
|
RegisterComponentEditor(TCustomPage, TPageComponentEditor);
|
|
RegisterComponentEditor(TCustomTabControl, TTabControlComponentEditor);
|
|
RegisterComponentEditor(TStringGrid, TStringGridComponentEditor);
|
|
RegisterComponentEditor(TCheckListBox, TCheckListBoxComponentEditor);
|
|
RegisterComponentEditor(TCheckGroup, TCheckGroupComponentEditor);
|
|
RegisterComponentEditor(TToolBar, TToolBarComponentEditor);
|
|
RegisterComponentEditor(TCommonDialog, TCommonDialogComponentEditor);
|
|
RegisterComponentEditor(TCustomTimer, TTimerComponentEditor);
|
|
|
|
finalization
|
|
InternalFinal;
|
|
|
|
end.
|
|
|