lazarus/components/ideintf/unitresources.pas
2020-03-23 20:33:04 +00:00

190 lines
6.5 KiB
ObjectPascal

{
*****************************************************************************
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
Author:
Joost van der Sluis
Abstract:
Change the resource type (e.g. .lfm) of forms.
Every unit can have one resource file. Default is .lfm.
This unit allows to define other formats, like .xib.
}
unit UnitResources;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,
// LCL
LCLMemManager, Forms, LResources,
// LazUtils
UITypes;
type
{ TUnitResourcefileFormat }
TUnitResourcefileFormat = class
public
class function FindResourceDirective(Source: TObject): boolean; virtual; abstract;
class function GetUnitResourceFilename(AUnitFilename: string; Loading: boolean): string; virtual; abstract;
class procedure TextStreamToBinStream(ATxtStream, ABinStream: TExtMemoryStream); virtual; abstract;
class procedure BinStreamToTextStream(ABinStream, ATxtStream: TExtMemoryStream); virtual; abstract;
class function GetClassNameFromStream(s: TStream; out IsInherited: Boolean): shortstring; virtual; abstract;
class function CreateReader(s: TStream; var DestroyDriver: boolean): TReader; virtual; abstract;
class function CreateWriter(s: TStream; var DestroyDriver: boolean): TWriter; virtual; abstract;
class function QuickCheckResourceBuffer(
PascalBuffer, LFMBuffer: TObject; // TCodeBuffer
out LFMType, LFMComponentName, LFMClassName: string;
out LCLVersion: string;
out MissingClasses: TStrings// e.g. MyFrame2:TMyFrame
): TModalResult; virtual; abstract;
class function Priority: integer; virtual; // higher priority is tested first
class function DefaultComponentClass: TComponentClass; virtual;
class function FindComponentClass({%H-}aClassName: string): TComponentClass; virtual;
end;
TUnitResourcefileFormatClass = class of TUnitResourcefileFormat;
TUnitResourcefileFormatArr = array of TUnitResourcefileFormatClass;
{ TCustomLFMUnitResourceFileFormat }
TCustomLFMUnitResourceFileFormat = class(TUnitResourcefileFormat)
public
class function ResourceDirectiveFilename: string; virtual;
class function GetUnitResourceFilename(AUnitFilename: string; {%H-}Loading: boolean): string; override;
class procedure TextStreamToBinStream(ATxtStream, ABinStream: TExtMemoryStream); override;
class procedure BinStreamToTextStream(ABinStream, ATxtStream: TExtMemoryStream); override;
class function GetClassNameFromStream(s: TStream; out IsInherited: Boolean): shortstring; override;
class function CreateReader(s: TStream; var DestroyDriver: boolean): TReader; override;
class function CreateWriter(s: TStream; var DestroyDriver: boolean): TWriter; override;
class function DefaultComponentClass: TComponentClass; override;
class function FindComponentClass(aClassName: string): TComponentClass; override;
end;
var
LFMUnitResourceFileFormat: TUnitResourcefileFormatClass = nil;// set by IDE
procedure RegisterUnitResourcefileFormat(AResourceFileFormat: TUnitResourcefileFormatClass);
function GetUnitResourcefileFormats: TUnitResourcefileFormatArr;
implementation
uses
FormEditingIntf;
var
GUnitResourcefileFormats: TUnitResourcefileFormatArr;
procedure RegisterUnitResourcefileFormat(AResourceFileFormat: TUnitResourcefileFormatClass);
var
i: Integer;
Priority: Integer;
l: Integer;
begin
Priority:=AResourceFileFormat.Priority;
i:=0;
while (i<length(GUnitResourcefileFormats))
and (GUnitResourcefileFormats[i].Priority>=Priority) do
inc(i);
l:=length(GUnitResourcefileFormats)-i;
SetLength(GUnitResourcefileFormats, length(GUnitResourcefileFormats)+1);
if l>0 then
System.Move(GUnitResourcefileFormats[i],GUnitResourcefileFormats[i+1],
l*SizeOf(TUnitResourcefileFormatClass));
GUnitResourcefileFormats[high(GUnitResourcefileFormats)] := AResourceFileFormat;
end;
function GetUnitResourcefileFormats: TUnitResourcefileFormatArr;
begin
Result := GUnitResourcefileFormats;
end;
{ TCustomLFMUnitResourceFileFormat }
class function TCustomLFMUnitResourceFileFormat.ResourceDirectiveFilename: string;
// Note: $R uses fpcres, which supports only a few formats like dfm and lfm.
// In other words: If you want other formats you need to extend fpcres or use
// other storages like include files (e.g. like the old lrs format).
begin
Result := '*.lfm';
end;
class function TCustomLFMUnitResourceFileFormat.GetUnitResourceFilename(
AUnitFilename: string; Loading: boolean): string;
begin
Result := ChangeFileExt(AUnitFilename,'.lfm');
end;
class procedure TCustomLFMUnitResourceFileFormat.TextStreamToBinStream(ATxtStream,
ABinStream: TExtMemoryStream);
begin
LRSObjectTextToBinary(ATxtStream,ABinStream);
end;
class procedure TCustomLFMUnitResourceFileFormat.BinStreamToTextStream(ABinStream,
ATxtStream: TExtMemoryStream);
begin
LRSObjectBinaryToText(ABinStream,ATxtStream);
end;
class function TCustomLFMUnitResourceFileFormat.GetClassNameFromStream(s: TStream;
out IsInherited: Boolean): shortstring;
begin
Result := GetClassNameFromLRSStream(s,IsInherited);
end;
class function TCustomLFMUnitResourceFileFormat.CreateReader(s: TStream;
var DestroyDriver: boolean): TReader;
begin
Result := CreateLRSReader(s,DestroyDriver);
end;
class function TCustomLFMUnitResourceFileFormat.CreateWriter(s: TStream;
var DestroyDriver: boolean): TWriter;
begin
Result := CreateLRSWriter(s, DestroyDriver);
end;
class function TCustomLFMUnitResourceFileFormat.DefaultComponentClass: TComponentClass;
begin
Result := FormEditingHook.StandardDesignerBaseClasses[DesignerBaseClassId_TForm];
end;
class function TCustomLFMUnitResourceFileFormat.FindComponentClass(
aClassName: string): TComponentClass;
begin
if CompareText(aClassName,'TForm')=0 then
Result:=FormEditingHook.StandardDesignerBaseClasses[DesignerBaseClassId_TForm]
else if CompareText(aClassName,'TFrame')=0 then
Result:=FormEditingHook.StandardDesignerBaseClasses[DesignerBaseClassId_TFrame]
else if CompareText(aClassName,'TDataModule')=0 then
Result:=FormEditingHook.StandardDesignerBaseClasses[DesignerBaseClassId_TDataModule]
else
Result:=nil;
end;
{ TUnitResourcefileFormat }
class function TUnitResourcefileFormat.Priority: integer;
begin
Result:=0;
end;
class function TUnitResourcefileFormat.DefaultComponentClass: TComponentClass;
begin
Result:=TForm;
end;
class function TUnitResourcefileFormat.FindComponentClass(aClassName: string): TComponentClass;
begin
Result:=nil;
end;
end.