mirror of https://gitlab.com/basile.b/dexed.git
295 lines
5.9 KiB
Plaintext
295 lines
5.9 KiB
Plaintext
unit ce_common;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, ActnList, dialogs, forms;
|
|
|
|
const
|
|
|
|
DdiagFilter = 'D source|*.d|D interface|*.di|All files|*.*';
|
|
|
|
type
|
|
|
|
(**
|
|
* MRU list for strings
|
|
*)
|
|
TMRUList = class(TStringList)
|
|
private
|
|
fMaxCount: Integer;
|
|
protected
|
|
procedure setMaxCount(aValue: Integer);
|
|
function checkItem(const S: string): boolean; virtual;
|
|
procedure Put(Index: Integer; const S: string); override;
|
|
published
|
|
property maxCount: Integer read fMaxCount write setMaxCount;
|
|
public
|
|
constructor Create;
|
|
procedure Insert(Index: Integer; const S: string); override;
|
|
end;
|
|
|
|
(**
|
|
* MRU list for filenames
|
|
*)
|
|
TMRUFileList = class(TMRUList)
|
|
protected
|
|
function checkItem(const S: string): boolean; override;
|
|
end;
|
|
|
|
(**
|
|
* Save a component with a readable aspect.
|
|
*)
|
|
procedure saveCompToTxtFile(const aComp: TComponent; const aFilename: string);
|
|
|
|
(**
|
|
* Load a component.
|
|
*)
|
|
procedure loadCompFromTxtFile(const aComp: TComponent; const aFilename: string);
|
|
|
|
(**
|
|
* Converts a relative path to an absolute path.
|
|
*)
|
|
function expandFilenameEx(const aBasePath, aFilename: string): string;
|
|
|
|
(**
|
|
* Extracts the module name of a D source file.
|
|
*)
|
|
function getModuleName(const aSource: TStrings): string;
|
|
|
|
(**
|
|
* Patches the directory separators from a string.
|
|
* This is used to ensure that a project saved on a platform can be loaded
|
|
* on another one.
|
|
*)
|
|
function patchPlateformPath(const aPath: string): string;
|
|
procedure patchPlateformPaths(const sPaths: TStrings);
|
|
|
|
(**
|
|
* Ok/Cancel modal dialog
|
|
*)
|
|
function dlgOkCancel(const aMsg: string): TModalResult;
|
|
|
|
(**
|
|
* Info dialog
|
|
*)
|
|
function dlgOkInfo(const aMsg: string): TModalResult;
|
|
|
|
(**
|
|
* Returns an unique object identifier, based on its heap address.
|
|
*)
|
|
function uniqueObjStr(const aObject: Tobject): string;
|
|
|
|
implementation
|
|
|
|
constructor TMRUList.Create;
|
|
begin
|
|
fMaxCount := 10;
|
|
end;
|
|
|
|
procedure TMRUList.setMaxCount(aValue: Integer);
|
|
begin
|
|
if aValue < 0 then aValue := 0;
|
|
if fMaxCount = aValue then exit;
|
|
while Count > fMaxCount do delete(Count-1);
|
|
end;
|
|
|
|
function TMRUList.checkItem(const S: string): boolean;
|
|
begin
|
|
exit( indexOf(S) = -1 );
|
|
end;
|
|
|
|
procedure TMRUList.Put(Index: Integer; const S: string);
|
|
begin
|
|
if not (checkItem(S)) then exit;
|
|
inherited;
|
|
while Count > fMaxCount do delete(Count-1);
|
|
end;
|
|
|
|
procedure TMRUList.Insert(Index: Integer; const S: string);
|
|
begin
|
|
if not (checkItem(S)) then exit;
|
|
inherited;
|
|
while Count > fMaxCount do delete(Count-1);
|
|
end;
|
|
|
|
function TMRUFileList.checkItem(const S: string): boolean;
|
|
begin
|
|
exit( inherited checkItem(S) and fileExists(S));
|
|
end;
|
|
|
|
|
|
procedure saveCompToTxtFile(const aComp: TComponent; const aFilename: string);
|
|
var
|
|
str1, str2: TMemoryStream;
|
|
begin
|
|
str1 := TMemoryStream.Create;
|
|
str2 := TMemoryStream.Create;
|
|
try
|
|
str1.WriteComponent(aComp);
|
|
str1.Position := 0;
|
|
ObjectBinaryToText(str1,str2);
|
|
str2.SaveToFile(aFilename);
|
|
finally
|
|
str1.Free;
|
|
str2.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure loadCompFromTxtFile(const aComp: TComponent; const aFilename: string);
|
|
var
|
|
str1, str2: TMemoryStream;
|
|
begin
|
|
str1 := TMemoryStream.Create;
|
|
str2 := TMemoryStream.Create;
|
|
try
|
|
str1.LoadFromFile(aFilename);
|
|
str1.Position := 0;
|
|
ObjectTextToBinary(str1,str2);
|
|
str2.Position := 0;
|
|
try
|
|
str2.ReadComponent(aComp);
|
|
except
|
|
end;
|
|
finally
|
|
str1.Free;
|
|
str2.Free;
|
|
end;
|
|
end;
|
|
|
|
function expandFilenameEx(const aBasePath, aFilename: string): string;
|
|
var
|
|
curr: string;
|
|
begin
|
|
curr := '';
|
|
getDir(0,curr);
|
|
try
|
|
if curr <> aBasePath then
|
|
chDir(aBasePath);
|
|
result := expandFileName(aFilename);
|
|
finally
|
|
chDir(curr);
|
|
end;
|
|
end;
|
|
|
|
function patchPlateformPath(const aPath: string): string;
|
|
function patchProc(const src: string; const invalid: char): string;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
result := src;
|
|
i := pos(invalid, result);
|
|
if i <> 0 then
|
|
begin
|
|
repeat
|
|
result[i] := directorySeparator;
|
|
i := pos(invalid,result);
|
|
until
|
|
i = 0;
|
|
end;
|
|
end;
|
|
begin
|
|
result := aPath;
|
|
{$IFDEF MSWINDOWS}
|
|
result := patchProc(result,'/');
|
|
result := patchProc(result,':');
|
|
{$ENDIF}
|
|
{$IFDEF LINUX}
|
|
result := patchProc(result,'\');
|
|
result := patchProc(result,':');
|
|
{$ENDIF}
|
|
{$IFDEF MACOS}
|
|
result := patchProc(result,'\');
|
|
result := patchProc(result,'/');
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure patchPlateformPaths(const sPaths: TStrings);
|
|
var
|
|
i: Integer;
|
|
str: string;
|
|
begin
|
|
for i:= 0 to sPaths.Count-1 do
|
|
begin
|
|
str := sPaths.Strings[i];
|
|
sPaths.Strings[i] := patchPlateformPath(str);
|
|
end;
|
|
end;
|
|
|
|
// TODO: block comments handling
|
|
function getModuleName(const aSource: TStrings): string;
|
|
var
|
|
ln: string;
|
|
pos, lcnt: NativeInt;
|
|
id: string;
|
|
tok: boolean;
|
|
begin
|
|
result := '';
|
|
tok := false;
|
|
lcnt := -1;
|
|
for ln in aSource do
|
|
begin
|
|
pos := 1;
|
|
id := '';
|
|
lcnt += 1;
|
|
if lcnt > 100 then exit;
|
|
|
|
while(true) do
|
|
begin
|
|
if pos > length(ln) then
|
|
break;
|
|
|
|
if ln[pos] in [#0..#32] then
|
|
begin
|
|
Inc(pos);
|
|
id := '';
|
|
continue;
|
|
end;
|
|
|
|
if tok then if ln[pos] = ';' then
|
|
exit(id);
|
|
|
|
id += ln[pos];
|
|
Inc(pos);
|
|
|
|
if id = '//' then
|
|
begin
|
|
Inc(pos, length(ln));
|
|
break;
|
|
end;
|
|
|
|
if id = 'module' then
|
|
begin
|
|
tok := true;
|
|
id := '';
|
|
continue;
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function dlgOkCancel(const aMsg: string): TModalResult;
|
|
const
|
|
Btns = [mbOK,mbCancel];
|
|
begin
|
|
exit( MessageDlg('Coedit', aMsg, mtConfirmation, Btns, ''));
|
|
end;
|
|
|
|
function dlgOkInfo(const aMsg: string): TModalResult;
|
|
const
|
|
Btns = [mbOK];
|
|
begin
|
|
exit( MessageDlg('Coedit', aMsg, mtInformation, Btns, ''));
|
|
end;
|
|
|
|
function uniqueObjStr(const aObject: Tobject): string;
|
|
begin
|
|
{$HINTS OFF}{$WARNINGS OFF}
|
|
exit( format('%.8X',[NativeUint(@aObject)]));
|
|
{$HINTS ON}{$WARNINGS ON}
|
|
end;
|
|
|
|
end.
|