mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 23:58:06 +02:00

IDE, SourceEditor: fixed hints. Mouse can move into hint area. Issue #0030077 / broken by revision 49872 #d5bd14f7ac ........ ide: Normalize path delims of resource items ........ git-svn-id: branches/fixes_1_6@52459 -
286 lines
8.9 KiB
ObjectPascal
286 lines
8.9 KiB
ObjectPascal
{
|
|
/***************************************************************************
|
|
projectuserresources.pas - Lazarus IDE unit
|
|
---------------------------------------
|
|
TProjectUserResources is responsible for the inclusion of the
|
|
custom resources in executables as res file
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code 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. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
* *
|
|
***************************************************************************
|
|
}
|
|
unit ProjectUserResources;
|
|
|
|
{$mode objfpc}{$H+}
|
|
{$modeswitch advancedrecords}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Laz2_XMLCfg, LCLProc, FileProcs, LazFileUtils, LazUTF8,
|
|
ProjectResourcesIntf, IDEMsgIntf, MacroIntf, IDEExternToolIntf,
|
|
LazarusIDEStrConsts, resource, bitmapresource, groupresource,
|
|
groupiconresource, groupcursorresource;
|
|
|
|
type
|
|
TUserResourceType = (
|
|
rtIcon, // maps to RT_GROUP_ICON
|
|
rtCursor, // maps to RT_GROUP_CURSOR
|
|
rtBitmap, // maps to RT_BITMAP
|
|
rtHTML, // maps to RT_HTML
|
|
rtRCData // maps to RT_RCDATA
|
|
);
|
|
PResourceItem = ^TResourceItem;
|
|
|
|
{ TResourceItem }
|
|
|
|
TResourceItem = record
|
|
public
|
|
FileName: String;
|
|
ResType: TUserResourceType;
|
|
ResName: String;
|
|
procedure ReadFromProjectFile(AConfig: TXMLConfig; Path: String);
|
|
procedure WriteToProjectFile(AConfig: TXMLConfig; Path: String);
|
|
function CreateResource(ProjectDirectory: String): TAbstractResource;
|
|
function GetRealFileName(ProjectDirectory: String): String;
|
|
end;
|
|
|
|
{ TResourceList }
|
|
|
|
TResourceList = class(TList)
|
|
private
|
|
function GetItem(AIndex: Integer): PResourceItem;
|
|
protected
|
|
procedure Notify(Ptr: Pointer; Action: TListNotification); override;
|
|
public
|
|
function AddItem: PResourceItem;
|
|
procedure AddResource(FileName: String; ResType: TUserResourceType; ResName: String);
|
|
property Items[AIndex: Integer]: PResourceItem read GetItem; default;
|
|
end;
|
|
|
|
{ TProjectUserResources }
|
|
|
|
TProjectUserResources = class(TAbstractProjectResource)
|
|
private
|
|
FList: TResourceList;
|
|
public
|
|
constructor Create; override;
|
|
destructor Destroy; override;
|
|
|
|
function UpdateResources(AResources: TAbstractProjectResources;
|
|
const MainFilename: string): Boolean; override;
|
|
procedure WriteToProjectFile(AConfig: {TXMLConfig}TObject; Path: String); override;
|
|
procedure ReadFromProjectFile(AConfig: {TXMLConfig}TObject; Path: String); override;
|
|
property List: TResourceList read FList;
|
|
end;
|
|
|
|
const
|
|
ResourceTypeToStr: array[TUserResourceType] of String = (
|
|
{ rtIcon } 'ICON',
|
|
{ rtCursor } 'CURSOR',
|
|
{ rtBitmap } 'BITMAP',
|
|
{ rtHTML } 'HTML',
|
|
{ rtRCData } 'RCDATA'
|
|
);
|
|
|
|
function StrToResourceType(AStr: String): TUserResourceType;
|
|
|
|
implementation
|
|
|
|
function StrToResourceType(AStr: String): TUserResourceType;
|
|
begin
|
|
case AStr of
|
|
'ICON': Result := rtIcon;
|
|
'CURSOR': Result := rtCursor;
|
|
'BITMAP': Result := rtBitmap;
|
|
'HTML': Result := rtHTML;
|
|
else
|
|
Result := rtRCData;
|
|
end;
|
|
end;
|
|
|
|
{ TResourceItem }
|
|
|
|
procedure TResourceItem.ReadFromProjectFile(AConfig: TXMLConfig; Path: String);
|
|
begin
|
|
FileName := AConfig.GetValue(Path + 'FileName', '');
|
|
ResType := StrToResourceType(AConfig.GetValue(Path + 'Type', ''));
|
|
ResName := AConfig.GetValue(Path + 'ResourceName', '');
|
|
end;
|
|
|
|
procedure TResourceItem.WriteToProjectFile(AConfig: TXMLConfig; Path: String);
|
|
begin
|
|
AConfig.SetValue(Path + 'FileName', FileName);
|
|
AConfig.SetValue(Path + 'Type', ResourceTypeToStr[ResType]);
|
|
AConfig.SetValue(Path + 'ResourceName', ResName);
|
|
end;
|
|
|
|
function TResourceItem.CreateResource(ProjectDirectory: String): TAbstractResource;
|
|
var
|
|
Stream: TFileStream;
|
|
TypeDesc, NameDesc: TResourceDesc;
|
|
RealFileName: String;
|
|
begin
|
|
Result := nil;
|
|
|
|
RealFileName := GetRealFileName(ProjectDirectory);
|
|
|
|
if FileExistsUTF8(RealFileName) then
|
|
begin
|
|
Stream := TFileStream.Create(UTF8ToSys(RealFileName), fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
NameDesc := TResourceDesc.Create(ResName);
|
|
case ResType of
|
|
rtIcon:
|
|
begin
|
|
Result := TGroupIconResource.Create(nil, NameDesc);
|
|
TGroupResource(Result).ItemData.CopyFrom(Stream, Stream.Size)
|
|
end;
|
|
rtCursor:
|
|
begin
|
|
Result := TGroupCursorResource.Create(nil, NameDesc);
|
|
TGroupResource(Result).ItemData.CopyFrom(Stream, Stream.Size)
|
|
end;
|
|
rtBitmap:
|
|
begin
|
|
Result := TBitmapResource.Create(nil, NameDesc);
|
|
TBitmapResource(Result).BitmapData.CopyFrom(Stream, Stream.Size);
|
|
end;
|
|
rtHTML:
|
|
begin
|
|
TypeDesc := TResourceDesc.Create(RT_HTML);
|
|
Result := TGenericResource.Create(TypeDesc, NameDesc);
|
|
TypeDesc.Free;
|
|
TGenericResource(Result).RawData.CopyFrom(Stream, Stream.Size)
|
|
end;
|
|
rtRCData:
|
|
begin
|
|
TypeDesc := TResourceDesc.Create(RT_RCDATA);
|
|
Result := TGenericResource.Create(TypeDesc, NameDesc);
|
|
TypeDesc.Free;
|
|
TGenericResource(Result).RawData.CopyFrom(Stream, Stream.Size)
|
|
end;
|
|
end;
|
|
NameDesc.Free;
|
|
finally
|
|
Stream.Free;
|
|
end;
|
|
end
|
|
else
|
|
AddIDEMessage(mluError,Format(lisFileNotFound2, [Filename]));
|
|
end;
|
|
|
|
function TResourceItem.GetRealFileName(ProjectDirectory: String): String;
|
|
begin
|
|
Result := FileName;
|
|
if not IDEMacros.SubstituteMacros(Result) then
|
|
debugln(['TResourceItem.GetRealFileName failed FileName="', FileName, '"']);
|
|
Result := TrimFilename(Result);
|
|
ForcePathDelims(Result);
|
|
if not FilenameIsAbsolute(Result) then
|
|
Result := TrimFilename(AppendPathDelim(ProjectDirectory) + Result);
|
|
end;
|
|
|
|
{ TResourceList }
|
|
|
|
function TResourceList.GetItem(AIndex: Integer): PResourceItem;
|
|
begin
|
|
Result := PResourceItem(inherited Get(AIndex));
|
|
end;
|
|
|
|
procedure TResourceList.Notify(Ptr: Pointer; Action: TListNotification);
|
|
begin
|
|
if Action = lnDeleted then
|
|
Dispose(PResourceItem(Ptr))
|
|
else
|
|
inherited Notify(Ptr, Action);
|
|
end;
|
|
|
|
function TResourceList.AddItem: PResourceItem;
|
|
begin
|
|
New(Result);
|
|
Add(Result);
|
|
end;
|
|
|
|
procedure TResourceList.AddResource(FileName: String; ResType: TUserResourceType;
|
|
ResName: String);
|
|
var
|
|
Data: PResourceItem;
|
|
begin
|
|
Data := AddItem;
|
|
Data^.FileName := FileName;
|
|
Data^.ResType := ResType;
|
|
Data^.ResName := ResName;
|
|
end;
|
|
|
|
function TProjectUserResources.UpdateResources(AResources: TAbstractProjectResources; const MainFilename: string): Boolean;
|
|
var
|
|
I: Integer;
|
|
ARes: TAbstractResource;
|
|
ProjectDirectory: String;
|
|
begin
|
|
Result := True;
|
|
ProjectDirectory := ExtractFilePath(MainFileName);
|
|
for I := 0 to List.Count - 1 do
|
|
begin
|
|
ARes := List[I]^.CreateResource(ProjectDirectory);
|
|
if Assigned(ARes) then
|
|
AResources.AddSystemResource(ARes);
|
|
end;
|
|
end;
|
|
|
|
procedure TProjectUserResources.WriteToProjectFile(AConfig: TObject; Path: String);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
TXMLConfig(AConfig).SetDeleteValue(Path+'General/Resources/Count', List.Count, 0);
|
|
for I := 0 to List.Count - 1 do
|
|
List[I]^.WriteToProjectFile(TXMLConfig(AConfig), Path + 'General/Resources/Resource_' + IntToStr(I) + '/')
|
|
end;
|
|
|
|
procedure TProjectUserResources.ReadFromProjectFile(AConfig: TObject; Path: String);
|
|
var
|
|
I, Count: Integer;
|
|
begin
|
|
List.Clear;
|
|
Count := TXMLConfig(AConfig).GetValue(Path+'General/Resources/Count', 0);
|
|
for I := 0 to Count - 1 do
|
|
List.AddItem^.ReadFromProjectFile(TXMLConfig(AConfig), Path + 'General/Resources/Resource_' + IntToStr(I) + '/')
|
|
end;
|
|
|
|
constructor TProjectUserResources.Create;
|
|
begin
|
|
inherited Create;
|
|
FList := TResourceList.Create;
|
|
end;
|
|
|
|
destructor TProjectUserResources.Destroy;
|
|
begin
|
|
FList.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
initialization
|
|
RegisterProjectResource(TProjectUserResources);
|
|
|
|
end.
|
|
|