mirror of https://gitlab.com/basile.b/dexed.git
287 lines
6.2 KiB
Plaintext
287 lines
6.2 KiB
Plaintext
unit ce_common;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, ActnList, dialogs, forms, controls;
|
|
|
|
const
|
|
|
|
DdiagFilter = 'D source|*.d|D interface|*.di|All files|*.*';
|
|
|
|
type
|
|
|
|
(**
|
|
* MRU list for strings
|
|
*)
|
|
TMRUList = class(TStringList)
|
|
private
|
|
fMaxCount: Integer;
|
|
fObj: TObject;
|
|
protected
|
|
fChecking: boolean;
|
|
procedure clearOutOfRange;
|
|
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;
|
|
property objectTag: TObject read fObj write fObj;
|
|
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;
|
|
|
|
(**
|
|
* 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;
|
|
|
|
(**
|
|
* Reduce a filename if its length is over the threshold defined by charThresh.
|
|
* Even if the result is not usable anymore, it avoids any "visually-overloaded" MRU menus.
|
|
*)
|
|
function displayShortFilename(const aPath: string; charThresh: Word = 80): string;
|
|
|
|
implementation
|
|
|
|
constructor TMRUList.Create;
|
|
begin
|
|
fMaxCount := 10;
|
|
end;
|
|
|
|
procedure TMRUList.clearOutOfRange;
|
|
begin
|
|
while Count > fMaxCount do delete(Count-1);
|
|
end;
|
|
|
|
procedure TMRUList.setMaxCount(aValue: Integer);
|
|
begin
|
|
if aValue < 0 then aValue := 0;
|
|
if fMaxCount = aValue then exit;
|
|
clearOutOfRange;
|
|
end;
|
|
|
|
function TMRUList.checkItem(const S: string): boolean;
|
|
var
|
|
i: NativeInt;
|
|
begin
|
|
i := indexOf(S);
|
|
if i = -1 then exit(true);
|
|
if i = 0 then exit(false);
|
|
if Count < 2 then exit(false);
|
|
exchange(i, i-1);
|
|
exit( false);
|
|
end;
|
|
|
|
procedure TMRUList.Put(Index: Integer; const S: string);
|
|
begin
|
|
if not (checkItem(S)) then exit;
|
|
inherited;
|
|
clearOutOfRange;
|
|
end;
|
|
|
|
procedure TMRUList.Insert(Index: Integer; const S: string);
|
|
begin
|
|
if not (checkItem(S)) then exit;
|
|
inherited;
|
|
clearOutOfRange;
|
|
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;
|
|
dir: string;
|
|
begin
|
|
dir := ExtractFileDrive(src);
|
|
if length(dir) > 0 then
|
|
result := src[length(dir)+1..length(src)]
|
|
else
|
|
result := src;
|
|
i := pos(invalid, result);
|
|
if i <> 0 then
|
|
begin
|
|
repeat
|
|
result[i] := directorySeparator;
|
|
i := pos(invalid,result);
|
|
until
|
|
i = 0;
|
|
end;
|
|
result := dir + result;
|
|
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;
|
|
|
|
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;
|
|
|
|
function displayShortFilename(const aPath: string; charThresh: Word = 80): string;
|
|
var
|
|
i: NativeInt;
|
|
sepCnt: NativeInt;
|
|
drv: string;
|
|
pth1: string;
|
|
begin
|
|
sepCnt := 0;
|
|
if length(aPath) <= charThresh then
|
|
exit(aPath);
|
|
|
|
drv := extractFileDrive(aPath);
|
|
i := length(aPath);
|
|
while(i <> length(drv)+1) do
|
|
begin
|
|
Inc(sepCnt, Byte(aPath[i] = directorySeparator));
|
|
if sepCnt = 2 then break;
|
|
Dec(i);
|
|
end;
|
|
pth1 := aPath[i..length(aPath)];
|
|
exit( format('%s%s...%s',[drv,directorySeparator,pth1]) );
|
|
end;
|
|
|
|
end.
|