dexed/src/ce_common.pas

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.