Merged revision(s) 47490-47494 #bd0bafb893-#bd0bafb893 from trunk:

IDE: Improve TPathEditorButton class, handle Templates better.
........
IDE: Refactor TPathEditorButton more. Copy values between dialog and edit here instead of clients' code.
........
IDE: in Compiler_path_options, turn method CheckSearchPath into a function. Harmonize.
........
IDE: Let TPathEditorButton show the list of paths in edit control's hint.
........
IDE: Fix a layout error in TPathEditorDialog where TemplateGroupBox went under ButtonPanel.
........

git-svn-id: branches/fixes_1_4@47501 -
This commit is contained in:
maxim 2015-01-23 22:03:06 +00:00
parent 8085015aab
commit f661e77efd
6 changed files with 327 additions and 461 deletions

View File

@ -320,8 +320,7 @@ begin
Result := lisGeneral; Result := lisGeneral;
end; end;
procedure TDebuggerGeneralOptionsFrame.Setup( procedure TDebuggerGeneralOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
ADialog: TAbstractOptionsEditorDialog);
begin begin
gbDebuggerType.Caption := dlgDebugType; gbDebuggerType.Caption := dlgDebugType;
gbAdditionalSearchPath.Caption := lisDebugOptionsFrmAdditionalSearchPath; gbAdditionalSearchPath.Caption := lisDebugOptionsFrmAdditionalSearchPath;

View File

@ -46,14 +46,12 @@ type
btnLoadSave: TBitBtn; btnLoadSave: TBitBtn;
btnExport: TBitBtn; btnExport: TBitBtn;
chkUseAsDefault: TCheckBox; chkUseAsDefault: TCheckBox;
function CheckSearchPath(const Context, ExpandedPath: string;
Level: TCheckCompileOptionsMsgLvl): boolean;
function CheckSrcPathInUnitPath(OldParsedSrcPath, NewParsedSrcPath, function CheckSrcPathInUnitPath(OldParsedSrcPath, NewParsedSrcPath,
OldParsedUnitPath, NewParsedUnitPath: string; OldParsedUnitPath, NewParsedUnitPath: string;
out SrcPathChanged: boolean): boolean; out SrcPathChanged: boolean): boolean;
procedure FileBrowseBtnClick(Sender: TObject); procedure FileBrowseBtnClick(Sender: TObject);
procedure PathEditBtnClick(Sender: TObject); procedure PathEditBtnClick(Sender: TObject);
procedure PathEditBtnExecuted(Sender: TObject); function PathEditBtnExecuted(Context: String; var NewPath: String): Boolean;
procedure DoShowOptions(Sender: TObject); procedure DoShowOptions(Sender: TObject);
procedure DoCheck(Sender: TObject); procedure DoCheck(Sender: TObject);
procedure DoImport(Sender: TObject); procedure DoImport(Sender: TObject);
@ -75,6 +73,70 @@ implementation
{$R *.lfm} {$R *.lfm}
function CheckSearchPath(const Context, ExpandedPath: string; Level: TCheckCompileOptionsMsgLvl): boolean;
var
CurPath: string;
p: integer;
HasChars: TCCOSpecialChars;
ErrorMsg: string;
begin
Result := False;
// check for *
if Ord(Level) <= Ord(ccomlHints) then
begin
if System.Pos('*', ExpandedPath) > 0 then
begin
if IDEMessageDialog(lisHint, Format(
lisTheContainsAStarCharacterLazarusUsesThisAsNormalCh, [Context, LineEnding]),
mtWarning, [mbOK, mbCancel]) <> mrOk then
exit;
end;
end;
// check for non existing directories
if Ord(Level) <= Ord(ccomlWarning) then
begin
p := 1;
repeat
//DebugLn(['CheckSearchPath ',ExpandedPath,' ',p,' ',length(ExpandedPath)]);
CurPath := GetNextDirectoryInSearchPath(ExpandedPath, p);
if (CurPath <> '') and (not IDEMacros.StrHasMacros(CurPath)) and
(FilenameIsAbsolute(CurPath)) then
begin
if not DirPathExistsCached(CurPath) then
begin
if IDEMessageDialog(lisCCOWarningCaption, Format(
lisTheContainsANotExistingDirectory, [Context, LineEnding, CurPath]),
mtWarning, [mbIgnore, mbCancel]) <> mrIgnore then
Exit;
end;
end;
until p > length(ExpandedPath);
end;
// check for special characters
if (not IDEMacros.StrHasMacros(ExpandedPath)) then
begin
FindSpecialCharsInPath(ExpandedPath, HasChars);
if Ord(Level) <= Ord(ccomlWarning) then
begin
if Ord(Level) >= Ord(ccomlErrors) then
ErrorMsg := SpecialCharsToStr(HasChars * [ccoscSpecialChars, ccoscNewLine])
else
ErrorMsg := SpecialCharsToStr(HasChars);
if ErrorMsg <> '' then
begin
if IDEMessageDialog(lisCCOWarningCaption, Context + LineEnding + ErrorMsg,
mtWarning, [mbOK, mbCancel]) <> mrOk then
exit;
end;
end;
end;
Result := True;
end;
{ TCompilerPathOptionsFrame } { TCompilerPathOptionsFrame }
function TCompilerPathOptionsFrame.Check: boolean; function TCompilerPathOptionsFrame.Check: boolean;
@ -285,71 +347,6 @@ begin
UpdateTargetFileLabel; UpdateTargetFileLabel;
end; end;
function TCompilerPathOptionsFrame.CheckSearchPath(const Context, ExpandedPath: string;
Level: TCheckCompileOptionsMsgLvl): boolean;
var
CurPath: string;
p: integer;
HasChars: TCCOSpecialChars;
ErrorMsg: string;
begin
Result := False;
// check for *
if Ord(Level) <= Ord(ccomlHints) then
begin
if System.Pos('*', ExpandedPath) > 0 then
begin
if IDEMessageDialog(lisHint, Format(
lisTheContainsAStarCharacterLazarusUsesThisAsNormalCh, [Context, LineEnding]),
mtWarning, [mbOK, mbCancel]) <> mrOk then
exit;
end;
end;
// check for non existing directories
if Ord(Level) <= Ord(ccomlWarning) then
begin
p := 1;
repeat
//DebugLn(['CheckSearchPath ',ExpandedPath,' ',p,' ',length(ExpandedPath)]);
CurPath := GetNextDirectoryInSearchPath(ExpandedPath, p);
if (CurPath <> '') and (not IDEMacros.StrHasMacros(CurPath)) and
(FilenameIsAbsolute(CurPath)) then
begin
if not DirPathExistsCached(CurPath) then
begin
if IDEMessageDialog(lisCCOWarningCaption, Format(
lisTheContainsANotExistingDirectory, [Context, LineEnding, CurPath]),
mtWarning, [mbIgnore, mbCancel]) <> mrIgnore then
Exit;
end;
end;
until p > length(ExpandedPath);
end;
// check for special characters
if (not IDEMacros.StrHasMacros(ExpandedPath)) then
begin
FindSpecialCharsInPath(ExpandedPath, HasChars);
if Ord(Level) <= Ord(ccomlWarning) then
begin
if Ord(Level) >= Ord(ccomlErrors) then
ErrorMsg := SpecialCharsToStr(HasChars * [ccoscSpecialChars, ccoscNewLine])
else
ErrorMsg := SpecialCharsToStr(HasChars);
if ErrorMsg <> '' then
begin
if IDEMessageDialog(lisCCOWarningCaption, Context + LineEnding + ErrorMsg,
mtWarning, [mbOK, mbCancel]) <> mrOk then
exit;
end;
end;
end;
Result := True;
end;
function TCompilerPathOptionsFrame.CheckSrcPathInUnitPath(OldParsedSrcPath, function TCompilerPathOptionsFrame.CheckSrcPathInUnitPath(OldParsedSrcPath,
NewParsedSrcPath, OldParsedUnitPath, NewParsedUnitPath: string; out NewParsedSrcPath, OldParsedUnitPath, NewParsedUnitPath: string; out
SrcPathChanged: boolean): boolean; SrcPathChanged: boolean): boolean;
@ -429,112 +426,18 @@ begin
end; end;
procedure TCompilerPathOptionsFrame.PathEditBtnClick(Sender: TObject); procedure TCompilerPathOptionsFrame.PathEditBtnClick(Sender: TObject);
var
AButton: TPathEditorButton;
OldPath, Templates: string;
begin begin
if Sender is TPathEditorButton then if Sender is TPathEditorButton then
begin TPathEditorButton(Sender).CurrentPathEditor.BaseDirectory := FCompilerOpts.BaseDirectory;
AButton := TPathEditorButton(Sender);
if AButton = OtherUnitsPathEditBtn then
begin
OldPath := OtherUnitsEdit.Text;
Templates := SetDirSeparators(
'$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)' +
';$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)/$(LCLWidgetType)' +
';$(LazarusDir)/components/codetools/units/$(TargetCPU)-$(TargetOS)' +
';$(LazarusDir)/components/custom' +
';$(LazarusDir)/packager/units/$(TargetCPU)-$(TargetOS)');
end
else
if AButton = IncludeFilesPathEditBtn then
begin
OldPath := IncludeFilesEdit.Text;
Templates := 'include' + ';inc';
end
else
if AButton = OtherSourcesPathEditBtn then
begin
OldPath := OtherSourcesEdit.Text;
Templates := SetDirSeparators('$(LazarusDir)/lcl' +
';$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)' +
';$(LazarusDir)/components/synedit' + ';$(LazarusDir)/components/codetools');
end
else
if AButton = LibrariesPathEditBtn then
begin
OldPath := LibrariesEdit.Text;
Templates := SetDirSeparators('/usr/X11R6/lib;/sw/lib');
end
else
if AButton = DebugPathEditBtn then
begin
OldPath := DebugPathEdit.Text;
Templates := SetDirSeparators('$(LazarusDir)/lcl/include' +
';$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)' +
';$(LazarusDir)/include');
end
else
Exit;
AButton.CurrentPathEditor.BaseDirectory := FCompilerOpts.BaseDirectory;
AButton.CurrentPathEditor.Path := OldPath;
AButton.CurrentPathEditor.Templates := SetDirSeparators(Templates);
end;
end; end;
procedure TCompilerPathOptionsFrame.PathEditBtnExecuted(Sender: TObject); function TCompilerPathOptionsFrame.PathEditBtnExecuted(Context: String; var NewPath: String): Boolean;
function CheckPath(const Context, NewPath: string): boolean;
var
ExpandedPath: string;
BaseDir: string;
begin
BaseDir := FCompilerOpts.BaseDirectory;
ExpandedPath := TrimSearchPath(NewPath, BaseDir, true);
Result := CheckSearchPath(Context, ExpandedPath, ccomlHints);
end;
var var
AButton: TPathEditorButton; ExpandedPath: string;
NewPath: string;
begin begin
if Sender is TPathEditorButton then NewPath := FCompilerOpts.ShortenPath(NewPath, False);
begin ExpandedPath := TrimSearchPath(NewPath, FCompilerOpts.BaseDirectory, true);
AButton := TPathEditorButton(Sender); Result := CheckSearchPath(Context, ExpandedPath, ccomlHints);
if AButton.CurrentPathEditor.ModalResult <> mrOk then
Exit;
NewPath := AButton.CurrentPathEditor.Path;
NewPath := FCompilerOpts.ShortenPath(NewPath, False);
if AButton = OtherUnitsPathEditBtn then
begin
if CheckPath(OtherUnitsLabel.Caption, NewPath) then
OtherUnitsEdit.Text := NewPath;
end
else
if AButton = IncludeFilesPathEditBtn then
begin
if CheckPath(IncludeFilesLabel.Caption, NewPath) then
IncludeFilesEdit.Text := NewPath;
end
else
if AButton = OtherSourcesPathEditBtn then
begin
if CheckPath(OtherSourcesLabel.Caption, NewPath) then
OtherSourcesEdit.Text := NewPath;
end
else
if AButton = LibrariesPathEditBtn then
begin
if CheckPath(LibrariesLabel.Caption, NewPath) then
LibrariesEdit.Text := NewPath;
end
else
if AButton = DebugPathEditBtn then
begin
if CheckPath(DebugPathLabel.Caption, NewPath) then
DebugPathEdit.Text := NewPath;
end;
end;
end; end;
procedure TCompilerPathOptionsFrame.FileBrowseBtnClick(Sender: TObject); procedure TCompilerPathOptionsFrame.FileBrowseBtnClick(Sender: TObject);
@ -591,18 +494,24 @@ begin
begin begin
Name := 'OtherUnitsPathEditBtn'; Name := 'OtherUnitsPathEditBtn';
Caption := '...'; Caption := '...';
Parent := Self;
TabOrder := 1;
Anchors := [akRight, akTop, akBottom]; Anchors := [akRight, akTop, akBottom];
AnchorParallel(akTop, 0, OtherUnitsEdit); AnchorParallel(akTop, 0, OtherUnitsEdit);
AnchorParallel(akBottom, 0, OtherUnitsEdit); AnchorParallel(akBottom, 0, OtherUnitsEdit);
AnchorParallel(akRight, 0, Self); AnchorParallel(akRight, 0, Self);
AutoSize := True; AutoSize := True;
AssociatedEdit := OtherUnitsEdit;
ContextCaption := OtherUnitsLabel.Caption;
Templates:='$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)' +
';$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)/$(LCLWidgetType)' +
';$(LazarusDir)/components/codetools/units/$(TargetCPU)-$(TargetOS)' +
';$(LazarusDir)/components/custom' +
';$(LazarusDir)/packager/units/$(TargetCPU)-$(TargetOS)';
OnClick := @PathEditBtnClick; OnClick := @PathEditBtnClick;
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
Parent := Self;
TabOrder:=1;
end; end;
OtherUnitsEdit.AnchorToNeighbour(akRight, 0, OtherUnitsPathEditBtn); OtherUnitsEdit.AnchorToNeighbour(akRight, 0, OtherUnitsPathEditBtn);
OtherUnitsEdit.Hint := lisDelimiterIsSemicolon;
{------------------------------------------------------------} {------------------------------------------------------------}
@ -611,19 +520,21 @@ begin
with IncludeFilesPathEditBtn do with IncludeFilesPathEditBtn do
begin begin
Name := 'IncludeFilesPathEditBtn'; Name := 'IncludeFilesPathEditBtn';
Caption := '...';
Parent := Self;
TabOrder := 3;
Anchors := [akRight, akTop, akBottom]; Anchors := [akRight, akTop, akBottom];
AnchorParallel(akTop, 0, IncludeFilesEdit); AnchorParallel(akTop, 0, IncludeFilesEdit);
AnchorParallel(akBottom, 0, IncludeFilesEdit); AnchorParallel(akBottom, 0, IncludeFilesEdit);
AnchorParallel(akRight, 0, Self); AnchorParallel(akRight, 0, Self);
AutoSize := True; AutoSize := True;
Caption := '...'; AssociatedEdit := IncludeFilesEdit;
ContextCaption := IncludeFilesLabel.Caption;
Templates := 'include;inc';
OnClick := @PathEditBtnClick; OnClick := @PathEditBtnClick;
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
Parent := Self;
TabOrder:=3;
end; end;
IncludeFilesEdit.AnchorToNeighbour(akRight, 0, IncludeFilesPathEditBtn); IncludeFilesEdit.AnchorToNeighbour(akRight, 0, IncludeFilesPathEditBtn);
IncludeFilesEdit.Hint := lisDelimiterIsSemicolon;
{------------------------------------------------------------} {------------------------------------------------------------}
@ -632,19 +543,24 @@ begin
with OtherSourcesPathEditBtn do with OtherSourcesPathEditBtn do
begin begin
Name := 'OtherSourcesPathEditBtn'; Name := 'OtherSourcesPathEditBtn';
Caption := '...';
Parent := Self;
TabOrder := 9;
Anchors := [akRight, akTop, akBottom]; Anchors := [akRight, akTop, akBottom];
AnchorParallel(akTop, 0, OtherSourcesEdit); AnchorParallel(akTop, 0, OtherSourcesEdit);
AnchorParallel(akBottom, 0, OtherSourcesEdit); AnchorParallel(akBottom, 0, OtherSourcesEdit);
AnchorParallel(akRight, 0, Self); AnchorParallel(akRight, 0, Self);
AutoSize := True; AutoSize := True;
Caption := '...'; AssociatedEdit := OtherSourcesEdit;
ContextCaption := OtherSourcesLabel.Caption;
Templates := '$(LazarusDir)/lcl' +
';$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)' +
';$(LazarusDir)/components/synedit' +
';$(LazarusDir)/components/codetools';
OnClick := @PathEditBtnClick; OnClick := @PathEditBtnClick;
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
Parent := Self;
TabOrder:=9;
end; end;
OtherSourcesEdit.AnchorToNeighbour(akRight, 0, OtherSourcesPathEditBtn); OtherSourcesEdit.AnchorToNeighbour(akRight, 0, OtherSourcesPathEditBtn);
OtherSourcesEdit.Hint := lisDelimiterIsSemicolon;
{------------------------------------------------------------} {------------------------------------------------------------}
@ -653,19 +569,21 @@ begin
with LibrariesPathEditBtn do with LibrariesPathEditBtn do
begin begin
Name := 'LibrariesPathEditBtn'; Name := 'LibrariesPathEditBtn';
Caption := '...';
Parent := Self;
TabOrder := 5;
Anchors := [akRight, akTop, akBottom]; Anchors := [akRight, akTop, akBottom];
AnchorParallel(akTop, 0, LibrariesEdit); AnchorParallel(akTop, 0, LibrariesEdit);
AnchorParallel(akBottom, 0, LibrariesEdit); AnchorParallel(akBottom, 0, LibrariesEdit);
AnchorParallel(akRight, 0, Self); AnchorParallel(akRight, 0, Self);
AutoSize := True; AutoSize := True;
Caption := '...'; AssociatedEdit := LibrariesEdit;
ContextCaption := LibrariesLabel.Caption;
Templates := '/usr/X11R6/lib;/sw/lib';
OnClick := @PathEditBtnClick; OnClick := @PathEditBtnClick;
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
Parent := Self;
TabOrder:=5;
end; end;
LibrariesEdit.AnchorToNeighbour(akRight, 0, LibrariesPathEditBtn); LibrariesEdit.AnchorToNeighbour(akRight, 0, LibrariesPathEditBtn);
LibrariesEdit.Hint := lisDelimiterIsSemicolon;
{------------------------------------------------------------} {------------------------------------------------------------}
@ -674,20 +592,17 @@ begin
with btnUnitOutputDir do with btnUnitOutputDir do
begin begin
Name := 'btnUnitOutputDir'; Name := 'btnUnitOutputDir';
Caption := '...';
Parent := Self;
TabOrder := 7;
Anchors := [akRight, akTop, akBottom]; Anchors := [akRight, akTop, akBottom];
AnchorParallel(akTop, 0, UnitOutputDirEdit); AnchorParallel(akTop, 0, UnitOutputDirEdit);
AnchorParallel(akBottom, 0, UnitOutputDirEdit); AnchorParallel(akBottom, 0, UnitOutputDirEdit);
AnchorParallel(akRight, 0, Self); AnchorParallel(akRight, 0, Self);
AutoSize := True; AutoSize := True;
Caption := '...';
OnClick := @FileBrowseBtnClick; OnClick := @FileBrowseBtnClick;
Parent := Self;
TabOrder:=7;
end; end;
UnitOutputDirEdit.AnchorToNeighbour(akRight, 0, btnUnitOutputDir); UnitOutputDirEdit.AnchorToNeighbour(akRight, 0, btnUnitOutputDir);
UnitOutputDirEdit.Hint := lisDelimiterIsSemicolon;
ProjTargetFileEdit.Hint := lisDelimiterIsSemicolon;
{------------------------------------------------------------} {------------------------------------------------------------}
@ -696,19 +611,23 @@ begin
with DebugPathEditBtn do with DebugPathEditBtn do
begin begin
Name := 'DebugPathEditBtn'; Name := 'DebugPathEditBtn';
Caption := '...';
Parent := Self;
TabOrder := 13;
Anchors := [akRight, akTop, akBottom]; Anchors := [akRight, akTop, akBottom];
AnchorParallel(akTop, 0, DebugPathEdit); AnchorParallel(akTop, 0, DebugPathEdit);
AnchorParallel(akBottom, 0, DebugPathEdit); AnchorParallel(akBottom, 0, DebugPathEdit);
AnchorParallel(akRight, 0, Self); AnchorParallel(akRight, 0, Self);
AutoSize := True; AutoSize := True;
Caption := '...'; AssociatedEdit := DebugPathEdit;
ContextCaption := DebugPathLabel.Caption;
Templates := '$(LazarusDir)/lcl/include' +
';$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)' +
';$(LazarusDir)/include';
OnClick := @PathEditBtnClick; OnClick := @PathEditBtnClick;
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
Parent := Self;
TabOrder:=13;
end; end;
DebugPathEdit.AnchorToNeighbour(akRight, 0, DebugPathEditBtn); DebugPathEdit.AnchorToNeighbour(akRight, 0, DebugPathEditBtn);
DebugPathEdit.Hint := lisDelimiterIsSemicolon;
{------------------------------------------------------------} {------------------------------------------------------------}
@ -767,12 +686,12 @@ begin
ProjTargetApplyConventionsCheckBox.Visible:=false; ProjTargetApplyConventionsCheckBox.Visible:=false;
end; end;
OtherUnitsEdit.Text := FCompilerOpts.OtherUnitFiles; SetPathTextAndHint(FCompilerOpts.OtherUnitFiles, OtherUnitsEdit);
IncludeFilesEdit.Text := FCompilerOpts.IncludePath; SetPathTextAndHint(FCompilerOpts.IncludePath, IncludeFilesEdit);
LibrariesEdit.Text := FCompilerOpts.Libraries; SetPathTextAndHint(FCompilerOpts.Libraries, LibrariesEdit);
OtherSourcesEdit.Text := FCompilerOpts.SrcPath; SetPathTextAndHint(FCompilerOpts.SrcPath, OtherSourcesEdit);
UnitOutputDirEdit.Text := FCompilerOpts.UnitOutputDirectory; UnitOutputDirEdit.Text := FCompilerOpts.UnitOutputDirectory;
DebugPathEdit.Text := FCompilerOpts.DebugPath; SetPathTextAndHint(FCompilerOpts.DebugPath, DebugPathEdit);
chkUseAsDefault.Visible := FCompilerOpts.CanBeDefaulForProject; chkUseAsDefault.Visible := FCompilerOpts.CanBeDefaulForProject;
end; end;

View File

@ -82,7 +82,6 @@ type
FEffectiveBaseDirectory: string; FEffectiveBaseDirectory: string;
function GetPath: string; function GetPath: string;
function GetTemplates: string; function GetTemplates: string;
function PathToText(const APath: string): string;
function BaseRelative(const APath: string): String; function BaseRelative(const APath: string): String;
function PathAsAbsolute(const APath: string): String; function PathAsAbsolute(const APath: string): String;
function PathMayExist(APath: string): TObject; function PathMayExist(APath: string): TObject;
@ -90,7 +89,6 @@ type
procedure SetBaseDirectory(const AValue: string); procedure SetBaseDirectory(const AValue: string);
procedure SetPath(const AValue: string); procedure SetPath(const AValue: string);
procedure SetTemplates(const AValue: string); procedure SetTemplates(const AValue: string);
function TextToPath(const AText: string): string;
procedure UpdateButtons; procedure UpdateButtons;
procedure WriteHelper(Paths: TStringList); procedure WriteHelper(Paths: TStringList);
public public
@ -100,21 +98,30 @@ type
property Templates: string read GetTemplates write SetTemplates; property Templates: string read GetTemplates write SetTemplates;
end; end;
TOnPathEditorExecuted = TNotifyEvent; TOnPathEditorExecuted = function (Context: String; var NewPath: String): Boolean of object;
{ TPathEditorButton }
TPathEditorButton = class(TButton) TPathEditorButton = class(TButton)
private private
FCurrentPathEditor: TPathEditorDialog; FCurrentPathEditor: TPathEditorDialog;
FAssociatedEdit: TCustomEdit;
FContextCaption: String;
FTemplates: String;
FOnExecuted: TOnPathEditorExecuted; FOnExecuted: TOnPathEditorExecuted;
protected protected
procedure DoOnPathEditorExecuted; procedure DoOnPathEditorExecuted;
public public
procedure Click; override; procedure Click; override;
property CurrentPathEditor: TPathEditorDialog read FCurrentPathEditor; property CurrentPathEditor: TPathEditorDialog read FCurrentPathEditor;
property AssociatedEdit: TCustomEdit read FAssociatedEdit write FAssociatedEdit;
property ContextCaption: String read FContextCaption write FContextCaption;
property Templates: String read FTemplates write FTemplates;
property OnExecuted: TOnPathEditorExecuted read FOnExecuted write FOnExecuted; property OnExecuted: TOnPathEditorExecuted read FOnExecuted write FOnExecuted;
end; end;
function PathEditorDialog: TPathEditorDialog; function PathEditorDialog: TPathEditorDialog;
procedure SetPathTextAndHint(aPath: String; aEdit: TCustomEdit);
implementation implementation
@ -130,6 +137,71 @@ begin
Result:=PathEditor; Result:=PathEditor;
end; end;
function TextToPath(const AText: string): string;
var
i, j: integer;
begin
Result:=AText;
// convert all line ends to semicolons, remove empty paths and trailing spaces
i:=1;
j:=1;
while i<=length(AText) do begin
if AText[i] in [#10,#13] then begin
// new line -> new path
inc(i);
if (i<=length(AText)) and (AText[i] in [#10,#13])
and (AText[i]<>AText[i-1]) then
inc(i);
// skip spaces at end of path
while (j>1) and (Result[j-1]=' ') do
dec(j);
// skip empty paths
if (j=1) or (Result[j-1]<>';') then begin
Result[j]:=';';
inc(j);
end;
end else if ord(AText[i])<32 then begin
// skip trailing spaces
inc(i)
end else if AText[i]=' ' then begin
// space -> skip spaces at beginning of path
if (j>1) and (Result[j-1]<>';') then begin
Result[j]:=AText[i];
inc(j);
end;
inc(i);
end else begin
// path char -> just copy
Result[j]:=AText[i];
inc(j);
inc(i);
end;
end;
if (j>1) and (Result[j-1]=';') then dec(j);
SetLength(Result,j-1);
end;
function PathToText(const APath: string): string;
var
i: integer;
begin
Result:='';
for i:=1 to length(APath) do
if APath[i]=';' then
Result:=Result+LineEnding
else
Result:=Result+APath[i];
end;
procedure SetPathTextAndHint(aPath: String; aEdit: TCustomEdit);
begin
aEdit.Text := aPath;
if Pos(';', aPath) > 0 then // Zero or one separate paths.
aEdit.Hint := PathToText(aPath)
else
aEdit.Hint := lisDelimiterIsSemicolon;
end;
{ TPathEditorDialog } { TPathEditorDialog }
function TPathEditorDialog.BaseRelative(const APath: string): String; function TPathEditorDialog.BaseRelative(const APath: string): String;
@ -443,7 +515,7 @@ end;
procedure TPathEditorDialog.PathListBoxKeyDown(Sender: TObject; var Key: Word; procedure TPathEditorDialog.PathListBoxKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); Shift: TShiftState);
begin begin
if (ssCtrl in shift ) and ((Key = VK_UP) or (Key = VK_DOWN)) then begin if (ssCtrl in shift) and ((Key = VK_UP) or (Key = VK_DOWN)) then begin
if Key = VK_UP then if Key = VK_UP then
MoveUpButtonClick(Nil) MoveUpButtonClick(Nil)
else else
@ -481,67 +553,15 @@ begin
end; end;
procedure TPathEditorDialog.SetTemplates(const AValue: string); procedure TPathEditorDialog.SetTemplates(const AValue: string);
begin
TemplatesListBox.Items.Text:=PathToText(AValue);
TemplateGroupBox.Visible:=TemplatesListBox.Count>0;
end;
function TPathEditorDialog.TextToPath(const AText: string): string;
var var
i, j: integer; NewVis: Boolean;
PathAsText: string;
begin begin
PathAsText:=AText; TemplatesListBox.Items.Text := PathToText(AValue);
Result:=PathAsText; NewVis := TemplatesListBox.Count > 0;
// convert all line ends to semicolons, remove empty paths and trailing spaces if NewVis = TemplateGroupBox.Visible then Exit;
i:=1; TemplateGroupBox.Visible := NewVis;
j:=1; if NewVis then
while i<=length(PathAsText) do begin TemplateGroupBox.Top:=0;
if PathAsText[i] in [#10,#13] then begin
// new line -> new path
inc(i);
if (i<=length(PathAsText)) and (PathAsText[i] in [#10,#13])
and (PathAsText[i]<>PathAsText[i-1]) then
inc(i);
// skip spaces at end of path
while (j>1) and (Result[j-1]=' ') do
dec(j);
// skip empty paths
if (j=1) or (Result[j-1]<>';') then begin
Result[j]:=';';
inc(j);
end;
end else if ord(PathAsText[i])<32 then begin
// skip trailing spaces
inc(i)
end else if PathAsText[i]=' ' then begin
// space -> skip spaces at beginning of path
if (j>1) and (Result[j-1]<>';') then begin
Result[j]:=PathAsText[i];
inc(j);
end;
inc(i);
end else begin
// path char -> just copy
Result[j]:=PathAsText[i];
inc(j);
inc(i);
end;
end;
if (j>1) and (Result[j-1]=';') then dec(j);
SetLength(Result,j-1);
end;
function TPathEditorDialog.PathToText(const APath: string): string;
var
i: integer;
NewPath: string;
begin
NewPath:=APath;
for i:=1 to length(NewPath) do
if NewPath[i]=';' then
NewPath[i]:=#13;
Result:=NewPath;
end; end;
procedure TPathEditorDialog.UpdateButtons; procedure TPathEditorDialog.UpdateButtons;
@ -586,6 +606,8 @@ begin
FCurrentPathEditor:=PathEditorDialog; FCurrentPathEditor:=PathEditorDialog;
try try
inherited Click; inherited Click;
FCurrentPathEditor.Templates := SetDirSeparators(FTemplates);
FCurrentPathEditor.Path := AssociatedEdit.Text;
FCurrentPathEditor.ShowModal; FCurrentPathEditor.ShowModal;
DoOnPathEditorExecuted; DoOnPathEditorExecuted;
finally finally
@ -594,8 +616,17 @@ begin
end; end;
procedure TPathEditorButton.DoOnPathEditorExecuted; procedure TPathEditorButton.DoOnPathEditorExecuted;
var
Ok: Boolean;
NewPath: String;
begin begin
if Assigned(OnExecuted) then OnExecuted(Self); NewPath := FCurrentPathEditor.Path;
Ok := (FCurrentPathEditor.ModalResult = mrOk) and (AssociatedEdit.Text <> NewPath);
if Ok and Assigned(OnExecuted) then
Ok := OnExecuted(ContextCaption, NewPath);
// Assign value only if old <> new and OnExecuted allows it.
if Ok then
SetPathTextAndHint(NewPath, AssociatedEdit);
end; end;
end. end.

View File

@ -33,8 +33,7 @@ type
FPDocPathButton: TPathEditorButton; FPDocPathButton: TPathEditorButton;
FStoredPkgType: TLazPackageType; FStoredPkgType: TLazPackageType;
function GetSelectedPkgType: TLazPackageType; function GetSelectedPkgType: TLazPackageType;
procedure PathEditBtnClick(Sender: TObject); function PathEditBtnExecuted(Context: String; var NewPath: String): Boolean;
procedure PathEditBtnExecuted(Sender: TObject);
procedure SetSelectedPkgType(PkgType: TLazPackageType); procedure SetSelectedPkgType(PkgType: TLazPackageType);
function ShowMsgPackageTypeMustBeDesign: boolean; function ShowMsgPackageTypeMustBeDesign: boolean;
function GetFPDocPkgNameEditValue: string; function GetFPDocPkgNameEditValue: string;
@ -83,14 +82,6 @@ begin
FPDocPackageNameEdit.Text:=GetFPDocPkgNameEditValue; FPDocPackageNameEdit.Text:=GetFPDocPkgNameEditValue;
end; end;
procedure TPackageIntegrationOptionsFrame.PathEditBtnClick(Sender: TObject);
var
AButton: TPathEditorButton absolute Sender;
begin
AButton.CurrentPathEditor.Path := FPDocSearchPathsEdit.Text;
AButton.CurrentPathEditor.Templates := '';
end;
function TPackageIntegrationOptionsFrame.GetSelectedPkgType: TLazPackageType; function TPackageIntegrationOptionsFrame.GetSelectedPkgType: TLazPackageType;
begin begin
if RunTimeOnlyRadioButton.Checked then if RunTimeOnlyRadioButton.Checked then
@ -103,59 +94,44 @@ begin
Result:=lptRunAndDesignTime; Result:=lptRunAndDesignTime;
end; end;
procedure TPackageIntegrationOptionsFrame.PathEditBtnExecuted(Sender: TObject); function TPackageIntegrationOptionsFrame.PathEditBtnExecuted(Context: String;
var NewPath: String): Boolean;
var var
AButton: TPathEditorButton absolute Sender;
NewPath: string;
OldPath: string;
CurDir: string; CurDir: string;
StartPos: integer; StartPos, OldStartPos: integer;
DlgResult: TModalResult; DlgResult: TModalResult;
OldStartPos: longint;
begin begin
if AButton.CurrentPathEditor.ModalResult <> mrOk then // check NewPath
Exit; StartPos := 1;
NewPath := AButton.CurrentPathEditor.Path; repeat
OldPath := FPDocSearchPathsEdit.Text; OldStartPos := StartPos;
if OldPath <> NewPath then CurDir := GetNextDirectoryInSearchPath(NewPath, StartPos);
begin if CurDir <> '' then
// check NewPath begin
StartPos := 1; IDEMacros.SubstituteMacros(CurDir);
repeat FLazPackage.LongenFilename(CurDir);
OldStartPos := StartPos; if not DirPathExists(CurDir) then
CurDir := GetNextDirectoryInSearchPath(NewPath, StartPos);
if CurDir <> '' then
begin begin
IDEMacros.SubstituteMacros(CurDir); DlgResult := QuestionDlg(lisEnvOptDlgDirectoryNotFound,
FLazPackage.LongenFilename(CurDir); Format(lisDirectoryNotFound, [CurDir]),
if not DirPathExists(CurDir) then mtError, [mrIgnore, mrYes, lisRemoveFromSearchPath, mrCancel], 0);
begin case DlgResult of
DlgResult := QuestionDlg(lisEnvOptDlgDirectoryNotFound, mrIgnore: ;
Format(lisDirectoryNotFound, [CurDir]), mrYes:
mtError, [mrIgnore, mrYes, lisRemoveFromSearchPath, mrCancel], 0); begin // remove directory from search path
case DlgResult of NewPath := copy(NewPath,1,OldStartPos-1) + copy(NewPath,StartPos,length(NewPath));
mrIgnore: ; StartPos := OldStartPos;
mrYes:
begin
// remove directory from search path
NewPath := copy(NewPath, 1, OldStartPos - 1) +
copy(NewPath, StartPos, length(NewPath));
StartPos := OldStartPos;
end;
else
// undo
NewPath := OldPath;
break;
end; end;
else // undo
Exit(False);
end; end;
end; end;
until StartPos > length(NewPath); end;
end; until StartPos > length(NewPath);
FPDocSearchPathsEdit.Text := NewPath; Result := True;
end; end;
procedure TPackageIntegrationOptionsFrame.SetSelectedPkgType( procedure TPackageIntegrationOptionsFrame.SetSelectedPkgType(PkgType: TLazPackageType);
PkgType: TLazPackageType);
begin begin
case PkgType of case PkgType of
lptRunTime: RunTimeRadioButton.Checked:=true; lptRunTime: RunTimeRadioButton.Checked:=true;
@ -192,7 +168,8 @@ begin
FPDocPackageNameLabel.Caption := lisPckPackage; FPDocPackageNameLabel.Caption := lisPckPackage;
FPDocPackageNameEdit.Hint := lisPckClearToUseThePackageName; FPDocPackageNameEdit.Hint := lisPckClearToUseThePackageName;
FPDocSearchPathsLabel.Caption := lisPathEditSearchPaths; FPDocSearchPathsLabel.Caption := lisPathEditSearchPaths;
FPDocSearchPathsEdit.Hint := lisPckSearchPathsForFpdocXmlFilesMultiplePathsMustBeSepa; // ToDo: remove the resource string later.
//FPDocSearchPathsEdit.Hint := lisPckSearchPathsForFpdocXmlFilesMultiplePathsMustBeSepa;
FPDocPathButton := TPathEditorButton.Create(Self); FPDocPathButton := TPathEditorButton.Create(Self);
with FPDocPathButton do with FPDocPathButton do
@ -204,7 +181,7 @@ begin
AnchorParallel(akRight, 6, DocGroupBox); AnchorParallel(akRight, 6, DocGroupBox);
AnchorParallel(akTop, 0, FPDocSearchPathsEdit); AnchorParallel(akTop, 0, FPDocSearchPathsEdit);
AnchorParallel(akBottom, 0, FPDocSearchPathsEdit); AnchorParallel(akBottom, 0, FPDocSearchPathsEdit);
OnClick := @PathEditBtnClick; AssociatedEdit := FPDocSearchPathsEdit;
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
Parent := DocGroupBox; Parent := DocGroupBox;
end; end;
@ -222,7 +199,7 @@ begin
else else
UpdateRadioGroup.ItemIndex := 2; UpdateRadioGroup.ItemIndex := 2;
end; end;
FPDocSearchPathsEdit.Text:=FLazPackage.FPDocPaths; SetPathTextAndHint(FLazPackage.FPDocPaths, FPDocSearchPathsEdit);
if FLazPackage.FPDocPackageName='' then if FLazPackage.FPDocPackageName='' then
FPDocPackageNameEdit.Text:=lisDefaultPlaceholder FPDocPackageNameEdit.Text:=lisDefaultPlaceholder
else else

View File

@ -14,13 +14,13 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 0 Left = 0
Height = 147 Height = 133
Top = 0 Top = 0
Width = 535 Width = 535
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
AutoSize = True AutoSize = True
Caption = 'Add paths to dependent packages/projects' Caption = 'Add paths to dependent packages/projects'
ClientHeight = 130 ClientHeight = 114
ClientWidth = 531 ClientWidth = 531
TabOrder = 0 TabOrder = 0
object UnitPathLabel: TLabel object UnitPathLabel: TLabel
@ -29,8 +29,8 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 6 Left = 6
Height = 15 Height = 15
Top = 11 Top = 9
Width = 23 Width = 26
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'Unit' Caption = 'Unit'
ParentColor = False ParentColor = False
@ -41,8 +41,8 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 6 Left = 6
Height = 15 Height = 15
Top = 42 Top = 36
Width = 40 Width = 45
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'Include' Caption = 'Include'
ParentColor = False ParentColor = False
@ -53,8 +53,8 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 6 Left = 6
Height = 15 Height = 15
Top = 73 Top = 63
Width = 37 Width = 41
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'Object' Caption = 'Object'
ParentColor = False ParentColor = False
@ -65,8 +65,8 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 6 Left = 6
Height = 15 Height = 15
Top = 104 Top = 90
Width = 39 Width = 43
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'Library' Caption = 'Library'
ParentColor = False ParentColor = False
@ -77,12 +77,14 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideRight.Control = AddPathsGroupBox AnchorSideRight.Control = AddPathsGroupBox
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 80 Left = 80
Height = 25 Height = 21
Top = 6 Top = 6
Width = 401 Width = 401
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6 BorderSpacing.Top = 6
BorderSpacing.Right = 50 BorderSpacing.Right = 50
ParentShowHint = False
ShowHint = True
TabOrder = 0 TabOrder = 0
end end
object IncludePathEdit: TEdit object IncludePathEdit: TEdit
@ -92,12 +94,14 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideRight.Control = AddPathsGroupBox AnchorSideRight.Control = AddPathsGroupBox
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 80 Left = 80
Height = 25 Height = 21
Top = 37 Top = 33
Width = 401 Width = 401
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6 BorderSpacing.Top = 6
BorderSpacing.Right = 50 BorderSpacing.Right = 50
ParentShowHint = False
ShowHint = True
TabOrder = 1 TabOrder = 1
end end
object ObjectPathEdit: TEdit object ObjectPathEdit: TEdit
@ -107,12 +111,14 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideRight.Control = AddPathsGroupBox AnchorSideRight.Control = AddPathsGroupBox
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 80 Left = 80
Height = 25 Height = 21
Top = 68 Top = 60
Width = 401 Width = 401
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6 BorderSpacing.Top = 6
BorderSpacing.Right = 50 BorderSpacing.Right = 50
ParentShowHint = False
ShowHint = True
TabOrder = 2 TabOrder = 2
end end
object LibraryPathEdit: TEdit object LibraryPathEdit: TEdit
@ -122,14 +128,16 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideRight.Control = AddPathsGroupBox AnchorSideRight.Control = AddPathsGroupBox
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 80 Left = 80
Height = 25 Height = 21
Top = 99 Top = 87
Width = 401 Width = 401
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 80 BorderSpacing.Left = 80
BorderSpacing.Top = 6 BorderSpacing.Top = 6
BorderSpacing.Right = 50 BorderSpacing.Right = 50
BorderSpacing.Bottom = 6 BorderSpacing.Bottom = 6
ParentShowHint = False
ShowHint = True
TabOrder = 3 TabOrder = 3
end end
end end
@ -141,12 +149,12 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 0 Left = 0
Height = 171 Height = 171
Top = 153 Top = 139
Width = 535 Width = 535
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6 BorderSpacing.Top = 6
Caption = 'Add options to dependent packages and projects' Caption = 'Add options to dependent packages and projects'
ClientHeight = 154 ClientHeight = 152
ClientWidth = 531 ClientWidth = 531
TabOrder = 1 TabOrder = 1
object LinkerOptionsLabel: TLabel object LinkerOptionsLabel: TLabel
@ -155,7 +163,7 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
Left = 6 Left = 6
Height = 15 Height = 15
Top = 6 Top = 6
Width = 34 Width = 38
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'Linker' Caption = 'Linker'
ParentColor = False ParentColor = False
@ -166,7 +174,7 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
Left = 6 Left = 6
Height = 15 Height = 15
Top = 74 Top = 74
Width = 41 Width = 46
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'Custom' Caption = 'Custom'
ParentColor = False ParentColor = False
@ -176,10 +184,10 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideTop.Control = AddOptionsGroupBox AnchorSideTop.Control = AddOptionsGroupBox
AnchorSideRight.Control = AddOptionsGroupBox AnchorSideRight.Control = AddOptionsGroupBox
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 57 Left = 62
Height = 62 Height = 62
Top = 6 Top = 6
Width = 468 Width = 463
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6 BorderSpacing.Top = 6
BorderSpacing.Right = 6 BorderSpacing.Right = 6
@ -195,10 +203,10 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = AddOptionsGroupBox AnchorSideBottom.Control = AddOptionsGroupBox
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 57 Left = 62
Height = 74 Height = 72
Top = 74 Top = 74
Width = 468 Width = 463
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 10 BorderSpacing.Left = 10
BorderSpacing.Top = 6 BorderSpacing.Top = 6
@ -215,19 +223,19 @@ object PackageUsageOptionsFrame: TPackageUsageOptionsFrame
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 0 Left = 0
Height = 53 Height = 57
Top = 330 Top = 316
Width = 535 Width = 535
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
AutoSize = True AutoSize = True
BorderSpacing.Top = 6 BorderSpacing.Top = 6
Caption = 'ProjectGroupBox' Caption = 'ProjectGroupBox'
ClientHeight = 36 ClientHeight = 38
ClientWidth = 531 ClientWidth = 531
TabOrder = 2 TabOrder = 2
object AddPackageUnitToProjectCheckBox: TCheckBox object AddPackageUnitToProjectCheckBox: TCheckBox
Left = 6 Left = 6
Height = 24 Height = 20
Top = 6 Top = 6
Width = 519 Width = 519
Align = alTop Align = alTop

View File

@ -36,9 +36,7 @@ type
ObjectPathButton: TPathEditorButton; ObjectPathButton: TPathEditorButton;
LibraryPathButton: TPathEditorButton; LibraryPathButton: TPathEditorButton;
FLazPackage: TLazPackage; FLazPackage: TLazPackage;
procedure PathEditBtnClick(Sender: TObject); function PathEditBtnExecuted(Context: String; var NewPath: String): Boolean;
procedure PathEditBtnExecuted(Sender: TObject);
function GetEditForPathButton(AButton: TPathEditorButton): TEdit;
public public
function GetTitle: string; override; function GetTitle: string; override;
procedure Setup(ADialog: TAbstractOptionsEditorDialog); override; procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
@ -53,114 +51,40 @@ implementation
{ TPackageUsageOptionsFrame } { TPackageUsageOptionsFrame }
procedure TPackageUsageOptionsFrame.PathEditBtnClick(Sender: TObject); function TPackageUsageOptionsFrame.PathEditBtnExecuted(Context: String; var NewPath: String): Boolean;
var var
AButton: TPathEditorButton;
OldPath: string;
AnEdit: TEdit;
Templates: string;
begin
if not (Sender is TPathEditorButton) then
exit;
AButton := TPathEditorButton(Sender);
AnEdit := GetEditForPathButton(AButton);
OldPath := AnEdit.Text;
if AButton = UnitPathButton then
begin
Templates := SetDirSeparators('$(PkgOutDir)' +
'$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)' +
';$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)/$(LCLWidgetType)' +
';$(LazarusDir)/components/codetools/units/$(TargetCPU)-$(TargetOS)' +
';$(LazarusDir)/components/custom' +
';$(LazarusDir)/packager/units/$(TargetCPU)-$(TargetOS)');
end
else if AButton = IncludePathButton then
begin
Templates := 'include';
end
else
if AButton = ObjectPathButton then
begin
Templates := 'objects';
end
else
if AButton = LibraryPathButton then
begin
Templates := '';
end;
AButton.CurrentPathEditor.Path := OldPath;
AButton.CurrentPathEditor.Templates := SetDirSeparators(Templates);
end;
procedure TPackageUsageOptionsFrame.PathEditBtnExecuted(Sender: TObject);
var
AButton: TPathEditorButton;
NewPath: string;
AnEdit: TEdit;
OldPath: string;
CurDir: string; CurDir: string;
StartPos: integer; StartPos, OldStartPos: integer;
DlgResult: TModalResult; DlgResult: TModalResult;
OldStartPos: longint;
begin begin
if not (Sender is TPathEditorButton) then // check NewPath
exit; StartPos := 1;
AButton := TPathEditorButton(Sender); repeat
if AButton.CurrentPathEditor.ModalResult <> mrOk then OldStartPos := StartPos;
exit; CurDir := GetNextDirectoryInSearchPath(NewPath, StartPos);
NewPath := AButton.CurrentPathEditor.Path; if CurDir <> '' then
AnEdit := GetEditForPathButton(AButton); begin
OldPath := AnEdit.Text; IDEMacros.SubstituteMacros(CurDir);
if OldPath <> NewPath then FLazPackage.LongenFilename(CurDir);
begin if not DirPathExists(CurDir) then
// check NewPath
StartPos := 1;
repeat
OldStartPos := StartPos;
CurDir := GetNextDirectoryInSearchPath(NewPath, StartPos);
if CurDir <> '' then
begin begin
IDEMacros.SubstituteMacros(CurDir); DlgResult := QuestionDlg(lisEnvOptDlgDirectoryNotFound,
FLazPackage.LongenFilename(CurDir); Format(lisDirectoryNotFound, [CurDir]),
if not DirPathExists(CurDir) then mtError, [mrIgnore, mrYes, lisRemoveFromSearchPath, mrCancel], 0);
begin case DlgResult of
DlgResult := QuestionDlg(lisEnvOptDlgDirectoryNotFound, mrIgnore: ;
Format(lisDirectoryNotFound, [CurDir]), mrYes:
mtError, [mrIgnore, mrYes, lisRemoveFromSearchPath, mrCancel], 0); begin // remove directory from search path
case DlgResult of NewPath := copy(NewPath,1,OldStartPos-1) + copy(NewPath,StartPos,length(NewPath));
mrIgnore: ; StartPos := OldStartPos;
mrYes:
begin
// remove directory from search path
NewPath := copy(NewPath, 1, OldStartPos - 1) +
copy(NewPath, StartPos, length(NewPath));
StartPos := OldStartPos;
end;
else
// undo
NewPath := OldPath;
break;
end; end;
else // undo
Exit(False);
end; end;
end; end;
until StartPos > length(NewPath); end;
end; until StartPos > length(NewPath);
AnEdit.Text := NewPath; Result := True;
end;
function TPackageUsageOptionsFrame.GetEditForPathButton(
AButton: TPathEditorButton): TEdit;
begin
if AButton = UnitPathButton then
Result := UnitPathEdit
else if AButton = IncludePathButton then
Result := IncludePathEdit
else if AButton = ObjectPathButton then
Result := ObjectPathEdit
else if AButton = LibraryPathButton then
Result := LibraryPathEdit
else
Result := nil;
end; end;
function TPackageUsageOptionsFrame.GetTitle: string; function TPackageUsageOptionsFrame.GetTitle: string;
@ -190,7 +114,13 @@ begin
AnchorParallel(akRight, 6, AddPathsGroupBox); AnchorParallel(akRight, 6, AddPathsGroupBox);
AnchorParallel(akTop, 0, UnitPathEdit); AnchorParallel(akTop, 0, UnitPathEdit);
AnchorParallel(akBottom, 0, UnitPathEdit); AnchorParallel(akBottom, 0, UnitPathEdit);
OnClick := @PathEditBtnClick; AssociatedEdit := UnitPathEdit;
Templates := '$(PkgOutDir)' +
'$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)' +
';$(LazarusDir)/lcl/units/$(TargetCPU)-$(TargetOS)/$(LCLWidgetType)' +
';$(LazarusDir)/components/codetools/units/$(TargetCPU)-$(TargetOS)' +
';$(LazarusDir)/components/custom' +
';$(LazarusDir)/packager/units/$(TargetCPU)-$(TargetOS)';
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
end; end;
UnitPathEdit.AnchorToNeighbour(akRight,0,UnitPathButton); UnitPathEdit.AnchorToNeighbour(akRight,0,UnitPathButton);
@ -206,7 +136,8 @@ begin
AnchorParallel(akRight, 6, AddPathsGroupBox); AnchorParallel(akRight, 6, AddPathsGroupBox);
AnchorParallel(akTop, 0, IncludePathEdit); AnchorParallel(akTop, 0, IncludePathEdit);
AnchorParallel(akBottom, 0, IncludePathEdit); AnchorParallel(akBottom, 0, IncludePathEdit);
OnClick := @PathEditBtnClick; AssociatedEdit := IncludePathEdit;
Templates := 'include';
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
end; end;
IncludePathEdit.AnchorToNeighbour(akRight,0,IncludePathButton); IncludePathEdit.AnchorToNeighbour(akRight,0,IncludePathButton);
@ -222,7 +153,8 @@ begin
AnchorParallel(akRight, 6, AddPathsGroupBox); AnchorParallel(akRight, 6, AddPathsGroupBox);
AnchorParallel(akTop, 0, ObjectPathEdit); AnchorParallel(akTop, 0, ObjectPathEdit);
AnchorParallel(akBottom, 0, ObjectPathEdit); AnchorParallel(akBottom, 0, ObjectPathEdit);
OnClick := @PathEditBtnClick; AssociatedEdit := ObjectPathEdit;
Templates := 'objects';
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
end; end;
ObjectPathEdit.AnchorToNeighbour(akRight,0,ObjectPathButton); ObjectPathEdit.AnchorToNeighbour(akRight,0,ObjectPathButton);
@ -238,7 +170,7 @@ begin
AnchorParallel(akRight, 6, AddPathsGroupBox); AnchorParallel(akRight, 6, AddPathsGroupBox);
AnchorParallel(akTop, 0, LibraryPathEdit); AnchorParallel(akTop, 0, LibraryPathEdit);
AnchorParallel(akBottom, 0, LibraryPathEdit); AnchorParallel(akBottom, 0, LibraryPathEdit);
OnClick := @PathEditBtnClick; AssociatedEdit := LibraryPathEdit;
OnExecuted := @PathEditBtnExecuted; OnExecuted := @PathEditBtnExecuted;
end; end;
LibraryPathEdit.AnchorToNeighbour(akRight,0,LibraryPathButton); LibraryPathEdit.AnchorToNeighbour(akRight,0,LibraryPathButton);
@ -252,10 +184,10 @@ begin
FLazPackage := (AOptions as TPackageIDEOptions).Package; FLazPackage := (AOptions as TPackageIDEOptions).Package;
with FLazPackage.UsageOptions do with FLazPackage.UsageOptions do
begin begin
UnitPathEdit.Text := UnitPath; SetPathTextAndHint(UnitPath, UnitPathEdit);
IncludePathEdit.Text := IncludePath; SetPathTextAndHint(IncludePath, IncludePathEdit);
ObjectPathEdit.Text := ObjectPath; SetPathTextAndHint(ObjectPath, ObjectPathEdit);
LibraryPathEdit.Text := LibraryPath; SetPathTextAndHint(LibraryPath, LibraryPathEdit);
LinkerOptionsMemo.Text := LinkerOptions; LinkerOptionsMemo.Text := LinkerOptions;
CustomOptionsMemo.Text := CustomOptions; CustomOptionsMemo.Text := CustomOptions;
end; end;