implemented creating classes at run time from any TComponent descendant

git-svn-id: trunk@6272 -
This commit is contained in:
mattias 2004-11-20 11:20:06 +00:00
parent d4c88e8afe
commit d2d3030a60
27 changed files with 1076 additions and 577 deletions

View File

@ -1944,11 +1944,14 @@ begin
if not (sfIgnoreNextChar in fStateFlags) then begin
{$IFDEF SYN_LAZARUS}
if Assigned(OnUTF8KeyPress) then OnUTF8KeyPress(Self, Key);
{$IFDEF VerboseKeyboard}
DebugLn('TCustomSynEdit.UTF8KeyPress ',DbgSName(Self),' Key="',DbgStr(Key),'" UseUTF8=',dbgs(UseUTF8));
{$ENDIF}
{$ELSE}
if Assigned(OnKeyPress) then OnKeyPress(Self, Key);
{$ENDIF}
CommandProcessor(ecChar, Key, nil);
//Key was handled, any way, so eat it!
// Key was handled anyway, so eat it!
Key:='';
end else
// don't ignore further keys

View File

@ -326,8 +326,8 @@ constructor TDesigner.Create(TheDesignerForm: TCustomForm;
begin
inherited Create;
FForm := TheDesignerForm;
if FForm is TNonControlForm then
FLookupRoot:=TNonControlForm(FForm).LookupRoot
if FForm is TNonFormDesignerForm then
FLookupRoot:=TNonFormDesignerForm(FForm).LookupRoot
else
FLookupRoot:=FForm;

View File

@ -43,9 +43,8 @@ uses
type
// TJITForm is a template TForm descendent class that can be altered at
// runtime
TJITForm = class(TForm)
protected
class function NewInstance: TObject; override;
// OBSOLETE:
{TJITForm = class(TForm)
public
end;
@ -54,15 +53,12 @@ type
// TJITDataModule is a template TDataModule descendent class that can be
// altered at runtime
// OBSOLETE:
TJITDataModule = class(TDataModule)
protected
class function NewInstance: TObject; override;
procedure ValidateRename(AComponent: TComponent;
const CurName, NewName: string); override;
public
end;
TJITDataModuleClass = class of TJITDataModule;
TJITDataModuleClass = class of TJITDataModule;}
// TPersistentWithTemplates
@ -74,6 +70,8 @@ type
TJITClass = class of TPersistent;
procedure SetComponentDesignMode(AComponent: TComponent; Value: Boolean);
implementation
// Define a dummy component to set the csDesigning flag which can not be set
@ -81,10 +79,15 @@ implementation
type
TSetDesigningComponent = class(TComponent)
public
class procedure SetDesigningOfControl(AComponent: TComponent; Value: Boolean);
class procedure SetDesigningOfComponent(AComponent: TComponent; Value: Boolean);
end;
procedure TSetDesigningComponent.SetDesigningOfControl(
procedure SetComponentDesignMode(AComponent: TComponent; Value: Boolean);
begin
TSetDesigningComponent.SetDesigningOfComponent(AComponent,true);
end;
procedure TSetDesigningComponent.SetDesigningOfComponent(
AComponent: TComponent; Value: Boolean);
begin
AComponent.SetDesigning(Value);
@ -100,32 +103,5 @@ begin
end;
{$IFDEF StackCheckOn}{$S+}{$ENDIF}
{ TJITForm }
function TJITForm.NewInstance: TObject;
begin
Result:=inherited NewInstance;
TSetDesigningComponent.SetDesigningOfControl(TComponent(Result),true);
end;
{ TJITDataModule }
function TJITDataModule.NewInstance: TObject;
begin
Result:=inherited NewInstance;
TSetDesigningComponent.SetDesigningOfControl(TComponent(Result),true);
end;
procedure TJITDataModule.ValidateRename(AComponent: TComponent; const CurName,
NewName: string);
var
Designer: TIDesigner;
begin
inherited ValidateRename(AComponent, CurName, NewName);
Designer:=FindRootDesigner(Self);
if Designer <> nil then
Designer.ValidateRename(AComponent, CurName, NewName);
end;
end.

View File

@ -95,15 +95,9 @@ type
FJITComponents: TList;
FFlags: TJITCompListFlags;
// jit procedures
{$IFDEF UseJITClasses}
function CreateNewJITClass(ParentClass: TClass;
const NewClassName, NewUnitName: ShortString): TClass;
procedure FreeJITClass(var AClass: TClass);
{$ELSE}
function CreateVMTCopy(SourceClass: TClass;
const NewClassName: ShortString): Pointer;
procedure FreevmtCopy(vmtCopy: Pointer);
{$ENDIF}
procedure DoAddNewMethod(JITClass: TClass; const AName: ShortString;
ACode: Pointer); // Note: AddNewMethod does not check if method already exists
procedure DoRemoveMethod(JITClass: TClass; AName: ShortString;
@ -138,38 +132,39 @@ type
function OnFindGlobalComponent(const AName:AnsiString):TComponent;
procedure InitReading(BinStream: TStream; var Reader: TReader;
DestroyDriver: Boolean); virtual;
function DoCreateJITComponent(NewComponentName,NewClassName:shortstring
):integer;
function DoCreateJITComponent(const NewComponentName, NewClassName,
NewUnitName: shortstring; ParentClass: TClass):integer;
procedure DoFinishReading; virtual;
function CreateDefaultVMTCopy: Pointer; virtual; abstract;
public
constructor Create;
destructor Destroy; override;
property Items[Index:integer]: TComponent read GetItem; default;
function Count:integer;
function AddNewJITComponent:integer;
function AddJITComponentFromStream(BinStream:TStream;
property Items[Index: integer]: TComponent read GetItem; default;
function Count: integer;
function AddNewJITComponent(const NewUnitName: shortstring;
ParentClass: TClass): integer;
function AddJITComponentFromStream(BinStream: TStream; ParentClass: TClass;
const NewUnitName: ShortString;
Interactive: Boolean):integer;
procedure DestroyJITComponent(JITComponent:TComponent);
procedure DestroyJITComponent(Index:integer);
function IndexOf(JITComponent:TComponent):integer;
function FindComponentByClassName(const AClassName:shortstring):integer;
function FindComponentByName(const AName:shortstring):integer;
procedure DestroyJITComponent(JITComponent: TComponent);
procedure DestroyJITComponent(Index: integer);
function IndexOf(JITComponent: TComponent): integer;
function Contains(JITComponent: TComponent): boolean;
function FindComponentByClassName(const AClassName: shortstring):integer;
function FindComponentByName(const AName: shortstring): integer;
procedure GetUnusedNames(var ComponentName, ComponentClassName: shortstring);
procedure AddNewMethod(JITComponent: TComponent; const AName: ShortString);
function CreateNewMethod(JITComponent:TComponent;
const AName:ShortString): TMethod;
procedure RemoveMethod(JITComponent:TComponent; const AName:ShortString);
procedure RenameMethod(JITComponent:TComponent;
const OldName,NewName:ShortString);
procedure RenameComponentClass(JITComponent:TComponent;
const NewName:ShortString);
function CreateNewMethod(JITComponent: TComponent;
const AName: ShortString): TMethod;
procedure RemoveMethod(JITComponent: TComponent; const AName: ShortString);
procedure RenameMethod(JITComponent: TComponent;
const OldName, NewName: ShortString);
procedure RenameComponentClass(JITComponent: TComponent;
const NewName: ShortString);
// child components
function AddJITChildComponentFromStream(JITOwnerComponent: TComponent;
BinStream: TStream; ComponentClass: TComponentClass;
ParentControl: TWinControl): TComponent;
public
BaseJITClass: TJITClass;
property OnReaderError: TJITReaderErrorEvent
read FOnReaderError write FOnReaderError;
property OnPropertyNotFound: TJITPropertyNotFoundEvent
@ -191,8 +186,6 @@ type
TJITForms = class(TJITComponentList)
private
function GetItem(Index: integer): TForm;
protected
function CreateDefaultVMTCopy: Pointer; override;
public
constructor Create;
function IsJITForm(AComponent: TComponent): boolean;
@ -200,17 +193,12 @@ type
end;
{ TJITDataModules }
{ TJITNonFormComponents }
TJITDataModules = class(TJITComponentList)
private
function GetItem(Index: integer): TDataModule;
protected
function CreateDefaultVMTCopy: Pointer; override;
TJITNonFormComponents = class(TJITComponentList)
public
constructor Create;
function IsJITDataModule(AComponent: TComponent): boolean;
property Items[Index:integer]: TDataModule read GetItem; default;
function IsJITNonForm(AComponent: TComponent): boolean;
end;
@ -219,6 +207,9 @@ function ClassMethodTableAsString(AClass: TClass): string;
function ClassTypeInfoAsString(AClass: TClass): string;
function ClassFieldTableAsString(AClass: TClass): string;
const
DefaultJITUnitName = 'VirtualUnitForJITClasses';
implementation
@ -265,6 +256,70 @@ type
// Fields: array[Word] of TFieldInfo; Elements have variant size!
end;
function FindVMTMethodOffset(AClass: TClass; MethodPointer: Pointer): integer;
var
i: Integer;
begin
for i:=0 to 1000 do begin
if PPointer(AClass)[i]=MethodPointer then begin
Result:=i*SizeOf(Pointer);
exit;
end;
end;
Result:=0;
end;
function GetVMTVirtualMethodOffset(
ParentClassWithVirtualMethod: TClass; MethodOfParentClass: Pointer;
ClassWithOverrideMethod: TClass; OverrideMethodOfClass: Pointer
): integer;
var
ParentMethodOffset: LongInt;
OverrideMethodOffset: LongInt;
begin
ParentMethodOffset:=FindVMTMethodOffset(
ParentClassWithVirtualMethod,MethodOfParentClass);
if ParentMethodOffset<=0 then
raise Exception.Create('GetVMTVirtualMethodOffset Parent Virtual Method not found');
OverrideMethodOffset:=FindVMTMethodOffset(
ClassWithOverrideMethod,OverrideMethodOfClass);
if OverrideMethodOffset<=0 then
raise Exception.Create('GetVMTVirtualMethodOffset Override Method not found');
if ParentMethodOffset<>OverrideMethodOffset then
raise Exception.Create('GetVMTVirtualMethodOffset Virtual Method Offset <> Override Method Offset');
Result:=OverrideMethodOffset;
end;
{ TComponentWithOverrideValidateRename }
type
TComponentWithOverrideValidateRename = class(TComponent)
public
procedure ValidateRename(AComponent: TComponent;
const CurName, NewName: string); override;
end;
var
TComponentValidateRenameOffset: LongInt;
procedure TComponentWithOverrideValidateRename.ValidateRename(
AComponent: TComponent; const CurName, NewName: string);
var
Designer: TIDesigner;
begin
//debugln('TComponentWithOverrideValidateRename.ValidateRename ',DbgSName(Self));
inherited ValidateRename(AComponent, CurName, NewName);
Designer:=FindRootDesigner(Self);
if Designer <> nil then
Designer.ValidateRename(AComponent, CurName, NewName);
end;
function GetTComponentValidateRenameVMTOffset: integer;
begin
Result:=GetVMTVirtualMethodOffset(TComponent,@TComponent.ValidateRename,
TComponentWithOverrideValidateRename,
@TComponentWithOverrideValidateRename.ValidateRename);
end;
var
MyFindGlobalComponentProc:function(const AName:AnsiString):TComponent of object;
@ -438,6 +493,11 @@ begin
while (Result>=0) and (Items[Result]<>JITComponent) do dec(Result);
end;
function TJITComponentList.Contains(JITComponent: TComponent): boolean;
begin
Result:=IndexOf(JITComponent)>=0;
end;
procedure TJITComponentList.DestroyJITComponent(JITComponent:TComponent);
var a:integer;
begin
@ -456,11 +516,7 @@ var
begin
OldClass:=Items[Index].ClassType;
Items[Index].Free;
{$IFDEF UseJITClasses}
FreeJITClass(OldClass);
{$ELSE}
FreevmtCopy(OldClass);
{$ENDIF}
FJITComponents.Delete(Index);
end;
@ -514,26 +570,31 @@ begin
s.Position:=0;
end;
function TJITComponentList.AddNewJITComponent:integer;
var NewComponentName,NewClassName:shortstring;
function TJITComponentList.AddNewJITComponent(const NewUnitName: shortstring;
ParentClass: TClass): integer;
var
NewComponentName, NewClassName: shortstring;
begin
{$IFDEF VerboseJITForms}
Writeln('[TJITComponentList] AddNewJITComponent');
debugln('[TJITComponentList] AddNewJITComponent');
{$ENDIF}
GetUnusedNames(NewComponentName,NewClassName);
{$IFDEF VerboseJITForms}
Writeln('NewComponentName is ',NewComponentName,', NewClassName is ',NewClassName);
debugln('TJITComponentList.AddNewJITComponent NewComponentName=',NewComponentName,' NewClassName=',NewClassName,
' NewUnitName=',NewUnitName,' ParentClass=',ParentClass.ClassName);
{$ENDIF}
Result:=DoCreateJITComponent(NewComponentName,NewClassName);
Result:=DoCreateJITComponent(NewComponentName,NewClassName,NewUnitName,
ParentClass);
end;
function TJITComponentList.AddJITComponentFromStream(BinStream:TStream;
Interactive: Boolean):integer;
function TJITComponentList.AddJITComponentFromStream(BinStream: TStream;
ParentClass: TClass; const NewUnitName: ShortString; Interactive: Boolean
):integer;
// returns new index
// -1 = invalid stream
var
Reader:TReader;
NewClassName:shortstring;
NewClassName: shortstring;
NewName: string;
DestroyDriver: Boolean;
begin
@ -547,7 +608,7 @@ begin
writeln('[TJITComponentList.AddJITComponentFromStream] Create ...');
{$ENDIF}
try
Result:=DoCreateJITComponent('',NewClassName);
Result:=DoCreateJITComponent('',NewClassName,NewUnitName,ParentClass);
{$IFDEF VerboseJITForms}
writeln('[TJITComponentList.AddJITComponentFromStream] InitReading ...');
{$ENDIF}
@ -625,27 +686,32 @@ begin
end;
function TJITComponentList.DoCreateJITComponent(
NewComponentName,NewClassName:shortstring):integer;
const NewComponentName, NewClassName, NewUnitName: shortstring;
ParentClass: TClass):integer;
var
Instance:TComponent;
ok: boolean;
begin
Result:=-1;
// create new class and an instance
//writeln('[TJITForms.DoCreateJITComponent] Creating new JIT class '''+NewClassName+''' ...');
Pointer(FCurReadClass):=CreateDefaultVMTCopy;
//writeln('[TJITForms.DoCreateJITComponent] Creating an instance of JIT class '''+NewClassName+''' ...');
//debugln('[TJITForms.DoCreateJITComponent] Creating new JIT class '''+NewClassName+''' ...');
Pointer(FCurReadClass):=CreateNewJITClass(ParentClass,NewClassName,
NewUnitName);
//debugln('[TJITForms.DoCreateJITComponent] Creating an instance of JIT class "'+NewClassName+'" = class('+ParentClass.ClassName+') ...');
Instance:=TComponent(FCurReadClass.NewInstance);
//writeln('[TJITForms.DoCreateJITComponent] Initializing new instance ...');
//debugln('[TJITForms.DoCreateJITComponent] Initializing new instance ... ',HexStr(Cardinal(Instance),8));
TComponent(FCurReadJITComponent):=Instance;
ok:=false;
try
// set into design mode
SetComponentDesignMode(Instance,true);
// finish 'create' component
Instance.Create(nil);
if NewComponentName<>'' then
Instance.Name:=NewComponentName;
DoRenameClass(FCurReadClass,NewClassName);
ok:=true;
//writeln('[TJITForms.DoCreateJITComponent] Initialization was successful! FormName="',NewFormName,'"');
//debugln('[TJITForms.DoCreateJITComponent] Initialization was successful! FormName="',NewFormName,'"');
finally
if not ok then begin
TComponent(FCurReadJITComponent):=nil;
@ -814,7 +880,6 @@ begin
FComponentPrefix:=AValue;
end;
{$IFDEF UseJITClasses}
function TJITComponentList.CreateNewJITClass(ParentClass: TClass;
const NewClassName, NewUnitName: ShortString): TClass;
// Create a new class (vmt, virtual method table, field table and typeinfo)
@ -841,6 +906,10 @@ begin
raise Exception.Create('CreateNewClass NewClassName empty');
if not IsValidIdent(NewClassName) then
raise Exception.Create('CreateNewClass NewClassName is not a valid identifier');
if NewUnitName='' then
raise Exception.Create('CreateNewClass NewUnitName empty');
if not IsValidIdent(NewUnitName) then
raise Exception.Create('CreateNewClass NewUnitName is not a valid identifier');
Result:=nil;
// create vmt
@ -900,6 +969,12 @@ begin
Pointer(NewVMT+vmtMethodStart)^,
vmtTailSize);
// override 'ValidateRename' for TComponent descendents
if ParentClass.InheritsFrom(TComponent) then begin
Pointer(Pointer(NewVMT+TComponentValidateRenameOffset)^):=
@TComponentWithOverrideValidateRename.ValidateRename;
end;
Result:=TClass(NewVMT);
end;
@ -951,86 +1026,6 @@ begin
FreeMem(OldVMT);
AClass:=nil;
end;
{$ELSE UseJITClasses}
function TJITComponentList.CreateVMTCopy(SourceClass:TClass;
const NewClassName:ShortString):Pointer;
const
vmtSize:integer=5000; //XXX how big is the vmt of class TJITForm ?
var MethodTable, NewMethodTable: PMethodNameTable;
MethodTableSize: integer;
ClassNamePtr, ClassNamePShortString: Pointer;
begin
//writeln('[TJITComponentList.CreatevmtCopy] SourceClass='''+SourceClass.ClassName+''''
// +' NewClassName='''+NewClassName+'''');
// create copy of vmt
GetMem(Result,vmtSize);
// type of self is class of TJITForm => it points to the vmt
Move(Pointer(SourceClass)^,Result^,vmtSize);
// create copy of methodtable
MethodTable:=PMethodNameTable((Pointer(SourceClass)+vmtMethodTable)^);
if Assigned(MethodTable) then begin
MethodTableSize:=SizeOf(DWord)+
MethodTable^.Count*SizeOf(TMethodNameRec);
GetMem(NewMethodTable,MethodTableSize);
Move(MethodTable^,NewMethodTable^,MethodTableSize);
PPointer(Result+vmtMethodTable)^:=NewMethodTable;
end;
// create pointer to classname
// set ClassNamePtr to point to the PShortString of ClassName
ClassNamePtr:=Pointer(Result)+vmtClassName;
GetMem(ClassNamePShortString,SizeOf(ShortString));
Pointer(ClassNamePtr^):=ClassNamePShortString;
Move(NewClassName[0],ClassNamePShortString^,SizeOf(ShortString));
end;
procedure TJITComponentList.FreevmtCopy(vmtCopy:Pointer);
procedure FreeNewMethods(MethodTable: PMethodNameTable);
var
CurCount, BaseCount, i: integer;
BaseMethodTable: PMethodNameTable;
CurMethod: TMethodNameRec;
begin
if MethodTable=nil then exit;
BaseMethodTable:=PMethodNameTable((Pointer(BaseJITClass)+vmtMethodTable)^);
if Assigned(BaseMethodTable) then
BaseCount:=BaseMethodTable^.Count
else
BaseCount:=0;
CurCount:=MethodTable^.Count;
if CurCount=BaseCount then exit;
i:=CurCount;
while i>BaseCount do begin
CurMethod:=MethodTable^.Entries[i-1];
if CurMethod.Name<>nil then
FreeMem(CurMethod.Name);
if CurMethod.Addr<>nil then
FreeMem(CurMethod.Addr);
dec(i);
end;
end;
var
MethodTable : PMethodNameTable;
ClassNamePtr: Pointer;
begin
{$IFDEF VerboseJITForms}
writeln('[TJITComponentList.FreevmtCopy] ClassName='''+TClass(vmtCopy).ClassName+'''');
{$ENDIF}
if vmtCopy=nil then exit;
// free copy of methodtable
MethodTable:=PMethodNameTable((Pointer(vmtCopy)+vmtMethodTable)^);
if (Assigned(MethodTable)) then begin
FreeNewMethods(MethodTable);
FreeMem(MethodTable);
end;
// free pointer to classname
ClassNamePtr:=Pointer(vmtCopy)+vmtClassName;
FreeMem(Pointer(ClassNamePtr^));
// free copy of VMT
FreeMem(vmtCopy);
end;
{$ENDIF UseJITClasses}
procedure TJITComponentList.DoAddNewMethod(JITClass:TClass;
const AName:ShortString; ACode:Pointer);
@ -1301,7 +1296,6 @@ constructor TJITForms.Create;
begin
inherited Create;
FComponentPrefix:='Form';
BaseJITClass:=TJITForm;
end;
function TJITForms.IsJITForm(AComponent: TComponent): boolean;
@ -1315,44 +1309,22 @@ begin
Result:=TForm(inherited Items[Index]);
end;
function TJITForms.CreateDefaultVMTCopy: Pointer;
begin
{$IFDEF UseJITClasses}
Result:=CreateNewJITClass(TForm,'TJITForm','JITUnit');
{$ELSE}
Result:=CreateVMTCopy(TJITForm,'TJITForm');
{$ENDIF}
end;
{ TJITNonFormComponents }
{ TJITDataModules }
function TJITDataModules.GetItem(Index: integer): TDataModule;
begin
Result:=TDataModule(inherited Items[Index]);
end;
function TJITDataModules.CreateDefaultVMTCopy: Pointer;
begin
{$IFDEF UseJITClasses}
Result:=CreateNewJITClass(TDataModule,'TJITDataModule','JITUnit');
{$ELSE}
Result:=CreateVMTCopy(TJITForm,'TJITForm');
{$ENDIF}
end;
constructor TJITDataModules.Create;
constructor TJITNonFormComponents.Create;
begin
inherited Create;
FComponentPrefix:='DataModule';
BaseJITClass:=TJITDataModule;
end;
function TJITDataModules.IsJITDataModule(AComponent: TComponent): boolean;
function TJITNonFormComponents.IsJITNonForm(AComponent: TComponent): boolean;
begin
Result:=(AComponent<>nil) and (AComponent is TDataModule)
Result:=(AComponent<>nil) and (not (AComponent is TForm))
and (IndexOf(AComponent)>=0);
end;
Initialization
TComponentValidateRenameOffset:=GetTComponentValidateRenameVMTOffset;
end.

View File

@ -32,13 +32,14 @@ unit NonControlForms;
interface
uses
Classes, SysUtils, Graphics, GraphType, Forms, Controls, IDEProcs;
Classes, SysUtils, Math, LCLProc, Graphics, GraphType, Forms, Controls,
IDEProcs;
type
{ TNonControlForm }
{ TNonFormDesignerForm }
TNonControlForm = class(TForm)
TNonFormDesignerForm = class(TForm)
private
FFrameWidth: integer;
FLookupRoot: TComponent;
@ -61,21 +62,6 @@ type
end;
{ TDataModuleForm }
TDataModuleForm = class(TNonControlForm)
private
function GetDataModule: TDataModule;
procedure SetDataModule(const AValue: TDataModule);
protected
procedure SetLookupRoot(const AValue: TComponent); override;
public
procedure DoLoadBounds; override;
procedure DoSaveBounds; override;
public
property DataModule: TDataModule read GetDataModule write SetDataModule;
end;
function CompareNonControlForms(Data1, Data2: Pointer): integer;
function CompareLookupRootAndNonControlForm(Key, Data: Pointer): integer;
@ -84,27 +70,27 @@ implementation
function CompareNonControlForms(Data1, Data2: Pointer): integer;
var
Form1: TNonControlForm;
Form2: TNonControlForm;
Form1: TNonFormDesignerForm;
Form2: TNonFormDesignerForm;
begin
Form1:=TNonControlForm(Data1);
Form2:=TNonControlForm(Data2);
Form1:=TNonFormDesignerForm(Data1);
Form2:=TNonFormDesignerForm(Data2);
Result:=integer(Form1.LookupRoot)-integer(Form2.LookupRoot);
end;
function CompareLookupRootAndNonControlForm(Key, Data: Pointer): integer;
var
LookupRoot: TComponent;
Form: TNonControlForm;
Form: TNonFormDesignerForm;
begin
LookupRoot:=TComponent(Key);
Form:=TNonControlForm(Data);
Form:=TNonFormDesignerForm(Data);
Result:=integer(LookupRoot)-integer(Form.LookupRoot);
end;
{ TNonControlForm }
{ TNonFormDesignerForm }
procedure TNonControlForm.SetLookupRoot(const AValue: TComponent);
procedure TNonFormDesignerForm.SetLookupRoot(const AValue: TComponent);
begin
if FLookupRoot=AValue then exit;
DoSaveBounds;
@ -115,26 +101,26 @@ begin
DoLoadBounds;
end;
procedure TNonControlForm.SetFrameWidth(const AValue: integer);
procedure TNonFormDesignerForm.SetFrameWidth(const AValue: integer);
begin
if FFrameWidth=AValue then exit;
FFrameWidth:=AValue;
Invalidate;
end;
constructor TNonControlForm.Create(TheOwner: TComponent);
constructor TNonFormDesignerForm.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
FFrameWidth:=1;
ControlStyle:=ControlStyle-[csAcceptsControls];
end;
destructor TNonControlForm.Destroy;
destructor TNonFormDesignerForm.Destroy;
begin
inherited Destroy;
end;
procedure TNonControlForm.Paint;
procedure TNonFormDesignerForm.Paint;
var
ARect: TRect;
begin
@ -150,38 +136,22 @@ begin
end;
end;
procedure TNonControlForm.DoLoadBounds;
begin
if Assigned(OnLoadBounds) then OnLoadBounds(Self);
end;
procedure TNonFormDesignerForm.DoLoadBounds;
procedure TNonControlForm.DoSaveBounds;
begin
if Assigned(OnSaveBounds) then OnSaveBounds(Self);
end;
procedure SetNewBounds(NewLeft, NewTop, NewWidth, NewHeight: integer);
begin
if NewWidth<=0 then NewWidth:=Width;
if NewHeight<=0 then NewHeight:=Height;
{ TDataModuleForm }
NewWidth:=Max(20,Min(NewWidth,Screen.Width-50));
NewHeight:=Max(20,Min(NewHeight,Screen.Height-50));
NewLeft:=Max(0,Min(NewLeft,Screen.Width-NewWidth-50));
NewTop:=Max(0,Min(NewTop,Screen.Height-NewHeight-50));
procedure TDataModuleForm.SetDataModule(const AValue: TDataModule);
begin
LookupRoot:=AValue;
end;
//debugln('TNonFormDesignerForm.DoLoadBounds (TDataModule) ',dbgsName(LookupRoot),' ',dbgs(NewLeft),',',dbgs(NewTop),',',dbgs(NewWidth),',',dbgs(NewHeight));
SetBounds(NewLeft,NewTop,Max(20,NewWidth),Max(NewHeight,20));
end;
function TDataModuleForm.GetDataModule: TDataModule;
begin
Result:=TDataModule(LookupRoot);
end;
procedure TDataModuleForm.SetLookupRoot(const AValue: TComponent);
begin
if AValue=LookupRoot then exit;
if (AValue<>nil) and (not (AValue is TDataModule)) then
RaiseException('TDataModuleForm.SetLookupRoot AValue.ClassName='
+AValue.ClassName);
inherited SetLookupRoot(AValue);
end;
procedure TDataModuleForm.DoLoadBounds;
var
CurDataModule: TDataModule;
NewLeft: Integer;
@ -189,29 +159,36 @@ var
NewWidth: Integer;
NewHeight: Integer;
begin
inherited DoLoadBounds;
CurDataModule:=DataModule;
if CurDataModule<>nil then begin
if Assigned(OnLoadBounds) then OnLoadBounds(Self);
if LookupRoot is TDataModule then begin
CurDataModule:=TDataModule(LookupRoot);
NewLeft:=CurDataModule.DesignOffset.X;
NewTop:=CurDataModule.DesignOffset.Y;
NewWidth:=CurDataModule.DesignSize.X;
NewHeight:=CurDataModule.DesignSize.Y;
SetBounds(NewLeft,NewTop,NewWidth,NewHeight);
SetNewBounds(NewLeft,NewTop,NewWidth,NewHeight);
end else if LookupRoot<>nil then begin
NewLeft:=LongRec(LookupRoot.DesignInfo).Lo;
NewTop:=LongRec(LookupRoot.DesignInfo).Hi;
SetNewBounds(NewLeft,NewTop,Width,Height);
end;
end;
procedure TDataModuleForm.DoSaveBounds;
var
CurDataModule: TDataModule;
procedure TNonFormDesignerForm.DoSaveBounds;
begin
CurDataModule:=DataModule;
if CurDataModule<>nil then begin
CurDataModule.DesignOffset.X:=Left;
CurDataModule.DesignOffset.Y:=Top;
CurDataModule.DesignSize.X:=Width;
CurDataModule.DesignSize.Y:=Height;
if LookupRoot is TDataModule then begin
with TDataModule(LookupRoot) do begin
DesignOffset:=Point(Left,Top);
DesignSize:=Point(Width,Height);
//debugln('TNonFormDesignerForm.DoSaveBounds (TDataModule) ',dbgsName(LookupRoot),' ',dbgs(DesignOffset.X),',',dbgs(DesignOffset.Y));
end;
end else if LookupRoot<>nil then begin
//debugln('TNonFormDesignerForm.DoSaveBounds ',dbgsName(LookupRoot),' ',dbgs(Left),',',dbgs(Top));
LongRec(LookupRoot.DesignInfo).Lo:=Left;
LongRec(LookupRoot.DesignInfo).Hi:=Top;
end;
inherited DoSaveBounds;
if Assigned(OnSaveBounds) then OnSaveBounds(Self);
end;
end.

View File

@ -123,7 +123,7 @@ each control that's dropped onto the form
FDefineProperties: TAVLTree;
function GetPropertyEditorHook: TPropertyEditorHook;
protected
FNonControlForms: TAVLTree; // tree of TNonControlForm sorted for LookupRoot
FNonControlForms: TAVLTree; // tree of TNonFormDesignerForm sorted for LookupRoot
procedure SetSelection(const ASelection: TPersistentSelectionList);
procedure OnObjectInspectorModified(Sender: TObject);
procedure SetObj_Inspector(AnObjectInspector: TObjectInspector); virtual;
@ -137,7 +137,7 @@ each control that's dropped onto the form
function FindNonControlFormNode(LookupRoot: TComponent): TAVLTreeNode;
public
JITFormList: TJITForms;// designed forms
JITDataModuleList: TJITDataModules;// designed data modules
JITNonFormList: TJITNonFormComponents;// designed data modules
constructor Create;
destructor Destroy; override;
@ -165,8 +165,8 @@ each control that's dropped onto the form
function FindJITListByClassName(const AComponentClassName: string
): TJITComponentList;
function GetDesignerForm(AComponent: TComponent): TCustomForm; override;
function FindNonControlForm(LookupRoot: TComponent): TNonControlForm;
function CreateNonControlForm(LookupRoot: TComponent): TNonControlForm;
function FindNonControlForm(LookupRoot: TComponent): TNonFormDesignerForm;
function CreateNonControlForm(LookupRoot: TComponent): TNonFormDesignerForm;
procedure RenameJITComponent(AComponent: TComponent;
const NewName: shortstring);
procedure UpdateDesignerFormName(AComponent: TComponent);
@ -198,6 +198,7 @@ each control that's dropped onto the form
X,Y,W,H : Integer): TIComponentInterface; override;
Function CreateComponentFromStream(BinStream: TStream;
AncestorType: TComponentClass;
const NewUnitName: ShortString;
Interactive: boolean): TIComponentInterface; override;
Function CreateChildComponentFromStream(BinStream: TStream;
ComponentClass: TComponentClass; Root: TComponent;
@ -747,9 +748,9 @@ begin
JITFormList.OnReaderError:=@JITListReaderError;
JITFormList.OnPropertyNotFound:=@JITListPropertyNotFound;
JITDataModuleList := TJITDataModules.Create;
JITDataModuleList.OnReaderError:=@JITListReaderError;
JITDataModuleList.OnPropertyNotFound:=@JITListPropertyNotFound;
JITNonFormList := TJITNonFormComponents.Create;
JITNonFormList.OnReaderError:=@JITListReaderError;
JITNonFormList.OnPropertyNotFound:=@JITListPropertyNotFound;
DesignerMenuItemClick:=@OnDesignerMenuItemClick;
OnGetDesignerForm:=@GetDesignerForm;
@ -765,7 +766,7 @@ begin
FreeAndNil(FDefineProperties);
end;
FreeAndNil(JITFormList);
FreeAndNil(JITDataModuleList);
FreeAndNil(JITNonFormList);
FreeAndNil(FComponentInterfaces);
FreeAndNil(FSelection);
FreeAndNil(FNonControlForms);
@ -818,15 +819,15 @@ Begin
if JITFormList.IsJITForm(AComponent) then
// free a form component
JITFormList.DestroyJITComponent(AComponent)
else if JITDataModuleList.IsJITDataModule(AComponent) then begin
// free a datamodule and its designer form
else if JITNonFormList.IsJITNonForm(AComponent) then begin
// free a non form component and its designer form
AForm:=GetDesignerForm(AComponent);
if not (AForm is TNonControlForm) then
RaiseException('TCustomFormEditor.DeleteControl Where is the TNonControlForm? '+AComponent.ClassName);
if not (AForm is TNonFormDesignerForm) then
RaiseException('TCustomFormEditor.DeleteControl Where is the TNonFormDesignerForm? '+AComponent.ClassName);
FNonControlForms.Remove(AForm);
TNonControlForm(AForm).LookupRoot:=nil;
TNonFormDesignerForm(AForm).LookupRoot:=nil;
AForm.Free;
JITDataModuleList.DestroyJITComponent(AComponent);
JITNonFormList.DestroyJITComponent(AComponent);
end else
RaiseException('TCustomFormEditor.DeleteControl '+AComponent.ClassName);
end;
@ -993,7 +994,7 @@ end;
function TCustomFormEditor.IsJITComponent(AComponent: TComponent): boolean;
begin
Result:=JITFormList.IsJITForm(AComponent)
or JITDataModuleList.IsJITDataModule(AComponent);
or JITNonFormList.IsJITNonForm(AComponent);
end;
function TCustomFormEditor.GetJITListOfType(AncestorType: TComponentClass
@ -1001,8 +1002,8 @@ function TCustomFormEditor.GetJITListOfType(AncestorType: TComponentClass
begin
if AncestorType.InheritsFrom(TForm) then
Result:=JITFormList
else if AncestorType.InheritsFrom(TDataModule) then
Result:=JITDataModuleList
else if AncestorType.InheritsFrom(TComponent) then
Result:=JITNonFormList
else
Result:=nil;
end;
@ -1012,8 +1013,8 @@ function TCustomFormEditor.FindJITList(AComponent: TComponent
begin
if JITFormList.IndexOf(AComponent)>=0 then
Result:=JITFormList
else if JITDataModuleList.IndexOf(AComponent)>=0 then
Result:=JITDataModuleList
else if JITNonFormList.IndexOf(AComponent)>=0 then
Result:=JITNonFormList
else
Result:=nil;
end;
@ -1023,8 +1024,8 @@ function TCustomFormEditor.FindJITListByClassName(
begin
if JITFormList.FindComponentByClassName(AComponentClassName)>=0 then
Result:=JITFormList
else if JITDataModuleList.FindComponentByClassName(AComponentClassName)>=0 then
Result:=JITDataModuleList
else if JITNonFormList.FindComponentByClassName(AComponentClassName)>=0 then
Result:=JITNonFormList
else
Result:=nil;
end;
@ -1045,24 +1046,24 @@ begin
end;
function TCustomFormEditor.FindNonControlForm(LookupRoot: TComponent
): TNonControlForm;
): TNonFormDesignerForm;
var
AVLNode: TAVLTreeNode;
begin
AVLNode:=FindNonControlFormNode(LookupRoot);
if AVLNode<>nil then
Result:=TNonControlForm(AVLNode.Data)
Result:=TNonFormDesignerForm(AVLNode.Data)
else
Result:=nil;
end;
function TCustomFormEditor.CreateNonControlForm(LookupRoot: TComponent
): TNonControlForm;
): TNonFormDesignerForm;
begin
if FindNonControlFormNode(LookupRoot)<>nil then
RaiseException('TCustomFormEditor.CreateNonControlForm exists already');
if LookupRoot is TDataModule then begin
Result:=TDataModuleForm.Create(nil);
if LookupRoot is TComponent then begin
Result:=TNonFormDesignerForm.Create(nil);
Result.LookupRoot:=LookupRoot;
FNonControlForms.Add(Result);
end else
@ -1083,7 +1084,7 @@ end;
procedure TCustomFormEditor.UpdateDesignerFormName(AComponent: TComponent);
var
ANonControlForm: TNonControlForm;
ANonControlForm: TNonFormDesignerForm;
begin
ANonControlForm:=FindNonControlForm(AComponent);
DebugLn('TCustomFormEditor.UpdateDesignerFormName ',
@ -1117,7 +1118,7 @@ end;
procedure TCustomFormEditor.SaveHiddenDesignerFormProperties(
AComponent: TComponent);
var
NonControlForm: TNonControlForm;
NonControlForm: TNonFormDesignerForm;
begin
NonControlForm:=FindNonControlForm(AComponent);
if NonControlForm<>nil then
@ -1140,7 +1141,7 @@ end;
function TCustomFormEditor.DesignerCount: integer;
begin
Result:=JITFormList.Count+JITDataModuleList.Count;
Result:=JITFormList.Count+JITNonFormList.Count;
end;
function TCustomFormEditor.GetDesigner(Index: integer): TIDesigner;
@ -1150,7 +1151,7 @@ begin
if Index<JITFormList.Count then
Result:=JITFormList[Index].Designer
else begin
AForm:=GetDesignerForm(JITDataModuleList[Index-JITFormList.Count]);
AForm:=GetDesignerForm(JITNonFormList[Index-JITFormList.Count]);
Result:=TIDesigner(AForm.Designer);
end;
end;
@ -1254,12 +1255,13 @@ Begin
end;
end;
end else begin
// create a toplevel control -> a form or a datamodule
// create a toplevel component
// -> a form or a datamodule or a custom component
ParentComponent:=nil;
JITList:=GetJITListOfType(TypeClass);
if JITList=nil then
RaiseException('TCustomFormEditor.CreateComponent '+TypeClass.ClassName);
NewJITIndex := JITList.AddNewJITComponent;
NewJITIndex := JITList.AddNewJITComponent(DefaultJITUnitName,TypeClass);
if NewJITIndex >= 0 then begin
// create component interface
Temp := TComponentInterface.Create;
@ -1321,10 +1323,9 @@ Begin
CompLeft:=Max(1,Min(250,Screen.Width-CompWidth-50));
if CompTop<0 then
CompTop:=Max(1,Min(250,Screen.Height-CompHeight-50));
DesignOffset.X:=CompLeft;
DesignOffset.Y:=CompTop;
DesignSize.X:=CompWidth;
DesignSize.Y:=CompHeight;
DesignOffset:=Point(CompLeft,CompTop);
DesignSize:=Point(CompWidth,CompHeight);
//debugln('TCustomFormEditor.CreateComponent TDataModule Bounds ',dbgsName(Temp.Component),' ',dbgs(DesignOffset.X),',',dbgs(DesignOffset.Y),' ',HexStr(Cardinal(Temp.Component),8),' ',HexStr(Cardinal(@DesignOffset),8));
end;
end
else begin
@ -1377,7 +1378,7 @@ end;
Function TCustomFormEditor.CreateComponentFromStream(
BinStream: TStream; AncestorType: TComponentClass;
Interactive: boolean): TIComponentInterface;
const NewUnitName: ShortString; Interactive: boolean): TIComponentInterface;
var
NewJITIndex: integer;
NewComponent: TComponent;
@ -1388,7 +1389,8 @@ begin
if JITList=nil then
RaiseException('TCustomFormEditor.CreateComponentFromStream ClassName='+
AncestorType.ClassName);
NewJITIndex := JITList.AddJITComponentFromStream(BinStream,Interactive);
NewJITIndex := JITList.AddJITComponentFromStream(BinStream,AncestorType,
NewUnitName,Interactive);
if NewJITIndex < 0 then begin
Result:=nil;
exit;
@ -1479,12 +1481,13 @@ var
APersistentClass: TPersistentClass;
begin
Result:=false;
// try to find the AClassName in the registered components
if APersistent=nil then begin
CacheItem.RegisteredComponent:=IDEComponentPalette.FindComponent(AClassname);
if (CacheItem.RegisteredComponent<>nil)
and (CacheItem.RegisteredComponent.ComponentClass<>nil) then begin
debugln('TCustomFormEditor.GetDefineProperties Component is registered');
debugln('TCustomFormEditor.GetDefineProperties ComponentClass ',AClassName,' is registered');
if not CreateTempPersistent(CacheItem.RegisteredComponent.ComponentClass)
then exit;
end;
@ -1494,7 +1497,7 @@ var
if APersistent=nil then begin
APersistentClass:=Classes.GetClass(AClassName);
if APersistentClass<>nil then begin
debugln('TCustomFormEditor.GetDefineProperties Persistent is registered');
debugln('TCustomFormEditor.GetDefineProperties PersistentClass ',AClassName,' is registered');
if not CreateTempPersistent(APersistentClass) then exit;
end;
end;
@ -1503,7 +1506,9 @@ var
// try to find the AClassName in the open forms/datamodules
APersistent:=FindJITComponentByClassName(AClassName);
if APersistent<>nil then
debugln('TCustomFormEditor.GetDefineProperties Component is a resource');
debugln('TCustomFormEditor.GetDefineProperties ComponentClass ',
AClassName,' is a resource,'
+' but inheriting design is not yet implemented');
end;
// try default classes

View File

@ -100,7 +100,8 @@ const
);
const
SynEditDefaultOptions = SYNEDIT_DEFAULT_OPTIONS - [eoShowScrollHint];
SynEditDefaultOptions = SYNEDIT_DEFAULT_OPTIONS - [eoShowScrollHint]
+ [eoHalfPageScroll];
type
{ TEditOptLanguageInfo stores lazarus IDE additional information

View File

@ -82,8 +82,8 @@ begin
ADesigner.DrawDesignerItems(true);
end;
end;
for i:=0 to JITDataModuleList.Count-1 do begin
AForm:=GetDesignerForm(JITDataModuleList[i]);
for i:=0 to JITNonFormList.Count-1 do begin
AForm:=GetDesignerForm(JITNonFormList[i]);
if AForm=nil then continue;
ADesigner:=TDesigner(AForm.Designer);
if ADesigner<>nil then begin

View File

@ -442,7 +442,7 @@ type
// methods for start
procedure LoadGlobalOptions;
procedure SetupMainMenu; override;
procedure SetuptStandardProjectTypes;
procedure SetupStandardProjectTypes;
procedure SetRecentFilesMenu;
procedure SetRecentProjectFilesMenu;
procedure SetupFileMenu; override;
@ -959,7 +959,8 @@ begin
ConnectMainBarEvents;
// create main IDE register items
SetuptStandardProjectTypes;
NewIDEItems:=TNewIDEItemCategories.Create;
SetupStandardProjectTypes;
// initialize the other IDE managers
DebugBoss:=TDebugManager.Create(nil);
@ -1042,6 +1043,7 @@ begin
FreeThenNil(MacroList);
FreeThenNil(LazProjectFileDescriptors);
FreeThenNil(LazProjectDescriptors);
FreeThenNil(NewIDEItems);
// IDE options objects
FreeThenNil(CodeToolsOpts);
FreeThenNil(MiscellaneousOptions);
@ -1545,7 +1547,7 @@ begin
SetupHelpMenu;
end;
procedure TMainIDE.SetuptStandardProjectTypes;
procedure TMainIDE.SetupStandardProjectTypes;
var
FileDescPascalUnit: TFileDescPascalUnit;
FileDescPascalUnitWithForm: TFileDescPascalUnitWithForm;
@ -1555,6 +1557,11 @@ var
ProjDescApplication: TProjectApplicationDescriptor;
ProjDescProgram: TProjectProgramDescriptor;
ProjDescCustomProgram: TProjectManualProgramDescriptor;
i: Integer;
NewItemFile: TNewItemProjectFile;
NewItemProject: TNewItemProject;
FileItem: TProjectFileDescriptor;
ProjectItem: TProjectDescriptor;
begin
// file descriptors ----------------------------------------------------------
LazProjectFileDescriptors:=TLazProjectFileDescriptors.Create;
@ -1585,6 +1592,25 @@ begin
// custom program
ProjDescCustomProgram:=TProjectManualProgramDescriptor.Create;
LazProjectDescriptors.RegisterDescriptor(ProjDescCustomProgram);
NewIDEItems.Add(TNewIDEItemCategoryFile.Create('File'));
NewIDEItems.Add(TNewIDEItemCategoryProject.Create('Project'));
// TODO: move this mechanism to LazProjectFileDescriptors.RegisterFileDescriptor
for i:=0 to LazProjectFileDescriptors.Count-1 do begin
FileItem:=LazProjectFileDescriptors[i];
if not FileItem.VisibleInNewDialog then continue;
NewItemFile:=TNewItemProjectFile.Create(FileItem.Name,niifCopy,[niifCopy]);
NewItemFile.Descriptor:=FileItem;
RegisterNewDialogItem('File',NewItemFile);
end;
for i:=0 to LazProjectDescriptors.Count-1 do begin
ProjectItem:=LazProjectDescriptors[i];
if not ProjectItem.VisibleInNewDialog then continue;
NewItemProject:=TNewItemProject.Create(ProjectItem.Name,niifCopy,[niifCopy]);
NewItemProject.Descriptor:=ProjectItem;
RegisterNewDialogItem('Project',NewItemProject);
end;
end;
procedure TMainIDE.SetRecentFilesMenu;
@ -3858,6 +3884,7 @@ var
DesignerForm: TCustomForm;
NewClassName: String;
NewAncestorName: String;
APersistentClass: TPersistentClass;
begin
CloseDesignerForm(AnUnitInfo);
@ -3894,12 +3921,23 @@ begin
// find the ancestor type in the source
NewAncestorName:='';
AncestorType:=TForm;
CodeToolBoss.FindFormAncestor(AnUnitInfo.Source,NewClassName,
NewAncestorName,true);
if AnsiCompareText(NewAncestorName,'TDataModule')=0 then
AncestorType:=TDataModule
else
AncestorType:=TForm;
if NewAncestorName<>'' then begin
if AnsiCompareText(NewAncestorName,'TDataModule')=0 then begin
// use our TDataModule
// (some fpc versions have non designable TDataModule)
AncestorType:=TDataModule;
end else begin
APersistentClass:=Classes.GetClass(NewAncestorName);
if (APersistentClass<>nil)
and (APersistentClass.InheritsFrom(TComponent)) then begin
// ancestor type is a registered component class
AncestorType:=TComponentClass(APersistentClass);
end;
end;
end;
DebugLn('TMainIDE.DoLoadLFM AncestorClassName=',NewAncestorName,' AncestorType=',AncestorType.ClassName);
// convert text to binary format
@ -3932,7 +3970,7 @@ begin
// create JIT component
CInterface := TComponentInterface(
FormEditor1.CreateComponentFromStream(BinLFMStream,
AncestorType,true));
AncestorType,copy(AnUnitInfo.UnitName,1,255),true));
if CInterface=nil then begin
// error streaming component -> examine lfm file
DebugLn('ERROR: streaming failed lfm="',LFMBuf.Filename,'"');
@ -4505,28 +4543,22 @@ end;
function TMainIDE.DoNewOther: TModalResult;
var
NewIDEItem: TNewIDEItem;
NewIDEItem: TNewIDEItemTemplate;
begin
Result:=ShowNewIDEItemDialog(NewIDEItem);
try
if Result<>mrOk then exit;
case NewIDEItem.TheType of
// files
niiText: Result:=DoNewEditorFile(FileDescriptorText,'','',
[nfOpenInEditor,nfCreateDefaultSrc]);
niiUnit: Result:=DoNewEditorFile(FileDescriptorUnit,'','',
[nfOpenInEditor,nfCreateDefaultSrc]);
niiForm: Result:=DoNewEditorFile(FileDescriptorForm,'','',
[nfOpenInEditor,nfCreateDefaultSrc]);
niiDataModule: Result:=DoNewEditorFile(FileDescriptorDatamodule,'','',
[nfOpenInEditor,nfCreateDefaultSrc]);
// projects
niiApplication: DoNewProject(ProjectDescriptorApplication);
niiFPCProject: DoNewProject(ProjectDescriptorProgram);
niiCustomProject: DoNewProject(ProjectDescriptorCustomProgram);
// packages
niiPackage: PkgBoss.DoNewPackage;
else
if NewIDEItem is TNewItemProjectFile then begin
// file
Result:=DoNewEditorFile(TNewItemProjectFile(NewIDEItem).Descriptor,
'','',[nfOpenInEditor,nfCreateDefaultSrc]);
end else if NewIDEItem is TNewItemProject then begin
// project
Result:=DoNewProject(TNewItemProject(NewIDEItem).Descriptor);
end else if NewIDEItem is TNewItemPackage then begin
// packages
PkgBoss.DoNewPackage;
end else begin
MessageDlg(ueNotImplCap,
lisSorryThisTypeIsNotYetImplemented,
mtInformation,[mbOk],0);
@ -10974,6 +11006,9 @@ end.
{ =============================================================================
$Log$
Revision 1.794 2004/11/20 11:20:05 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.793 2004/11/19 12:23:43 vincents
fixed WaitForLazarus: close process handle after use.

View File

@ -440,7 +440,9 @@ end;
function TFileDescSimplePascalProgram.GetLocalizedDescription: string;
begin
Result:='Custom Program';
Result:='A simple Pascal Program file.'#13
+'This can be used for quick and dirty testing.'#13
+'Better create a new project.';
end;
function TFileDescSimplePascalProgram.CreateSource(const Filename, SourceName,

View File

@ -40,24 +40,28 @@ unit NewDialog;
interface
uses
Classes, SysUtils, Forms, Controls, StdCtrls, Buttons, ComCtrls,
Dialogs, LResources, IDEOptionDefs, LazarusIDEStrConsts;
Classes, SysUtils, LCLProc, Forms, Controls, StdCtrls, Buttons, ComCtrls,
Dialogs, LResources, ProjectIntf, PackageIntf,
IDEOptionDefs, LazarusIDEStrConsts;
type
// Items that can be created in the IDE:
TNewIDEItemType = (
{TNewIDEItemType = (
niiNone,
niiCustom, // for experts (IDE plugins)
niiUnit, // pascal unit
niiForm, // pascal unit with lcl form
niiDataModule, // pascal nuit with datamodule
niiText, // text file
niiApplication,// Project: Application
niiFPCProject, // Project: with hidden main file
niiCustomProject,// Project: pascal program without any specials
niiPackage // standard package
);
TNewIDEItemTypes = set of TNewIDEItemType;
TNewIDEItemTypes = set of TNewIDEItemType;}
// Flags/Options for the items
TNewIDEItemFlag = (
@ -79,12 +83,15 @@ type
function GetCount: integer;
function GetItems(Index: integer): TNewIDEItemTemplate;
public
constructor Create;
constructor Create(const AName: string);
destructor Destroy; override;
procedure Clear;
procedure Add(ATemplate: TNewIDEItemTemplate);
function LocalizedName: string;
function Description: string;
function LocalizedName: string; virtual;
function Description: string; virtual;
function IndexOfCategory(const CategoryName: string): integer;
function FindCategoryByName(const CategoryName: string): TNewIDEItemCategory;
public
property Count: integer read GetCount;
property Items[Index: integer]: TNewIDEItemTemplate read GetItems; default;
@ -100,11 +107,17 @@ type
function GetItems(Index: integer): TNewIDEItemCategory;
procedure SetItems(Index: integer; const AValue: TNewIDEItemCategory);
public
constructor CreateWithDefaults;
constructor Create;
destructor Destroy; override;
procedure Clear;
procedure Add(ACategory: TNewIDEItemCategory);
function Count: integer;
function IndexOf(const CategoryName: string): integer;
function FindByName(const CategoryName: string): TNewIDEItemCategory;
procedure RegisterItem(const Paths: string; NewItem: TNewIDEItemTemplate);
procedure UnregisterItem(NewItem: TNewIDEItemTemplate);
function FindCategoryByPath(const Path: string;
ErrorOnNotFound: boolean): TNewIDEItemCategory;
public
property Items[Index: integer]: TNewIDEItemCategory
read GetItems write SetItems; default;
@ -113,46 +126,98 @@ type
{ TNewIDEItemTemplate }
TNewIDEItemTemplate = class
TNewIDEItemTemplate = class(TPersistent)
private
FAllowedFlags: TNewIDEItemFlags;
FDefaultFlag: TNewIDEItemFlag;
FName: string;
fCategory: TNewIDEItemCategory;
FTheType: TNewIDEItemType;
public
constructor Create(AType: TNewIDEItemType; const AName: string;
ADefaultFlag: TNewIDEItemFlag;
constructor Create(const AName: string; ADefaultFlag: TNewIDEItemFlag;
TheAllowedFlags: TNewIDEItemFlags);
function LocalizedName: string;
function Description: string;
function LocalizedName: string; virtual;
function Description: string; virtual;
function CreateCopy: TNewIDEItemTemplate; virtual;
procedure Assign(Source: TPersistent); override;
public
property TheType: TNewIDEItemType read FTheType;
property DefaultFlag: TNewIDEItemFlag read FDefaultFlag;
property AllowedFlags: TNewIDEItemFlags read FAllowedFlags;
property Name: string read FName;
property Category: TNewIDEItemCategory read fCategory;
property Category: TNewIDEItemCategory read fCategory; // main category
end;
TNewIDEItemTemplateClass = class of TNewIDEItemTemplate;
//----------------------------------------------------------------------------
// standard categories for new dialog
{ TNewIDEItemCategoryFile }
TNewIDEItemCategoryFile = class(TNewIDEItemCategory)
public
function LocalizedName: string; override;
function Description: string; override;
end;
{ TNewIDEItemCategoryProject }
{ TNewIDEItem }
TNewIDEItemCategoryProject = class(TNewIDEItemCategory)
public
function LocalizedName: string; override;
function Description: string; override;
end;
TNewIDEItem = class
{ TNewIDEItemCategoryPackage }
TNewIDEItemCategoryPackage = class(TNewIDEItemCategory)
public
function LocalizedName: string; override;
function Description: string; override;
end;
//----------------------------------------------------------------------------
// standard items for new dialog
{ TNewItemProjectFile - a new item for project file descriptors }
TNewItemProjectFile = class(TNewIDEItemTemplate)
private
FFlag: TNewIDEItemFlag;
FTheType: TNewIDEItemType;
procedure SetFlag(const AValue: TNewIDEItemFlag);
procedure SetTheType(const AValue: TNewIDEItemType);
FDescriptor: TProjectFileDescriptor;
public
constructor Create;
procedure Assign(Source: TNewIDEItem);
procedure Assign(Source: TNewIDEItemTemplate);
function CreateCopy: TNewIDEItem;
function LocalizedName: string; override;
function Description: string; override;
procedure Assign(Source: TPersistent); override;
public
property TheType: TNewIDEItemType read FTheType write SetTheType;
property Flag: TNewIDEItemFlag read FFlag write SetFlag;
property Descriptor: TProjectFileDescriptor read FDescriptor write FDescriptor;
end;
{ TNewItemProject - a new item for project descriptors }
TNewItemProject = class(TNewIDEItemTemplate)
private
FDescriptor: TProjectDescriptor;
public
function LocalizedName: string; override;
function Description: string; override;
procedure Assign(Source: TPersistent); override;
public
property Descriptor: TProjectDescriptor read FDescriptor write FDescriptor;
end;
{ TNewItemPackage - a new item for package descriptors }
TNewItemPackage = class(TNewIDEItemTemplate)
private
FDescriptor: TPackageDescriptor;
public
function LocalizedName: string; override;
function Description: string; override;
procedure Assign(Source: TPersistent); override;
public
property Descriptor: TPackageDescriptor read FDescriptor write FDescriptor;
end;
//----------------------------------------------------------------------------
{ TNewOtherDialog }
@ -167,49 +232,55 @@ type
procedure NewOtherDialogResize(Sender: TObject);
procedure OkButtonClick(Sender: TObject);
private
FItemType: TNewIDEItem;
procedure FillItemsTree;
procedure SetupComponents;
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
public
property ItemType: TNewIDEItem read FItemType;
function GetNewItem: TNewIDEItemTemplate;
end;
function ShowNewIDEItemDialog(var ItemType: TNewIDEItem): TModalResult;
function NewIDEItems: TNewIDEItemCategories;
function ShowNewIDEItemDialog(var NewItem: TNewIDEItemTemplate): TModalResult;
var
NewIDEItems: TNewIDEItemCategories;// will be set by the IDE
procedure RegisterNewDialogItem(const Paths: string;
NewItem: TNewIDEItemTemplate);
procedure UnregisterNewDialogItem(NewItem: TNewIDEItemTemplate);
implementation
var
InternalNewIDEItems: TNewIDEItemCategories;
function ShowNewIDEItemDialog(var ItemType: TNewIDEItem): TModalResult;
function ShowNewIDEItemDialog(var NewItem: TNewIDEItemTemplate): TModalResult;
var
NewOtherDialog: TNewOtherDialog;
begin
ItemType:=nil;
NewItem:=nil;
NewOtherDialog:=TNewOtherDialog.Create(Application);
Result:=NewOtherDialog.ShowModal;
if Result=mrOk then begin
ItemType:=NewOtherDialog.ItemType.CreateCopy;
NewItem:=NewOtherDialog.GetNewItem;
end;
IDEDialogLayoutList.SaveLayout(NewOtherDialog);
NewOtherDialog.Free;
end;
function NewIDEItems: TNewIDEItemCategories;
procedure RegisterNewDialogItem(const Paths: string;
NewItem: TNewIDEItemTemplate);
begin
if InternalNewIDEItems=nil then
InternalNewIDEItems:=TNewIDEItemCategories.CreateWithDefaults;
Result:=InternalNewIDEItems;
if NewIDEItems=nil then
raise Exception.Create('RegisterNewDialogItem NewIDEItems=nil');
NewIDEItems.RegisterItem(Paths,NewItem);
end;
procedure InternalFinal;
procedure UnregisterNewDialogItem(NewItem: TNewIDEItemTemplate);
begin
InternalNewIDEItems.Free;
InternalNewIDEItems:=nil;
if NewIDEItems=nil then
raise Exception.Create('RegisterNewDialogItem NewIDEItems=nil');
NewIDEItems.UnregisterItem(NewItem);
end;
{ TNewOtherDialog }
@ -241,7 +312,6 @@ end;
procedure TNewOtherDialog.OkButtonClick(Sender: TObject);
var
ANode: TTreeNode;
Template: TNewIDEItemTemplate;
begin
ANode:=ItemsTreeView.Selected;
if (ANode=nil) or (ANode.Data=nil)
@ -251,8 +321,6 @@ begin
lisNewDlgPleaseSelectAnItemFirst, mtInformation, [mbOk], 0);
exit;
end;
Template:=TNewIDEItemTemplate(ANode.Data);
FItemType.Assign(Template);
ModalResult:=mrOk;
end;
@ -265,6 +333,7 @@ var
TemplateID: Integer;
Template: TNewIDEItemTemplate;
begin
ItemsTreeView.BeginUpdate;
ItemsTreeView.Items.Clear;
for CategoryID:=0 to NewIDEItems.Count-1 do begin
Category:=NewIDEItems[CategoryID];
@ -275,6 +344,7 @@ begin
end;
NewParentNode.Expand(true);
end;
ItemsTreeView.EndUpdate;
end;
procedure TNewOtherDialog.CancelButtonClick(Sender: TObject);
@ -352,10 +422,9 @@ end;
constructor TNewOtherDialog.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
FItemType:=TNewIDEItem.Create;
if LazarusResources.Find(Classname)=nil then begin
Name:='NewOtherDialog';
Caption := 'New ...';
Caption := lisMenuNewOther;
Width:=400;
Height:=300;
Position:=poScreenCenter;
@ -369,46 +438,18 @@ end;
destructor TNewOtherDialog.Destroy;
begin
FItemType.Free;
inherited Destroy;
end;
{ TNewIDEItem }
procedure TNewIDEItem.SetTheType(const AValue: TNewIDEItemType);
function TNewOtherDialog.GetNewItem: TNewIDEItemTemplate;
var
ANode: TTreeNode;
begin
if FTheType=AValue then exit;
FTheType:=AValue;
end;
constructor TNewIDEItem.Create;
begin
FTheType:=niiNone;
FFlag:=niifCopy;
end;
procedure TNewIDEItem.SetFlag(const AValue: TNewIDEItemFlag);
begin
if FFlag=AValue then exit;
FFlag:=AValue;
end;
procedure TNewIDEItem.Assign(Source: TNewIDEItem);
begin
TheType:=Source.TheType;
Flag:=Source.Flag;
end;
procedure TNewIDEItem.Assign(Source: TNewIDEItemTemplate);
begin
TheType:=Source.TheType;
Flag:=Source.DefaultFlag;
end;
function TNewIDEItem.CreateCopy: TNewIDEItem;
begin
Result:=TNewIDEItem.Create;
Result.Assign(Self);
ANode:=ItemsTreeView.Selected;
if (ANode=nil) or (ANode.Data=nil)
or (not (TObject(ANode.Data) is TNewIDEItemTemplate))
then exit;
Result:=TNewIDEItemTemplate(ANode.Data).CreateCopy;
end;
{ TNewIDEItemCategory }
@ -423,10 +464,16 @@ begin
Result:=TNewIDEItemTemplate(FItems[Index]);
end;
constructor TNewIDEItemCategory.Create;
begin
raise Exception.Create('TNewIDEItemCategory.Create: call Create(Name) instead');
end;
constructor TNewIDEItemCategory.Create(const AName: string);
begin
FItems:=TList.Create;
FName:=AName;
//debugln('TNewIDEItemCategory.Create ',Name);
end;
destructor TNewIDEItemCategory.Destroy;
@ -446,6 +493,7 @@ end;
procedure TNewIDEItemCategory.Add(ATemplate: TNewIDEItemTemplate);
begin
//debugln('TNewIDEItemCategory.Add ',Name);
FItems.Add(ATemplate);
ATemplate.fCategory:=Self;
end;
@ -466,13 +514,30 @@ begin
Result:='';
end;
function TNewIDEItemCategory.IndexOfCategory(const CategoryName: string
): integer;
begin
// TODO
Result:=-1;
end;
function TNewIDEItemCategory.FindCategoryByName(const CategoryName: string
): TNewIDEItemCategory;
var
i: LongInt;
begin
i:=IndexOfCategory(CategoryName);
if i>=0 then
Result:=nil // TODO
else
Result:=nil;
end;
{ TNewIDEItemTemplate }
constructor TNewIDEItemTemplate.Create(AType: TNewIDEItemType;
const AName: string; ADefaultFlag: TNewIDEItemFlag;
TheAllowedFlags: TNewIDEItemFlags);
constructor TNewIDEItemTemplate.Create(const AName: string;
ADefaultFlag: TNewIDEItemFlag; TheAllowedFlags: TNewIDEItemFlags);
begin
FTheType:=AType;
FName:=AName;
FDefaultFlag:=ADefaultFlag;
FAllowedFlags:=TheAllowedFlags;
@ -481,49 +546,32 @@ end;
function TNewIDEItemTemplate.LocalizedName: string;
begin
// ToDo: translate
Result:=Name;
end;
function TNewIDEItemTemplate.Description: string;
begin
case TheType of
niiNone:
Result:='';
Result:='<Description not set>';
end;
niiCustom:
Result:='';
function TNewIDEItemTemplate.CreateCopy: TNewIDEItemTemplate;
begin
Result:=TNewIDEItemTemplateClass(ClassType).Create(
Name,DefaultFlag,AllowedFlags);
Result.Assign(Self);
end;
niiUnit:
Result:=lisNewDlgCreateANewPascalUnit;
niiForm:
Result:=lisNewDlgCreateANewUnitWithALCLForm;
niiDataModule:
Result:=lisNewDlgCreateANewUnitWithADataModule;
niiText:
Result:=lisNewDlgCreateANewEmptyTextFile;
niiApplication:
Result:=Format(
lisNewDlgCreateANewGraphicalApplication, [#13#13]);
niiFPCProject:
Result:=Format(
lisNewDlgCreateANewProgram, [#13#13]);
niiCustomProject:
Result:=lisNewDlgCreateANewCustomProgram;
niiPackage:
Result:=Format(
lisNewDlgCreateANewStandardPackageAPackageIsACollectionOfUn, [#13#13]);
else
Result:=''
end;
procedure TNewIDEItemTemplate.Assign(Source: TPersistent);
var
Src: TNewIDEItemTemplate;
begin
if Source is TNewIDEItemTemplate then begin
Src:=TNewIDEItemTemplate(Source);
FName:=Src.Name;
FDefaultFlag:=Src.DefaultFlag;
FAllowedFlags:=Src.AllowedFlags;
end else
inherited Assign(Source);
end;
{ TNewIDEItemCategories }
@ -539,36 +587,9 @@ begin
FItems[Index]:=AValue;
end;
constructor TNewIDEItemCategories.CreateWithDefaults;
var
NewCategory: TNewIDEItemCategory;
constructor TNewIDEItemCategories.Create;
begin
FItems:=TList.Create;
// category file
NewCategory:=TNewIDEItemCategory.Create('File');
Add(NewCategory);
NewCategory.Add(TNewIDEItemTemplate.Create(niiUnit,'Unit',niifCopy,[]));
NewCategory.Add(TNewIDEItemTemplate.Create(niiForm,'Form',niifCopy,[]));
NewCategory.Add(TNewIDEItemTemplate.Create(niiDataModule,'Data Module',
niifCopy,[]));
NewCategory.Add(TNewIDEItemTemplate.Create(niiText,'Text',niifCopy,[]));
// category project
NewCategory:=TNewIDEItemCategory.Create('Project');
Add(NewCategory);
NewCategory.Add(
TNewIDEItemTemplate.Create(niiApplication,'Application',niifCopy,[]));
NewCategory.Add(
TNewIDEItemTemplate.Create(niiFPCProject,'FPC Project',niifCopy,[]));
NewCategory.Add(
TNewIDEItemTemplate.Create(niiCustomProject,'Custom Project',niifCopy,[]));
// category package
NewCategory:=TNewIDEItemCategory.Create('Package');
Add(NewCategory);
NewCategory.Add(
TNewIDEItemTemplate.Create(niiPackage,'Standard Package',niifCopy,[]));
end;
destructor TNewIDEItemCategories.Destroy;
@ -596,8 +617,187 @@ begin
Result:=FItems.Count;
end;
finalization
InternalFinal;
function TNewIDEItemCategories.IndexOf(const CategoryName: string): integer;
begin
Result:=Count-1;
while (Result>=0) and (AnsiCompareText(CategoryName,Items[Result].Name)<>0) do
dec(Result);
end;
function TNewIDEItemCategories.FindByName(const CategoryName: string
): TNewIDEItemCategory;
var
i: LongInt;
begin
i:=IndexOf(CategoryName);
if i>=0 then
Result:=Items[i]
else
Result:=nil;
end;
procedure TNewIDEItemCategories.RegisterItem(const Paths: string;
NewItem: TNewIDEItemTemplate);
procedure AddToPath(const Path: string);
var
CurCategory: TNewIDEItemCategory;
begin
CurCategory:=FindCategoryByPath(Path,true);
CurCategory.Add(NewItem);
end;
var
StartPos: Integer;
EndPos: Integer;
Path: String;
begin
// go through all paths
EndPos:=1;
while EndPos<=length(Paths) do begin
StartPos:=EndPos;
while (StartPos<=length(Paths)) and (Paths[StartPos]=';') do
inc(StartPos);
EndPos:=StartPos;
while (EndPos<=length(Paths)) and (Paths[EndPos]<>';') do
inc(EndPos);
if EndPos>StartPos then begin
Path:=copy(Paths,StartPos,EndPos-StartPos);
AddToPath(Path);
end;
end;
end;
procedure TNewIDEItemCategories.UnregisterItem(NewItem: TNewIDEItemTemplate);
begin
raise Exception.Create('TODO TNewIDEItemCategories.UnregisterItem');
end;
function TNewIDEItemCategories.FindCategoryByPath(const Path: string;
ErrorOnNotFound: boolean): TNewIDEItemCategory;
var
StartPos: Integer;
EndPos: Integer;
CategoryName: String;
begin
Result:=nil;
EndPos:=1;
while EndPos<=length(Path) do begin
StartPos:=EndPos;
while (StartPos<=length(Path)) and (Path[StartPos]='/') do
inc(StartPos);
EndPos:=StartPos;
while (EndPos<=length(Path)) and (Path[EndPos]<>'/') do
inc(EndPos);
if EndPos>StartPos then begin
CategoryName:=copy(Path,StartPos,EndPos-StartPos);
if Result=nil then
Result:=FindByName(CategoryName)
else
Result:=Result.FindCategoryByName(CategoryName);
if (Result=nil) then begin
if ErrorOnNotFound then
raise Exception.Create(
'Unknown category: '+CategoryName+' in Path '+Path)
else
exit;
end;
end;
end;
end;
{ TNewItemProjectFile }
function TNewItemProjectFile.LocalizedName: string;
begin
Result:=Descriptor.GetLocalizedName;
end;
function TNewItemProjectFile.Description: string;
begin
Result:=Descriptor.GetLocalizedDescription;
end;
procedure TNewItemProjectFile.Assign(Source: TPersistent);
begin
inherited Assign(Source);
if Source is TNewItemProjectFile then
FDescriptor:=TNewItemProjectFile(Source).Descriptor;
end;
{ TNewItemProject }
function TNewItemProject.LocalizedName: string;
begin
Result:=Descriptor.GetLocalizedName;
end;
function TNewItemProject.Description: string;
begin
Result:=Descriptor.GetLocalizedDescription;
end;
procedure TNewItemProject.Assign(Source: TPersistent);
begin
inherited Assign(Source);
if Source is TNewItemProject then
FDescriptor:=TNewItemProject(Source).Descriptor;
end;
{ TNewItemPackage }
function TNewItemPackage.LocalizedName: string;
begin
Result:=Descriptor.GetLocalizedName;
end;
function TNewItemPackage.Description: string;
begin
Result:=Descriptor.GetLocalizedDescription;
end;
procedure TNewItemPackage.Assign(Source: TPersistent);
begin
inherited Assign(Source);
if Source is TNewItemPackage then
FDescriptor:=TNewItemPackage(Source).Descriptor;
end;
{ TNewIDEItemCategoryFile }
function TNewIDEItemCategoryFile.LocalizedName: string;
begin
Result:='File';
end;
function TNewIDEItemCategoryFile.Description: string;
begin
Result:='Choose one of these items to create a new File';
end;
{ TNewIDEItemCategoryProject }
function TNewIDEItemCategoryProject.LocalizedName: string;
begin
Result:='Project';
end;
function TNewIDEItemCategoryProject.Description: string;
begin
Result:='Choose one of these items to create a new Project';
end;
{ TNewIDEItemCategoryPackage }
function TNewIDEItemCategoryPackage.LocalizedName: string;
begin
Result:='Package';
end;
function TNewIDEItemCategoryPackage.Description: string;
begin
Result:='Choose one of these items to create a new Package';
end;
end.

View File

@ -86,7 +86,7 @@ type
this attribute contains the component name,
even if the unit is not loaded,
or the designer form is not created.
A component can be a TForm or a TDataModule }
A component can be for example a TForm or a TDataModule }
fComponentResourceName: string;
FComponentLastBinStreamSize: TStreamSeekType;
FComponentLastLFMStreamSize: TStreamSeekType;
@ -3130,6 +3130,9 @@ end.
{
$Log$
Revision 1.170 2004/11/20 11:20:05 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.169 2004/10/12 08:23:20 mattias
fixed compiler options interface double variables

View File

@ -83,6 +83,7 @@ type
procedure RegisterFileDescriptor(FileDescriptor: TProjectFileDescriptor); override;
procedure UnregisterFileDescriptor(FileDescriptor: TProjectFileDescriptor); override;
procedure UpdateDefaultPascalFileExtensions;
public
property DefaultPascalFileExt: string read FDefaultPascalFileExt write SetDefaultPascalFileExt;
end;

View File

@ -91,8 +91,9 @@ type
TypeClass : TComponentClass;
X,Y,W,H : Integer): TIComponentInterface; virtual; abstract;
Function CreateComponentFromStream(BinStream: TStream;
AncestorType: TComponentClass; Interactive: boolean
): TIComponentInterface; virtual; abstract;
AncestorType: TComponentClass;
const NewUnitName: ShortString;
Interactive: boolean): TIComponentInterface; virtual; abstract;
Function CreateChildComponentFromStream(BinStream: TStream;
ComponentClass: TComponentClass;
Root: TComponent;

View File

@ -40,7 +40,12 @@ interface
uses
Classes, SysUtils, Forms;
const
PkgDescNameStandard = 'Standard Package';
type
{ TPackageEditingInterface }
TPackageEditingInterface = class(TComponent)
public
function AddUnitDependenciesForComponentClasses(const UnitFilename: string;
@ -53,8 +58,96 @@ type
var
PackageEditingInterface: TPackageEditingInterface; // will be set by the IDE
type
{ TPackageDescriptor }
TPackageDescriptor = class(TPersistent)
private
FName: string;
FReferenceCount: integer;
FVisibleInNewDialog: boolean;
protected
procedure SetName(const AValue: string); virtual;
public
constructor Create; virtual;
function GetLocalizedName: string; virtual;
function GetLocalizedDescription: string; virtual;
procedure Release;
procedure Reference;
// TODO: procedure InitPackage(APackage: TLazPackage); virtual;
// TODO: procedure CreateStartFiles(APackage: TLazPackage); virtual;
public
property Name: string read FName write SetName;
property VisibleInNewDialog: boolean read FVisibleInNewDialog write FVisibleInNewDialog;
end;
{ TPackageDescriptors }
TPackageDescriptors = class(TPersistent)
protected
function GetItems(Index: integer): TPackageDescriptor; virtual; abstract;
public
function Count: integer; virtual; abstract;
function GetUniqueName(const Name: string): string; virtual; abstract;
function IndexOf(const Name: string): integer; virtual; abstract;
function FindByName(const Name: string): TPackageDescriptor; virtual; abstract;
procedure RegisterDescriptor(Descriptor: TPackageDescriptor); virtual; abstract;
procedure UnregisterDescriptor(Descriptor: TPackageDescriptor); virtual; abstract;
public
property Items[Index: integer]: TPackageDescriptor read GetItems; default;
end;
var
PackageDescriptors: TPackageDescriptors; // will be set by the IDE
function PackageDescriptorStd: TPackageDescriptor;
implementation
function PackageDescriptorStd: TPackageDescriptor;
begin
Result:=PackageDescriptors.FindByName(PkgDescNameStandard);
end;
{ TPackageDescriptor }
procedure TPackageDescriptor.SetName(const AValue: string);
begin
if FName=AValue then exit;
FName:=AValue;
end;
constructor TPackageDescriptor.Create;
begin
FReferenceCount:=1;
fVisibleInNewDialog:=true;
end;
function TPackageDescriptor.GetLocalizedName: string;
begin
Result:=Name;
end;
function TPackageDescriptor.GetLocalizedDescription: string;
begin
Result:=GetLocalizedName;
end;
procedure TPackageDescriptor.Release;
begin
//debugln('TPackageDescriptor.Release A ',Name,' ',dbgs(FReferenceCount));
if FReferenceCount=0 then
raise Exception.Create('');
dec(FReferenceCount);
if FReferenceCount=0 then Free;
end;
procedure TPackageDescriptor.Reference;
begin
inc(FReferenceCount);
end;
initialization
PackageEditingInterface:=nil;

View File

@ -245,6 +245,7 @@ type
property CustomOptions: string read fCustomOptions write SetCustomOptions;
end;
{ TLazProjectFile }
TLazProjectFile = class(TPersistent)
@ -262,6 +263,7 @@ type
property Filename: string read GetFilename;
end;
{ TProjectFileDescriptor }
TProjectFileDescriptor = class(TPersistent)
@ -370,7 +372,7 @@ function FileDescriptorText: TProjectFileDescriptor;
type
TLazProject = class;
{ TProjectDescriptor }
{ TProjectDescriptor - Template for initializing new projects }
TProjectFlag = (
pfSaveClosedUnits, // save info about closed files (not part of project)
@ -409,7 +411,7 @@ type
end;
{ TLazProject }
{ TLazProject - interface class to a Lazarus project }
TLazProject = class(TPersistent)
private
@ -492,6 +494,7 @@ function ProjectFlagsToStr(Flags: TProjectFlags): string;
implementation
function FileDescriptorUnit: TProjectFileDescriptor;
begin
Result:=ProjectFileDescriptors.FindByName(FileDescNamePascalUnit);
@ -600,6 +603,7 @@ begin
FReferenceCount:=1;
DefaultResFileExt:='.lrs';
AddToProject:=true;
VisibleInNewDialog:=true;
end;
function TProjectFileDescriptor.GetLocalizedName: string;

View File

@ -430,8 +430,6 @@ type
procedure UpdateShowing; override;
procedure DoFirstShow; virtual;
procedure UpdateWindowState;
procedure ValidateRename(AComponent: TComponent;
const CurName, NewName: string); override;
procedure VisibleChanging; override;
procedure WndProc(var TheMessage : TLMessage); override;
function VisibleIsStored: boolean;

View File

@ -52,11 +52,11 @@ type
TFontPitch = (fpDefault, fpVariable, fpFixed);
TFontName = string;
TFontCharSet = 0..255;
TFontDataName = string[LF_FACESIZE -1];
TFontStyle = (fsBold, fsItalic, fsStrikeOut, fsUnderline);
TFontStyles = set of TFontStyle;
TFontStylesbase = set of TFontStyle;
TFontCharSet = 0..255;
TFontData = record
Handle: HFont;
@ -67,6 +67,21 @@ type
Name: TFontDataName;
end;
const
// New TFont instances are initialized with the values in this structure.
// About font default values: The default font is chosen by the interfaces
// depending on the context. For example, there can be a different default
// font for a button and a groupbox.
DefFontData: TFontData = (
Handle: 0;
Height: 0;
Pitch: fpDefault;
Style: [];
Charset: DEFAULT_CHARSET;
Name: 'default'
);
type
{ Reflects text style when drawn in a rectangle }
TTextLayout = (tlTop, tlCenter, tlBottom);
@ -340,21 +355,6 @@ const
cmWhiteness = WHITENESS;
const
// New TFont instances are initialized with the values in this structure.
// About font default values: The default font is chosen by the interfaces
// depending on the context. For example, there can be a different default
// font for a button and a groupbox.
DefFontData: TFontData = (
Handle: 0;
Height: 0;
Pitch: fpDefault;
Style: [];
Charset: DEFAULT_CHARSET;
Name: 'default'
);
type
TCanvas = class;
@ -376,7 +376,7 @@ type
private
FOnChanging: TNotifyEvent;
FOnChange: TNotifyEvent;
Procedure DoChange(var msg); message LM_CHANGED;
Procedure DoChange(var Msg); message LM_CHANGED;
protected
procedure Changing; dynamic;
procedure Changed; dynamic;
@ -1784,6 +1784,9 @@ end.
{ =============================================================================
$Log$
Revision 1.161 2004/11/20 11:20:06 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.160 2004/11/10 18:23:56 mattias
impementing changing a TLabel.Font properties Size, Height, Name, Style - set only at Handle creation time

View File

@ -748,19 +748,6 @@ Begin
FDesigner := Value;
end;
{------------------------------------------------------------------------------
TCustomForm ValidateRename
if AComponent is nil, then the name of Self is changed
------------------------------------------------------------------------------}
procedure TCustomForm.ValidateRename(AComponent: TComponent;
const CurName, NewName: String);
begin
inherited ValidateRename(AComponent, CurName, NewName);
if FDesigner <> nil then
FDesigner.ValidateRename(AComponent, CurName, NewName);
end;
{------------------------------------------------------------------------------
procedure TCustomForm.SetZOrder(Topmost: Boolean);
------------------------------------------------------------------------------}
@ -1833,6 +1820,9 @@ end;
{ =============================================================================
$Log$
Revision 1.165 2004/11/20 11:20:06 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.164 2004/11/10 20:53:18 vincents
Destroy menu handle, when destroying form handle.

View File

@ -1082,9 +1082,9 @@ begin
gtk_label_set_text(ALabel, PChar(Caption));
{$ifdef gtk1}
{$ifdef gtk1}
gtk_label_set_pattern(ALabel, PChar(Pattern));
{$endif gtk1}
{$endif gtk1}
if AComponent = nil then Exit;
if ASignalWidget = nil then Exit;
@ -6324,9 +6324,33 @@ const
var
UseFont : PGDKFont;
UnRef : Boolean;
Width: LongInt;
{procedure UseWidthHeuristic;
var
i: Integer;
l: Integer;
lBearing: LongInt;
rBearing: LongInt;
tmAscent: Longint;
tmDescent: Longint;
CurWidth: integer;
PC: PGdkWChar;
begin
l:=length(TestString[false]);
for i:=1 to l do begin
PC:=PGdkWChar(@TestString[true][i*2-1]);
gdk_text_extents_wc(UseFont, PC,
2, @lBearing, @rBearing, @CurWidth,
@tmAscent, @tmDescent);
debugln('UseWidthHeuristic i=',dbgs(i),' lBearing=',dbgs(lBearing),
' rBearing=',dbgs(rBearing),' CurWidth=',dbgs(CurWidth),' ',HexStr(ord(PC^),8));
end;
end;}
var
AvgTxtLen: Integer;
CachedFont: TGdkFontCacheItem;
width: LongInt;
begin
with TDeviceContext(DC) do begin
if dcfTextMetricsValid in DCFlags then begin
@ -6358,6 +6382,7 @@ begin
gdk_text_extents_wc(UseFont, PGdkWChar(TestString[IsDoubleByteChar]),
AvgTxtLen*2, @lBearing, @rBearing, @Width,
@TextMetric.tmAscent, @TextMetric.tmDescent);
//debugln('TGtkWidgetSet.UpdateDCTextMetric A IsDoubleByteChar=',dbgs(IsDoubleByteChar),' Width=',dbgs(Width),' AvgTxtLen=',dbgs(AvgTxtLen));
TextMetric.tmHeight := gdk_text_height(UseFont,
PChar(TestString[IsDoubleByteChar]),
AvgTxtLen*2)
@ -6371,6 +6396,7 @@ begin
AvgTxtLen)
{$IfNDef Win32} + TextMetric.tmdescent div 2{$EndIf};
end;
//if Width<AvgTxtLen then UseWidthHeuristic;
//TextMetric.tmAscent := TextMetric.tmHeight - TextMetric.tmDescent;
TextMetric.tmAveCharWidth := Width div AvgTxtLen;
if TextMetric.tmAveCharWidth<1 then TextMetric.tmAveCharWidth:=1;
@ -6942,6 +6968,9 @@ end;
{ =============================================================================
$Log$
Revision 1.609 2004/11/20 11:20:06 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.608 2004/11/08 19:11:55 mattias
disabled hardly used gtk FillScreenFont, this should be only done on demand, improved getting default font family for gtk

View File

@ -7183,7 +7183,6 @@ var
NewColor: TGdkColor;
MainWidget: PGtkWidget;
FontHandle: HFONT;
i: Integer;
FreeFontName: boolean;
FreeFontSetName: boolean;
@ -7879,6 +7878,9 @@ end;
{ =============================================================================
$Log$
Revision 1.321 2004/11/20 11:20:06 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.320 2004/11/17 07:46:32 mattias
fixed postcript printer TextOut/TextEntend from Olivier

View File

@ -1574,12 +1574,15 @@ begin
else AverageWidth := InttoStr(lfWidth * 10);
end;
// CharSetRegistry := '*';
// TODO: Match charset.
// CharSetCoding := '*';
if CharSetCoding = '*' then begin
{if lfCharset=fcsISO_8859_2 then begin
CharSetRegistry:='iso8859';
CharSetCoding:='2';
end;}
end;
end;
{$IFDEF VerboseFonts}
write('CreateFontIndirect->');
{$ENDIF}
@ -1632,8 +1635,16 @@ begin
if LoadFont then exit;
// try all spacings
Spacing := '*';
if LoadFont then exit;
if spacing<>'*' then begin
Spacing := '*';
if LoadFont then exit;
end;
if charSetCoding<>'*' then begin
charsetCoding := '*';
charSetRegistry:= '*';
if LoadFont then exit;
end;
if (Foundry<>'*') then begin
// try all Families
@ -8729,6 +8740,9 @@ end;
{ =============================================================================
$Log$
Revision 1.373 2004/11/20 11:20:06 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.372 2004/11/10 18:23:56 mattias
impementing changing a TLabel.Font properties Size, Height, Name, Style - set only at Handle creation time

View File

@ -209,16 +209,16 @@ end;
The interiour of TBitBtn is created with a 4X4 table
Depending in how the image and label are aligned, only a
columns or rows are used (like a 4x1 or 1x4 table).
This wat the table doesn't have to be recreated on changes.
This way the table doesn't have to be recreated on changes.
So there are 4 positions 0, 1, 2, 3.
Positions 1 and 2 are used for the label and image.
Since this is always the case, spacing can be implenented
Since this is always the case, spacing can be implemented
by setting the spacing of row/col 1
To get a margin, a gtkInvisible is needed for bottom and
right, so the invisible is always in position 3.
}
function TGtkWSBitBtn.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): THandle;
function TGtkWSBitBtn.CreateHandle(const AWinControl: TWinControl;
const AParams: TCreateParams): THandle;
var
BitBtn: TCustomBitBtn;
WidgetInfo: PWidgetInfo;
@ -245,7 +245,8 @@ begin
gtk_container_add(BitBtnInfo^.AlignWidget, BitBtnInfo^.TableWidget);
BitBtnInfo^.LabelWidget := gtk_label_new('bitbtn');
gtk_table_attach(BitBtnInfo^.TableWidget, BitBtnInfo^.LabelWidget, 2, 3, 0, 4, 0, 0, 0, 0);
gtk_table_attach(BitBtnInfo^.TableWidget, BitBtnInfo^.LabelWidget,
2, 3, 0, 4, 0, 0, 0, 0);
BitBtnInfo^.SpaceWidget := nil;
BitBtnInfo^.ImageWidget := nil;
@ -293,12 +294,14 @@ begin
// check for image
if BitBtnInfo^.ImageWidget = nil
then begin
BitBtnInfo^.ImageWidget := gtk_pixmap_new(GDIObject^.GDIPixmapObject, GDIObject^.GDIBitmapMaskObject);
BitBtnInfo^.ImageWidget :=
gtk_pixmap_new(GDIObject^.GDIPixmapObject, GDIObject^.GDIBitmapMaskObject);
gtk_widget_show(BitBtnInfo^.ImageWidget);
UpdateLayout(BitBtnInfo, ABitBtn.Layout, ABitBtn.Margin);
end
else begin
gtk_pixmap_set(BitBtnInfo^.ImageWidget, GDIObject^.GDIPixmapObject, GDIObject^.GDIBitmapMaskObject);
gtk_pixmap_set(BitBtnInfo^.ImageWidget, GDIObject^.GDIPixmapObject,
GDIObject^.GDIBitmapMaskObject);
end;
end;
@ -345,7 +348,8 @@ begin
gtk_table_set_row_spacing(BitBtnInfo^.TableWidget, 1, AValue);
end;
procedure TGtkWSBitBtn.SetText(const AWinControl: TWinControl; const AText: String);
procedure TGtkWSBitBtn.SetText(const AWinControl: TWinControl;
const AText: String);
var
WidgetInfo: PWidgetInfo;
BitBtnInfo: PBitBtnWidgetInfo;
@ -357,10 +361,13 @@ begin
BitBtnInfo := WidgetInfo^.UserData;
if BitBtnInfo^.LabelWidget = nil then Exit;
GtkWidgetSet.SetLabelCaption(BitBtnInfo^.LabelWidget, AText, AWinControl, WidgetInfo^.CoreWidget, 'clicked');
//debugln('TGtkWSBitBtn.SetText ',DbgStr(AText));
GtkWidgetSet.SetLabelCaption(BitBtnInfo^.LabelWidget, AText, AWinControl,
WidgetInfo^.CoreWidget, 'clicked');
end;
procedure TGtkWSBitBtn.UpdateLayout(const AInfo: PBitBtnWidgetInfo; const ALayout: TButtonLayout; const AMargin: Integer);
procedure TGtkWSBitBtn.UpdateLayout(const AInfo: PBitBtnWidgetInfo;
const ALayout: TButtonLayout; const AMargin: Integer);
begin
if (AInfo^.ImageWidget = nil)
and (AMargin < 0)
@ -385,27 +392,37 @@ begin
case ALayout of
blGlyphLeft: begin
if AInfo^.ImageWidget <> nil
then gtk_table_attach(AInfo^.TableWidget, AInfo^.ImageWidget, 1, 2, 1, 3, 0, 0, 0, 0);
gtk_table_attach(AInfo^.TableWidget, AInfo^.LabelWidget, 2, 3, 1, 3, 0, 0, 0, 0);
then gtk_table_attach(AInfo^.TableWidget, AInfo^.ImageWidget,
1, 2, 1, 3, 0, 0, 0, 0);
gtk_table_attach(AInfo^.TableWidget, AInfo^.LabelWidget,
2, 3, 1, 3, 0, 0, 0, 0);
end;
blGlyphRight: begin
gtk_table_attach(AInfo^.TableWidget, AInfo^.LabelWidget, 1, 2, 1, 3, 0, 0, 0, 0);
gtk_table_attach(AInfo^.TableWidget, AInfo^.LabelWidget,
1, 2, 1, 3, 0, 0, 0, 0);
if AInfo^.ImageWidget <> nil
then gtk_table_attach(AInfo^.TableWidget, AInfo^.ImageWidget, 2, 3, 1, 3, 0, 0, 0, 0);
then gtk_table_attach(AInfo^.TableWidget, AInfo^.ImageWidget,
2, 3, 1, 3, 0, 0, 0, 0);
if AInfo^.SpaceWidget <> nil
then gtk_table_attach(AInfo^.TableWidget, AInfo^.SpaceWidget, 3, 4, 1, 3, 0, 0, 0, 0);
then gtk_table_attach(AInfo^.TableWidget, AInfo^.SpaceWidget,
3, 4, 1, 3, 0, 0, 0, 0);
end;
blGlyphTop: begin
if AInfo^.ImageWidget <> nil
then gtk_table_attach(AInfo^.TableWidget, AInfo^.ImageWidget, 1, 3, 1, 2, 0, 0, 0, 0);
gtk_table_attach(AInfo^.TableWidget, AInfo^.LabelWidget, 1, 3, 2, 3, 0, 0, 0, 0);
then gtk_table_attach(AInfo^.TableWidget, AInfo^.ImageWidget,
1, 3, 1, 2, 0, 0, 0, 0);
gtk_table_attach(AInfo^.TableWidget, AInfo^.LabelWidget,
1, 3, 2, 3, 0, 0, 0, 0);
end;
blGlyphBottom: begin
gtk_table_attach(AInfo^.TableWidget, AInfo^.LabelWidget, 1, 3, 1, 2, 0, 0, 0, 0);
gtk_table_attach(AInfo^.TableWidget, AInfo^.LabelWidget,
1, 3, 1, 2, 0, 0, 0, 0);
if AInfo^.ImageWidget <> nil
then gtk_table_attach(AInfo^.TableWidget, AInfo^.ImageWidget, 1, 3, 2, 3, 0, 0, 0, 0);
then gtk_table_attach(AInfo^.TableWidget, AInfo^.ImageWidget,
1, 3, 2, 3, 0, 0, 0, 0);
if AInfo^.SpaceWidget <> nil
then gtk_table_attach(AInfo^.TableWidget, AInfo^.SpaceWidget, 1, 3, 3, 4, 0, 0, 0, 0);
then gtk_table_attach(AInfo^.TableWidget, AInfo^.SpaceWidget,
1, 3, 3, 4, 0, 0, 0, 0);
end;
end;
@ -420,7 +437,8 @@ begin
then UpdateMargin(AInfo, ALayout, AMargin)
end;
procedure TGtkWSBitBtn.UpdateMargin(const AInfo: PBitBtnWidgetInfo; const ALayout: TButtonLayout; const AMargin: Integer);
procedure TGtkWSBitBtn.UpdateMargin(const AInfo: PBitBtnWidgetInfo;
const ALayout: TButtonLayout; const AMargin: Integer);
begin
if AMargin < 0
then begin

View File

@ -19,6 +19,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
*****************************************************************************
Defines the base class for all LCL TComponents including controls.
}
unit LCLClasses;

View File

@ -1170,7 +1170,6 @@ const
EASTEUROPE_CHARSET = 238;
OEM_CHARSET = 255;
//-----------
// Font Sets
//-----------
@ -2248,6 +2247,9 @@ end.
{
$Log$
Revision 1.68 2004/11/20 11:20:06 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.67 2004/09/18 10:52:48 micha
convert LM_SCREENINIT message to interface method (integrated with TWidgetSet.AppInit(var ScreenInfo)

View File

@ -49,14 +49,14 @@ uses
// codetools
CodeToolManager, CodeCache, BasicCodeTools, Laz_XMLCfg, OldAvLTree,
// IDE Interface
ProjectIntf, LazIDEIntf,
ProjectIntf, PackageIntf, LazIDEIntf,
// IDE
LazConf, LazarusIDEStrConsts, IDEProcs, ObjectLists, DialogProcs, KeyMapping,
EnvironmentOpts, MiscOptions, InputHistory, ProjectDefs, Project,
ComponentReg, UComponentManMain, PackageEditor, AddToPackageDlg, PackageDefs,
PackageLinks, PackageSystem, OpenInstalledPkgDlg, PkgGraphExplorer,
BrokenDependenciesDlg, CompilerOptions, ExtToolEditDlg,
MsgView, BuildLazDialog, DefineTemplates,
MsgView, BuildLazDialog, DefineTemplates, NewDialog,
ProjectInspector, ComponentPalette, UnitEditor, AddFileToAPackageDlg,
LazarusPackageIntf, PublishProjectDlg,
// bosses
@ -250,6 +250,42 @@ type
ShowDialog: boolean): TModalResult;
end;
{ TLazPackageDescriptors }
TLazPackageDescriptors = class(TPackageDescriptors)
private
fDestroying: boolean;
fItems: TList; // list of TProjectDescriptor
protected
function GetItems(Index: integer): TPackageDescriptor; override;
public
constructor Create;
destructor Destroy; override;
function Count: integer; override;
function GetUniqueName(const Name: string): string; override;
function IndexOf(const Name: string): integer; override;
function FindByName(const Name: string): TPackageDescriptor; override;
procedure RegisterDescriptor(Descriptor: TPackageDescriptor); override;
procedure UnregisterDescriptor(Descriptor: TPackageDescriptor); override;
procedure AddDefaultPackageDescriptors;
public
property Items[Index: integer]: TPackageDescriptor read GetItems; default;
end;
{ TPackageDescriptorStd }
TPackageDescriptorStd = class(TPackageDescriptor)
public
constructor Create; override;
function GetLocalizedName: string; override;
function GetLocalizedDescription: string; override;
end;
var
LazPackageDescriptors: TLazPackageDescriptors;
implementation
{ TPkgManager }
@ -1569,6 +1605,9 @@ begin
CodeToolBoss.DefineTree.MacroFunctions.AddExtended(
'PKGINCPATH',nil,@MacroFunctionPkgIncPath);
LazPackageDescriptors:=TLazPackageDescriptors.Create;
LazPackageDescriptors.AddDefaultPackageDescriptors;
// idle handler
Application.AddOnIdleHandler(@OnApplicationIdle,true);
end;
@ -1577,6 +1616,7 @@ destructor TPkgManager.Destroy;
var
Dependency: TPkgDependency;
begin
FreeThenNil(LazPackageDescriptors);
while FirstAutoInstallDependency<>nil do begin
Dependency:=FirstAutoInstallDependency;
Dependency.RequiredPackage:=nil;
@ -3371,5 +3411,129 @@ begin
Result:=mrOk;
end;
{ TLazPackageDescriptors }
function TLazPackageDescriptors.GetItems(Index: integer): TPackageDescriptor;
begin
Result:=TPackageDescriptor(FItems[Index]);
end;
constructor TLazPackageDescriptors.Create;
begin
PackageDescriptors:=Self;
FItems:=TList.Create;
end;
destructor TLazPackageDescriptors.Destroy;
var
i: Integer;
begin
fDestroying:=true;
for i:=Count-1 downto 0 do Items[i].Release;
FItems.Free;
FItems:=nil;
PackageDescriptors:=nil;
inherited Destroy;
end;
function TLazPackageDescriptors.Count: integer;
begin
Result:=FItems.Count;
end;
function TLazPackageDescriptors.GetUniqueName(const Name: string): string;
var
i: Integer;
begin
Result:=Name;
if IndexOf(Result)<0 then exit;
i:=0;
repeat
inc(i);
Result:=Name+IntToStr(i);
until IndexOf(Result)<0;
end;
function TLazPackageDescriptors.IndexOf(const Name: string): integer;
begin
Result:=Count-1;
while (Result>=0) and (AnsiCompareText(Name,Items[Result].Name)<>0) do
dec(Result);
end;
function TLazPackageDescriptors.FindByName(const Name: string
): TPackageDescriptor;
var
i: LongInt;
begin
i:=IndexOf(Name);
if i>=0 then
Result:=Items[i]
else
Result:=nil;
end;
procedure TLazPackageDescriptors.RegisterDescriptor(
Descriptor: TPackageDescriptor);
begin
if Descriptor.Name='' then
raise Exception.Create('TLazPackageDescriptors.RegisterDescriptor Descriptor.Name empty');
Descriptor.Name:=GetUniqueName(Descriptor.Name);
FItems.Add(Descriptor);
end;
procedure TLazPackageDescriptors.UnregisterDescriptor(
Descriptor: TPackageDescriptor);
var
i: LongInt;
begin
if fDestroying then exit;
i:=FItems.IndexOf(Descriptor);
if i<0 then
raise Exception.Create('TLazPackageDescriptors.UnregisterDescriptor');
FItems.Delete(i);
Descriptor.Release;
end;
procedure TLazPackageDescriptors.AddDefaultPackageDescriptors;
var
i: Integer;
NewItem: TNewItemPackage;
PkgItem: TPackageDescriptor;
begin
// standard package
RegisterDescriptor(TPackageDescriptorStd.Create);
// register in new dialog: package category
NewIDEItems.Add(TNewIDEItemCategoryPackage.Create('Package'));
// register in new dialog: all package templates
for i:=0 to Count-1 do begin
PkgItem:=Items[i];
if not PkgItem.VisibleInNewDialog then continue;
NewItem:=TNewItemPackage.Create(PkgItem.Name,niifCopy,[niifCopy]);
NewItem.Descriptor:=PkgItem;
RegisterNewDialogItem('Package',NewItem);
end;
end;
{ TPackageDescriptorStd }
constructor TPackageDescriptorStd.Create;
begin
inherited Create;
Name:=PkgDescNameStandard;
end;
function TPackageDescriptorStd.GetLocalizedName: string;
begin
Result:='Package';
end;
function TPackageDescriptorStd.GetLocalizedDescription: string;
begin
Result:=Format(lisNewDlgCreateANewStandardPackageAPackageIsACollectionOfUn,
[#13]);
end;
end.

View File

@ -15,8 +15,12 @@ BuildRoot: %{_tmppath}/fpcsrc-build%{version}
# The normal redhat rpm scripts tests every installed file for requirements.
# We install only sources, so we don't need the requirements.
# But it seems, RPM ignores these macros:
# %define _use_internal_dependency_generator 0
%define __find_provides /tmp/do_nothing.sh
%define __find_requires /tmp/do_nothing.sh
# %define __find_requires %{nil}
# AutoReq: 0
# The normal redhat rpm scripts do not recognize properly, what files to strip
# Hook our own strip command