mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-27 23:20:38 +02:00
Converter: optionally delete files in project dir if LCL has a unit with same name.
git-svn-id: trunk@41665 -
This commit is contained in:
parent
8c2b602dda
commit
cff5dd3116
@ -23,7 +23,7 @@
|
|||||||
Abstract:
|
Abstract:
|
||||||
Convert Delphi projects/packages to lazarus projects/packages.
|
Convert Delphi projects/packages to lazarus projects/packages.
|
||||||
This was refactored and cleaned from code in unit DelphiProject2Laz.
|
This was refactored and cleaned from code in unit DelphiProject2Laz.
|
||||||
Now it is objects oriented and easier to maintain / improve.
|
Now it is object oriented and easier to maintain / improve.
|
||||||
}
|
}
|
||||||
unit ConvertDelphi;
|
unit ConvertDelphi;
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ uses
|
|||||||
// IDEIntf
|
// IDEIntf
|
||||||
ComponentReg, IDEMsgIntf, MainIntf, LazIDEIntf, PackageIntf, ProjectIntf,
|
ComponentReg, IDEMsgIntf, MainIntf, LazIDEIntf, PackageIntf, ProjectIntf,
|
||||||
// IDE
|
// IDE
|
||||||
IDEProcs, Project, ProjectDefs, DialogProcs, EditorOptions, CompilerOptions,
|
IDEProcs, Project, ProjectDefs, DialogProcs, IDEDialogs, EditorOptions, CompilerOptions,
|
||||||
PackageDefs, PackageSystem, PackageEditor, BasePkgManager, LazarusIDEStrConsts,
|
PackageDefs, PackageSystem, PackageEditor, BasePkgManager, LazarusIDEStrConsts,
|
||||||
// Converter
|
// Converter
|
||||||
ConverterTypes, ConvertSettings, ConvCodeTool, MissingUnits, MissingPropertiesDlg,
|
ConverterTypes, ConvertSettings, ConvCodeTool, MissingUnits, MissingPropertiesDlg,
|
||||||
@ -137,7 +137,7 @@ type
|
|||||||
function DoMissingUnits(AUsedUnitsTool: TUsedUnitsTool): integer; virtual;
|
function DoMissingUnits(AUsedUnitsTool: TUsedUnitsTool): integer; virtual;
|
||||||
function GetCachedUnitPath(const AUnitName: string): string;
|
function GetCachedUnitPath(const AUnitName: string): string;
|
||||||
protected
|
protected
|
||||||
function EndConvert(AStatus: TModalResult): Boolean;
|
procedure EndConvert(AStatus: TModalResult);
|
||||||
public
|
public
|
||||||
constructor Create(const AFilename, ADescription: string);
|
constructor Create(const AFilename, ADescription: string);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -174,8 +174,9 @@ type
|
|||||||
fMainUnitConverter: TDelphiUnit;
|
fMainUnitConverter: TDelphiUnit;
|
||||||
// Unit search path for project settings.
|
// Unit search path for project settings.
|
||||||
fUnitSearchPaths: TStringList;
|
fUnitSearchPaths: TStringList;
|
||||||
// Units that are found and will be added to project and converted.
|
// Units that are found and will be added to project or package and converted.
|
||||||
fUnitsToAddToProject: TStringList;
|
fUnitsToAddToProject: TStringList;
|
||||||
|
fFilesToDelete: TStringList;
|
||||||
fUseThreads: boolean; // The project/package uses TThread.
|
fUseThreads: boolean; // The project/package uses TThread.
|
||||||
function ConvertSub: TModalResult;
|
function ConvertSub: TModalResult;
|
||||||
procedure CleanUpCompilerOptionsSearchPaths(Options: TBaseCompilerOptions);
|
procedure CleanUpCompilerOptionsSearchPaths(Options: TBaseCompilerOptions);
|
||||||
@ -187,6 +188,7 @@ type
|
|||||||
function ExtractOptionsFromCFG(const CFGFilename: string): TModalResult;
|
function ExtractOptionsFromCFG(const CFGFilename: string): TModalResult;
|
||||||
function DoMissingUnits(AUsedUnitsTool: TUsedUnitsTool): integer; override;
|
function DoMissingUnits(AUsedUnitsTool: TUsedUnitsTool): integer; override;
|
||||||
function AddToProjectLater(AFileName: string): Boolean;
|
function AddToProjectLater(AFileName: string): Boolean;
|
||||||
|
function MaybeDeleteFiles: TModalResult;
|
||||||
function CheckPackageDep(AUnitName: string): Boolean;
|
function CheckPackageDep(AUnitName: string): Boolean;
|
||||||
function TryAddPackageDep(AUnitName, ADefaultPkgName: string): Boolean;
|
function TryAddPackageDep(AUnitName, ADefaultPkgName: string): Boolean;
|
||||||
protected
|
protected
|
||||||
@ -471,7 +473,7 @@ end;
|
|||||||
{ TDelphiUnit }
|
{ TDelphiUnit }
|
||||||
|
|
||||||
constructor TDelphiUnit.Create(AOwnerConverter: TConvertDelphiPBase;
|
constructor TDelphiUnit.Create(AOwnerConverter: TConvertDelphiPBase;
|
||||||
const AFilename: string; AFlags: TConvertUnitFlags);
|
const AFilename: string; aFlags: TConvertUnitFlags);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
fOwnerConverter:=AOwnerConverter;
|
fOwnerConverter:=AOwnerConverter;
|
||||||
@ -510,7 +512,8 @@ begin
|
|||||||
fOwnerConverter.fSettings.AddLogLine(Format(lisConvDelphiConvertingFile,
|
fOwnerConverter.fSettings.AddLogLine(Format(lisConvDelphiConvertingFile,
|
||||||
[fOrigUnitFilename]));
|
[fOrigUnitFilename]));
|
||||||
Application.ProcessMessages;
|
Application.ProcessMessages;
|
||||||
// ConvertUnit in place. File must be writable.
|
|
||||||
|
// Convert unit in place. File must be writable.
|
||||||
Result:=CheckFileIsWritable(fOrigUnitFilename,[mbAbort]);
|
Result:=CheckFileIsWritable(fOrigUnitFilename,[mbAbort]);
|
||||||
if Result<>mrOK then exit;
|
if Result<>mrOK then exit;
|
||||||
// close Delphi unit file in editor.
|
// close Delphi unit file in editor.
|
||||||
@ -852,7 +855,7 @@ begin
|
|||||||
Result:=fCachedUnitNames[AUnitName];
|
Result:=fCachedUnitNames[AUnitName];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TConvertDelphiPBase.EndConvert(AStatus: TModalResult): Boolean;
|
procedure TConvertDelphiPBase.EndConvert(AStatus: TModalResult);
|
||||||
begin
|
begin
|
||||||
// Show ending message
|
// Show ending message
|
||||||
if AStatus=mrOK then
|
if AStatus=mrOK then
|
||||||
@ -931,12 +934,15 @@ begin
|
|||||||
fAllCommentedUnits.Sorted:=True;
|
fAllCommentedUnits.Sorted:=True;
|
||||||
fUnitsToAddToProject:=TStringList.Create;
|
fUnitsToAddToProject:=TStringList.Create;
|
||||||
fUnitsToAddToProject.Sorted:=True;
|
fUnitsToAddToProject.Sorted:=True;
|
||||||
|
fFilesToDelete:=TStringList.Create;
|
||||||
|
fFilesToDelete.Sorted:=True;
|
||||||
fMainUnitConverter:=nil;
|
fMainUnitConverter:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TConvertDelphiProjPack.Destroy;
|
destructor TConvertDelphiProjPack.Destroy;
|
||||||
begin
|
begin
|
||||||
fMainUnitConverter.Free;
|
fMainUnitConverter.Free;
|
||||||
|
fFilesToDelete.Free;
|
||||||
fUnitsToAddToProject.Free;
|
fUnitsToAddToProject.Free;
|
||||||
fAllCommentedUnits.Free;
|
fAllCommentedUnits.Free;
|
||||||
fCachedRealFileNames.Free;
|
fCachedRealFileNames.Free;
|
||||||
@ -1043,9 +1049,11 @@ begin
|
|||||||
Result:=fMainUnitConverter.ConvertFormFile;
|
Result:=fMainUnitConverter.ConvertFormFile;
|
||||||
if Result<>mrOK then exit;
|
if Result<>mrOK then exit;
|
||||||
Result:=ConvertAllUnits; // convert all files.
|
Result:=ConvertAllUnits; // convert all files.
|
||||||
|
if Result<>mrOK then exit;
|
||||||
finally
|
finally
|
||||||
UnsetCompilerModeForDefineTempl(CustomDefines);
|
UnsetCompilerModeForDefineTempl(CustomDefines);
|
||||||
end;
|
end;
|
||||||
|
Result:=MaybeDeleteFiles; // Delete files having same name with a LCL unit.
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TConvertDelphiProjPack.ConvertAllFormFiles(ConverterList: TObjectList): TModalResult;
|
function TConvertDelphiProjPack.ConvertAllFormFiles(ConverterList: TObjectList): TModalResult;
|
||||||
@ -1315,10 +1323,33 @@ var
|
|||||||
x: Integer;
|
x: Integer;
|
||||||
begin
|
begin
|
||||||
Result:=not fUnitsToAddToProject.Find(AFileName,x);
|
Result:=not fUnitsToAddToProject.Find(AFileName,x);
|
||||||
if Result then
|
if Result then // Add the file later to project if not already done.
|
||||||
fUnitsToAddToProject.Add(AFileName);
|
fUnitsToAddToProject.Add(AFileName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TConvertDelphiProjPack.MaybeDeleteFiles: TModalResult;
|
||||||
|
// Maybe delete files that are already in LCL. They are potentially copied from VCL.
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i := fFilesToDelete.Count-1 downto 0 do begin
|
||||||
|
s:=fFilesToDelete[i];
|
||||||
|
// Ask confirmation from user.
|
||||||
|
if IDEMessageDialog(lisConvDelphiUnitnameExistsInLCL,
|
||||||
|
Format(lisConvDelphiUnitWithNameExistsInLCL, [ExtractFileNameOnly(s)]),
|
||||||
|
mtConfirmation, mbYesNo) = mrYes
|
||||||
|
then begin
|
||||||
|
// Delete from file system because compiler would find it otherwise.
|
||||||
|
if not DeleteFileUTF8(s) then
|
||||||
|
exit(mrCancel);
|
||||||
|
//fFilesToDelete.Delete(i);
|
||||||
|
fSettings.AddLogLine(Format('Deleted file %s',[s]));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=mrOK;
|
||||||
|
end;
|
||||||
|
|
||||||
function TConvertDelphiProjPack.CheckPackageDep(AUnitName: string): Boolean;
|
function TConvertDelphiProjPack.CheckPackageDep(AUnitName: string): Boolean;
|
||||||
// Check if the given unit can be found in existing packages. Add a dependency if found.
|
// Check if the given unit can be found in existing packages. Add a dependency if found.
|
||||||
// This is called only if the unit is reported as missing.
|
// This is called only if the unit is reported as missing.
|
||||||
@ -1479,8 +1510,10 @@ begin
|
|||||||
if FilenameIsPascalUnit(AFileName) then begin
|
if FilenameIsPascalUnit(AFileName) then begin
|
||||||
CurUnitInfo:=LazProject.UnitWithUnitname(PureUnitName);
|
CurUnitInfo:=LazProject.UnitWithUnitname(PureUnitName);
|
||||||
if CurUnitInfo<>nil then begin
|
if CurUnitInfo<>nil then begin
|
||||||
Result:=QuestionDlg(lisConvDelphiUnitnameExistsTwice,
|
raise Exception.CreateFmt('TConvertDelphiProject.AddUnit: Unitname %s exists twice',
|
||||||
Format(lisConvDelphiThereAreTwoUnitsWithTheSameUnitname,
|
[PureUnitName]);
|
||||||
|
{ Result:=QuestionDlg(lisConvDelphiUnitnameExistsTwice,
|
||||||
|
Format(lisConvDelphiTwoUnitsWithSameName,
|
||||||
[LineEnding, CurUnitInfo.Filename, LineEnding, AFileName, LineEnding]),
|
[LineEnding, CurUnitInfo.Filename, LineEnding, AFileName, LineEnding]),
|
||||||
mtWarning, [mrYes,lisConvDelphiRemoveFirst,mrNo,lisConvDelphiRemoveSecond,
|
mtWarning, [mrYes,lisConvDelphiRemoveFirst,mrNo,lisConvDelphiRemoveSecond,
|
||||||
mrIgnore,lisConvDelphiKeepBoth,mrAbort], 0);
|
mrIgnore,lisConvDelphiKeepBoth,mrAbort], 0);
|
||||||
@ -1493,6 +1526,7 @@ begin
|
|||||||
exit(mrAbort);
|
exit(mrAbort);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
CurUnitInfo:=TUnitInfo.Create(nil);
|
CurUnitInfo:=TUnitInfo.Create(nil);
|
||||||
@ -1505,16 +1539,30 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TConvertDelphiProject.CheckUnitForConversion(aFileName: string): Boolean;
|
function TConvertDelphiProject.CheckUnitForConversion(aFileName: string): Boolean;
|
||||||
|
// Units in project directory but not part of the project are not reported
|
||||||
|
// as missing and would not be converted. Now add them to the project.
|
||||||
|
// ToDo: move to TConvertDelphiProjPack and support packages, too.
|
||||||
var
|
var
|
||||||
UnitInfo: TUnitInfo;
|
UnitInfo: TUnitInfo;
|
||||||
|
PkgFile: TPkgFile;
|
||||||
|
PureUnitName: String;
|
||||||
|
x: Integer;
|
||||||
begin
|
begin
|
||||||
// Units in project directory but not part of the project are not reported
|
|
||||||
// as missing and would not be converted. Now add them to the project.
|
|
||||||
if ExtractFilePath(aFileName)=LazProject.ProjectDirectory then begin
|
if ExtractFilePath(aFileName)=LazProject.ProjectDirectory then begin
|
||||||
UnitInfo:=LazProject.UnitInfoWithFilename(aFileName);
|
UnitInfo:=LazProject.UnitInfoWithFilename(aFileName);
|
||||||
Result:=Assigned(UnitInfo);
|
Result:=not Assigned(UnitInfo);
|
||||||
if not Result then
|
if Result then begin
|
||||||
AddToProjectLater(aFileName); // Will be added later to project.
|
// Not in project.
|
||||||
|
// Check if unit with same name already exists in LCL, maybe copied from VCL.
|
||||||
|
PureUnitName:=ExtractFileNameOnly(AFileName);
|
||||||
|
PkgFile:=PackageGraph.LCLBasePackage.FindUnit(PureUnitName);
|
||||||
|
if Assigned(PkgFile) then begin
|
||||||
|
if not fFilesToDelete.Find(aFileName, x) then
|
||||||
|
fFilesToDelete.Add(AFileName); // Found also in LCL, delete later.
|
||||||
|
end;
|
||||||
|
//else
|
||||||
|
AddToProjectLater(aFileName); // Add to project later.
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1809,7 +1857,7 @@ var
|
|||||||
CodeBuffer: TCodeBuffer;
|
CodeBuffer: TCodeBuffer;
|
||||||
Flags: TPkgFileFlags;
|
Flags: TPkgFileFlags;
|
||||||
HasRegisterProc: boolean;
|
HasRegisterProc: boolean;
|
||||||
UnitN: String;
|
PureUnitName: String;
|
||||||
begin
|
begin
|
||||||
Result:=mrOK;
|
Result:=mrOK;
|
||||||
if not FilenameIsAbsolute(AFileName) then
|
if not FilenameIsAbsolute(AFileName) then
|
||||||
@ -1819,12 +1867,15 @@ begin
|
|||||||
exit(mrNo);
|
exit(mrNo);
|
||||||
PkgFile:=LazPackage.FindPkgFile(AFileName,true,false);
|
PkgFile:=LazPackage.FindPkgFile(AFileName,true,false);
|
||||||
if PkgFile=nil then begin
|
if PkgFile=nil then begin
|
||||||
|
PureUnitName:=ExtractFileNameOnly(AFileName);
|
||||||
if FilenameIsPascalUnit(AFileName) then begin
|
if FilenameIsPascalUnit(AFileName) then begin
|
||||||
// Check unitname
|
// Check unitname
|
||||||
OffendingUnit:=LazPackage.FindUnit(ExtractFileNameOnly(AFileName));
|
OffendingUnit:=LazPackage.FindUnit(PureUnitName);
|
||||||
if OffendingUnit<>nil then begin
|
if OffendingUnit<>nil then begin
|
||||||
Result:=QuestionDlg(lisConvDelphiUnitnameExistsTwice,
|
raise Exception.CreateFmt('TConvertDelphiPackage.AddUnit: Unitname %s exists twice',
|
||||||
Format(lisConvDelphiThereAreTwoUnitsWithTheSameUnitname,
|
[PureUnitName]);
|
||||||
|
{ Result:=QuestionDlg(lisConvDelphiUnitnameExistsTwice,
|
||||||
|
Format(lisConvDelphiTwoUnitsWithSameName,
|
||||||
[LineEnding, OffendingUnit.Filename, LineEnding, AFileName, LineEnding]),
|
[LineEnding, OffendingUnit.Filename, LineEnding, AFileName, LineEnding]),
|
||||||
mtWarning, [mrNo, lisConvDelphiRemoveSecond, mrAbort], 0);
|
mtWarning, [mrNo, lisConvDelphiRemoveSecond, mrAbort], 0);
|
||||||
case Result of
|
case Result of
|
||||||
@ -1835,9 +1886,9 @@ begin
|
|||||||
exit(mrAbort);
|
exit(mrAbort);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
UnitN:=ExtractFileNameOnly(AFileName);
|
|
||||||
Flags:=[pffAddToPkgUsesSection];
|
Flags:=[pffAddToPkgUsesSection];
|
||||||
// Check if the unit has a Register procedure.
|
// Check if the unit has a Register procedure.
|
||||||
// ToDo: Optimize. The source is read again during unit conversion.
|
// ToDo: Optimize. The source is read again during unit conversion.
|
||||||
@ -1847,10 +1898,10 @@ begin
|
|||||||
if HasRegisterProc then begin
|
if HasRegisterProc then begin
|
||||||
Include(Flags, pffHasRegisterProc);
|
Include(Flags, pffHasRegisterProc);
|
||||||
fSettings.AddLogLine(Format('Adding flag for "Register" procedure in unit %s.',
|
fSettings.AddLogLine(Format('Adding flag for "Register" procedure in unit %s.',
|
||||||
[UnitN]));
|
[PureUnitName]));
|
||||||
end;
|
end;
|
||||||
// Add new unit to package
|
// Add new unit to package
|
||||||
LazPackage.AddFile(AFileName, UnitN, pftUnit, Flags, cpNormal);
|
LazPackage.AddFile(AFileName, PureUnitName, pftUnit, Flags, cpNormal);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ type
|
|||||||
function BackupFile(const AFilename: string): TModalResult;
|
function BackupFile(const AFilename: string): TModalResult;
|
||||||
procedure ClearLog;
|
procedure ClearLog;
|
||||||
function AddLogLine(const ALine: string): integer;
|
function AddLogLine(const ALine: string): integer;
|
||||||
function SaveLog: Boolean;
|
procedure SaveLog;
|
||||||
public
|
public
|
||||||
property MainFilename: String read fMainFilename write SetMainFilename;
|
property MainFilename: String read fMainFilename write SetMainFilename;
|
||||||
property MainPath: String read fMainPath;
|
property MainPath: String read fMainPath;
|
||||||
@ -787,7 +787,7 @@ begin
|
|||||||
Result:=fLog.Add(ALine); // and store for log.
|
Result:=fLog.Add(ALine); // and store for log.
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TConvertSettings.SaveLog: Boolean;
|
procedure TConvertSettings.SaveLog;
|
||||||
var
|
var
|
||||||
aFilename: String;
|
aFilename: String;
|
||||||
Code: TCodeBuffer;
|
Code: TCodeBuffer;
|
||||||
|
@ -251,8 +251,9 @@ begin
|
|||||||
fMissingUnits.Add(OldUnitName);
|
fMissingUnits.Add(OldUnitName);
|
||||||
end;
|
end;
|
||||||
// Check if the unit is not part of project. It will be added and converted then.
|
// Check if the unit is not part of project. It will be added and converted then.
|
||||||
if Assigned(fOwnerTool.OnCheckUnitForConversion) then
|
if not fOwnerTool.IsMainFile then
|
||||||
fOwnerTool.OnCheckUnitForConversion(FullFileN);
|
if Assigned(fOwnerTool.OnCheckUnitForConversion) then
|
||||||
|
fOwnerTool.OnCheckUnitForConversion(FullFileN);
|
||||||
end
|
end
|
||||||
else begin // * Unit not found *
|
else begin // * Unit not found *
|
||||||
// Add unit to fMissingUnits, but don't add Windows specific units if target
|
// Add unit to fMissingUnits, but don't add Windows specific units if target
|
||||||
@ -574,11 +575,9 @@ begin
|
|||||||
MapToEdit:=TStringToStringTree.Create(false);
|
MapToEdit:=TStringToStringTree.Create(false);
|
||||||
fCTLink.CodeTool.BuildTree(lsrEnd);
|
fCTLink.CodeTool.BuildTree(lsrEnd);
|
||||||
if not (fMainUsedUnits.FindMissingUnits(UnitUpdater) and
|
if not (fMainUsedUnits.FindMissingUnits(UnitUpdater) and
|
||||||
fImplUsedUnits.FindMissingUnits(UnitUpdater)) then begin
|
fImplUsedUnits.FindMissingUnits(UnitUpdater)) then
|
||||||
Result:=mrCancel;
|
exit(mrCancel);
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if Result<>mrOK then exit;
|
|
||||||
// Find replacements for missing units from settings.
|
// Find replacements for missing units from settings.
|
||||||
fMainUsedUnits.FindReplacement(UnitUpdater, MapToEdit);
|
fMainUsedUnits.FindReplacement(UnitUpdater, MapToEdit);
|
||||||
fImplUsedUnits.FindReplacement(UnitUpdater, MapToEdit);
|
fImplUsedUnits.FindReplacement(UnitUpdater, MapToEdit);
|
||||||
|
@ -5436,8 +5436,9 @@ resourcestring
|
|||||||
lisConvDelphiExceptionDuringConversion = 'Exception happened during unit conversion.'
|
lisConvDelphiExceptionDuringConversion = 'Exception happened during unit conversion.'
|
||||||
+' Continuing with form files of already converted units...';
|
+' Continuing with form files of already converted units...';
|
||||||
lisConvDelphiUnitnameExistsTwice = 'Unitname exists twice';
|
lisConvDelphiUnitnameExistsTwice = 'Unitname exists twice';
|
||||||
lisConvDelphiThereAreTwoUnitsWithTheSameUnitname = 'There are two units '
|
lisConvDelphiTwoUnitsWithSameName = 'There are two units with the same name:%s%s%s%s%s';
|
||||||
+'with the same unitname:%s%s%s%s%s';
|
lisConvDelphiUnitnameExistsInLCL = 'Unitname exists in LCL';
|
||||||
|
lisConvDelphiUnitWithNameExistsInLCL = 'LCL already has a unit with name %s. Delete it?';
|
||||||
lisConvDelphiRemoveFirst = 'Remove first';
|
lisConvDelphiRemoveFirst = 'Remove first';
|
||||||
lisConvDelphiRemoveSecond = 'Remove second';
|
lisConvDelphiRemoveSecond = 'Remove second';
|
||||||
lisConvDelphiKeepBoth = 'Keep both';
|
lisConvDelphiKeepBoth = 'Keep both';
|
||||||
|
Loading…
Reference in New Issue
Block a user