diff --git a/.gitattributes b/.gitattributes index cc9a179fff..5592bcee11 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7319,6 +7319,8 @@ ide/frames/window_options.lfm svneol=native#text/plain ide/frames/window_options.pas svneol=native#text/pascal ide/frmcustomapplicationoptions.lfm svneol=native#text/plain ide/frmcustomapplicationoptions.pas svneol=native#text/plain +ide/generatefppkgconfigurationdlg.lfm svneol=native#text/plain +ide/generatefppkgconfigurationdlg.pas svneol=native#text/pascal ide/genericchecklist.lfm svneol=native#text/plain ide/genericchecklist.pas svneol=native#text/plain ide/genericlisteditor.lfm svneol=native#text/plain diff --git a/ide/generatefppkgconfigurationdlg.lfm b/ide/generatefppkgconfigurationdlg.lfm new file mode 100644 index 0000000000..61cda349e0 --- /dev/null +++ b/ide/generatefppkgconfigurationdlg.lfm @@ -0,0 +1,117 @@ +object GenerateFppkgConfigurationDialog: TGenerateFppkgConfigurationDialog + Left = 1498 + Height = 731 + Top = 614 + Width = 937 + Caption = 'GenerateFppkgConfigurationDialog' + ClientHeight = 731 + ClientWidth = 937 + DesignTimePPI = 192 + OnCreate = FormCreate + Position = poOwnerFormCenter + LCLVersion = '2.1.0.0' + object FppkgLabel: TLabel + Left = 12 + Height = 36 + Top = 12 + Width = 913 + Align = alTop + BorderSpacing.Around = 12 + Caption = 'FppkgLabel' + ParentColor = False + WordWrap = True + end + object FppkgPrefixLabel: TLabel + Left = 12 + Height = 36 + Top = 60 + Width = 913 + Align = alTop + BorderSpacing.Around = 12 + Caption = 'FppkgPrefixLabel' + ParentColor = False + WordWrap = True + end + object FpcPrefixCombobox: TComboBox + Left = 12 + Height = 53 + Top = 108 + Width = 913 + Align = alTop + BorderSpacing.Around = 12 + ItemHeight = 0 + OnChange = FpcPrefixComboboxChange + TabOrder = 0 + Text = 'FpcPrefixCombobox' + end + object InfoMemo: TMemo + Left = 12 + Height = 402 + Top = 237 + Width = 913 + Align = alClient + BorderSpacing.Around = 12 + Lines.Strings = ( + 'InfoMemo' + ) + ReadOnly = True + TabOrder = 1 + end + object BtnPanel: TPanel + Left = 20 + Height = 52 + Top = 659 + Width = 897 + Align = alBottom + BorderSpacing.Around = 20 + BevelOuter = bvNone + ClientHeight = 52 + ClientWidth = 897 + TabOrder = 2 + object FppkgWriteConfigButton: TButton + Left = 546 + Height = 52 + Top = 0 + Width = 351 + Align = alRight + AutoSize = True + Caption = 'FppkgWriteConfigButton' + OnClick = FppkgWriteConfigButtonClick + TabOrder = 0 + end + object WarningsLabel: TLabel + Left = 0 + Height = 52 + Top = 0 + Width = 546 + Align = alClient + AutoSize = False + Caption = 'WarningsLabel' + Layout = tlCenter + ParentColor = False + end + end + object BrowsePanel: TPanel + Left = 12 + Height = 52 + Top = 173 + Width = 913 + Align = alTop + BorderSpacing.Around = 12 + BevelOuter = bvNone + ClientHeight = 52 + ClientWidth = 913 + TabOrder = 3 + object BrowseButton: TButton + Left = 0 + Height = 52 + Top = 0 + Width = 206 + Align = alLeft + AutoSize = True + Caption = 'BrowseButton' + OnClick = BrowseButtonClick + TabOrder = 0 + end + end +end diff --git a/ide/generatefppkgconfigurationdlg.pas b/ide/generatefppkgconfigurationdlg.pas new file mode 100644 index 0000000000..176791482b --- /dev/null +++ b/ide/generatefppkgconfigurationdlg.pas @@ -0,0 +1,468 @@ +unit GenerateFppkgConfigurationDlg; + +{$mode objfpc}{$H+} + +interface + +uses + // Rtl + Classes, + SysUtils, + // Fcl + fpmkunit, + process, + // Fppkg + pkgglobals, + // LazUtils + LazFileUtils, + LazFileCache, + UTF8Process, + // Lcl + Forms, + Controls, + Graphics, + Dialogs, + StdCtrls, + ExtCtrls, + // Codetools + CodeToolManager, + // IDE + IDEProcs, + LazConf, + LazarusIDEStrConsts, + InitialSetupProc, + EnvironmentOpts, + // Packager + FppkgHelper, + // Ideintf + IDEDialogs; + +type + + { TGenerateFppkgConfigurationDialog } + + TGenerateFppkgConfigurationDialog = class(TForm) + FppkgLabel: TLabel; + FpcPrefixCombobox: TComboBox; + FppkgPrefixLabel: TLabel; + InfoMemo: TMemo; + BtnPanel: TPanel; + FppkgWriteConfigButton: TButton; + WarningsLabel: TLabel; + BrowsePanel: TPanel; + BrowseButton: TButton; + + procedure FormCreate(Sender: TObject); + procedure FpcPrefixComboboxChange(Sender: TObject); + procedure BrowseButtonClick(Sender: TObject); + procedure FppkgWriteConfigButtonClick(Sender: TObject); + private + FCompiler: string; + procedure SetCompiler(AValue: string); + procedure SetFppkgCfgFilename(AValue: string); + private + fLastParsedFpcPrefix: string; + fLastParsedFpcLibPath: string; + FFppkgCfgFilename: string; + function CheckFppkgQuality(APrefix: string; out LibPath, Note: string): TSDFilenameQuality; + procedure UpdateFppkgNote; + procedure SearchFppkgFpcPrefixCandidates; + function CheckFpcmkcfgQuality(out Note: string): TSDFilenameQuality; + public + property Compiler: string read FCompiler write SetCompiler; + property FppkgCfgFilename: string read FFppkgCfgFilename write SetFppkgCfgFilename; + end; + +var + GenerateFppkgConfigurationDialog: TGenerateFppkgConfigurationDialog; + +implementation + +{$R *.lfm} + +{ TGenerateFppkgConfigurationDialog } + +procedure TGenerateFppkgConfigurationDialog.FormCreate(Sender: TObject); +begin + Caption := lisGenerateFppkgConfigurationCaption; + FppkgLabel.Caption := lisGenerateFppkgConfiguration; + {$IFDEF WINDOWS} + FppkgPrefixLabel.Caption:=Format(lisFppkgInstallationPath, [GetFPCVer+PathDelim+'units', GetFPCVer+PathDelim+'fpmkinst']); + {$ELSE} + FppkgPrefixLabel.Caption:=Format(lisFppkgInstallationPath, ['lib/fpc', 'lib64/fpc']); + {$ENDIF WINDOWS} + SearchFppkgFpcPrefixCandidates; + FpcPrefixCombobox.Text := ''; + if FpcPrefixCombobox.Items.Count > 0 then + FpcPrefixCombobox.ItemIndex := 0; + WarningsLabel.Caption := lisFppkgConfGenProblems; + FppkgWriteConfigButton.Caption := lisFppkgWriteConfigFile; + BrowseButton.Caption:=lisPathEditBrowse; + UpdateFppkgNote; +end; + +procedure TGenerateFppkgConfigurationDialog.SearchFppkgFpcPrefixCandidates; + + function CheckPath(APath: string; List: TStrings): boolean; + var + LibPath, Note: String; + begin + Result:=false; + if APath='' then exit; + ForcePathDelims(APath); + // check if already checked + if Assigned(List) and (List.IndexOf(APath)>-1) then exit; + + if CheckFppkgQuality(APath, LibPath, Note) = sddqCompatible then + begin + List.Add(APath); + Result := True; + end; + end; + +var + ChkPath: string; +begin + FpcPrefixCombobox.Clear; + + ChkPath := ExtractFileDir(ExtractFileDir(EnvironmentOptions.GetParsedCompilerFilename)); + {$IFDEF WINDOWS} + ChkPath := ExtractFileDir(ExtractFileDir(ChkPath)); + {$ENDIF WINDOWS} + CheckPath(ChkPath, FpcPrefixCombobox.Items); + + {$IFDEF WINDOWS} + CheckPath('C:\PP', FpcPrefixCombobox.Items); + CheckPath('D:\PP', FpcPrefixCombobox.Items); + CheckPath('C:\FPC', FpcPrefixCombobox.Items); + CheckPath('D:\FPC', FpcPrefixCombobox.Items); + {$ELSE} + CheckPath('/usr', FpcPrefixCombobox.Items); + CheckPath('/usr/local', FpcPrefixCombobox.Items); + {$ENDIF WINDOWS} +end; + +function TGenerateFppkgConfigurationDialog.CheckFppkgQuality(APrefix: string; out LibPath, + Note: string): TSDFilenameQuality; +var + SR: TRawByteSearchRec; + LibPathValid: Boolean; + Ver: TFPVersion; +begin + Result := sddqInvalid; + + if APrefix='' then + begin + Note := lisWarning + lisNoFppkgPrefix + LineEnding; + Exit; + end; + + LibPath := ''; + APrefix:=TrimFilename(APrefix); + if not FileExistsCached(APrefix) then + begin + Note:= lisWarning + lisFreePascalPrefix + ' ' + lisISDDirectoryNotFound + LineEnding; + end + else if not DirPathExistsCached(APrefix) then + begin + Note:= lisWarning + lisFreePascalPrefix + ' ' + lisPathIsNoDirectory + LineEnding; + end + else + begin + LibPathValid := True; + + {$IFNDEF WINDOWS} + LibPath := ConcatPaths([APrefix, 'lib', 'fpc']); + if not DirPathExistsCached(LibPath) then + begin + LibPath := ConcatPaths([APrefix, 'lib64', 'fpc']); + if not DirPathExistsCached(LibPath) then + begin + LibPathValid := False; + end; + end; + {$ELSE} + LibPath := APrefix; + {$ENDIF} + LibPath := IncludeTrailingPathDelimiter(LibPath); + + if DirPathExistsCached(LibPath+PathDelim+'fpmkinst') and + DirPathExistsCached(LibPath+PathDelim+'units') then + begin + LibPathValid := True; + Result := sddqCompatible; + end + else if LibPathValid and (FindFirstUTF8(LibPath+AllFilesMask, faDirectory, SR) = 0) then + begin + LibPathValid := False; + repeat + if (SR.Name<>'.') and (SR.Name<>'..') then + begin + if DirPathExistsCached(LibPath+SR.Name+PathDelim+'fpmkinst') and + DirPathExistsCached(LibPath+SR.Name+PathDelim+'units') then + begin + Ver := TFPVersion.Create; + try + Ver.AsString:=SR.Name; + if (Ver.Major > -1) and (Ver.Minor > -1) and (Ver.Micro > -1) then + LibPath:=LibPath + '{CompilerVersion}' + PathDelim + else + LibPath:=LibPath + SR.Name + PathDelim + finally + Ver.Free; + end; + LibPathValid := True; + Result := sddqCompatible; + Break; + end; + end; + until FindNext(SR) <> 0; + FindCloseUTF8(SR); + end; + + if not LibPathValid then + Note:= Note + lisWarning + lisNotAValidFppkgPrefix + LineEnding + else + Note:=''; + end; + +end; + +procedure TGenerateFppkgConfigurationDialog.UpdateFppkgNote; +var + CurCaption: String; + Msg, Note: string; + FileName: string; +begin + if csDestroying in ComponentState then exit; + CurCaption:=FpcPrefixCombobox.Text; + if (fLastParsedFpcPrefix=CurCaption) and (CurCaption<>'') then exit; + fLastParsedFpcPrefix:=CurCaption; + + Msg := ''; + if CheckFppkgQuality(CurCaption,fLastParsedFpcLibPath,Note)<>sddqCompatible then + Msg := Note; + if (CheckFPCExeQuality(FCompiler, Note, CodeToolBoss.CompilerDefinesCache.TestFilename)<>sddqCompatible) then + Msg := Msg + lisWarning + lisFppkgCompilerProblem +Note; + if CheckFpcmkcfgQuality(Note) <> sddqCompatible then + Msg := Msg + lisWarning + Note; + + Note := lisFppkgFilesToBeWritten + LineEnding; + Note := Note + Format(lisGenerateFppkgCfg, [FppkgCfgFilename]) + LineEnding; + // These are the default config-locations used by fpcmkcfg + {$IFDEF WINDOWS} + FileName := '%LocalAppData%\FreePascal\Fppkg\config\default'; + {$ELSE} + FileName := '~/.fppkg/config/default'; + {$ENDIF} + Note := Note + Format(lisGenerateFppkgCompCfg, [FileName]) + LineEnding; + + if Msg<>'' then + begin + WarningsLabel.Visible := True; + Note := Note + LineEnding + Msg; + FppkgWriteConfigButton.Enabled := False; + end + else + begin + WarningsLabel.Visible := False; + FppkgWriteConfigButton.Enabled := True; + end; + + Note := Note + LineEnding + Format(lisFppkgPrefix, [fLastParsedFpcPrefix]) + LineEnding; + Note := Note + Format(lisFppkgLibPrefix, [fLastParsedFpcLibPath]) + LineEnding; + + InfoMemo.Text := Note; +end; + +procedure TGenerateFppkgConfigurationDialog.SetCompiler(AValue: string); +begin + if FCompiler = AValue then Exit; + FCompiler := AValue; + fLastParsedFpcPrefix := ' '; + UpdateFppkgNote; +end; + +function TGenerateFppkgConfigurationDialog.CheckFpcmkcfgQuality(out Note: string): TSDFilenameQuality; +{$IF FPC_FULLVERSION>30100} +var + FpcmkcfgExecutable: string; + Proc: TProcessUTF8; + S: string; + Ver: TFPVersion; +{$ENDIF} +begin + Result := sddqCompatible; + Note:=''; + {$IF FPC_FULLVERSION>30100} + FpcmkcfgExecutable := FindFPCTool('fpcmkcfg'+GetExecutableExt, EnvironmentOptions.GetParsedCompilerFilename); + if FpcmkcfgExecutable = '' then + begin + Note := lisFppkgFpcmkcfgMissing + ' ' + lisFppkgRecentFpcmkcfgNeeded; + Result := sddqInvalid; + end + else + begin + Proc := TProcessUTF8.Create(nil); + try + + Proc.Options := proc.Options + [poWaitOnExit,poUsePipes]; + // Write fppkg.cfg + Proc.Executable := FpcmkcfgExecutable; + proc.Parameters.Add('-V'); + proc.Execute; + + if proc.ExitStatus <> 0 then + begin + Note := lisFppkgFpcmkcfgCheckFailed + ' ' + lisFppkgFpcmkcfgProbTooOld + ' ' + lisFppkgRecentFpcmkcfgNeeded; + Result := sddqInvalid; + end + else + begin + S := ''; + SetLength(S, Proc.Output.NumBytesAvailable); + Proc.Output.Read(S[1], Proc.Output.NumBytesAvailable); + Ver := TFPVersion.Create; + try + S := Copy(S, pos(':', S)+2); + Ver.AsString := Trim(S); + if Ver.Major = -1 then + begin + Note := lisFppkgFpcmkcfgCheckFailed + ' ' + lisFppkgFpcmkcfgNeeded + lisFppkgRecentFpcmkcfgNeeded; + Result := sddqInvalid; + end + else if not ((Ver.Major = 0) or (Ver.Major > 3) or (((Ver.Major = 3)) and (Ver.Minor>1))) then + begin + // fpcmkcfg's version must be > 3.1. Older versions need other + // parameters. Version 0 is also allowed, because it is probably + // self-built. + Note := Format( lisFppkgFpcmkcfgTooOld, [Ver.AsString]) + ' ' + lisFppkgFpcmkcfgNeeded + ' ' + lisFppkgRecentFpcmkcfgNeeded; + Result := sddqInvalid; + end; + finally + Ver.Free; + end; + end; + finally + Proc.Free; + end; + end; + {$ENDIF} +end; + +procedure TGenerateFppkgConfigurationDialog.FpcPrefixComboboxChange(Sender: TObject); +begin + UpdateFppkgNote; +end; + +procedure TGenerateFppkgConfigurationDialog.SetFppkgCfgFilename(AValue: string); +begin + if FFppkgCfgFilename = AValue then Exit; + FFppkgCfgFilename := AValue; + fLastParsedFpcPrefix := ' '; + UpdateFppkgNote; +end; + +procedure TGenerateFppkgConfigurationDialog.BrowseButtonClick(Sender: TObject); +var + Dlg: TSelectDirectoryDialog; +begin + Dlg:=TSelectDirectoryDialog.Create(nil); + try + Dlg.Title:=lisSelectFPCPath; + Dlg.Options:=Dlg.Options+[ofPathMustExist]; + if not Dlg.Execute then exit; + FpcPrefixCombobox.Text:=Dlg.FileName; + finally + Dlg.Free; + end; + UpdateFppkgNote; +end; + +procedure TGenerateFppkgConfigurationDialog.FppkgWriteConfigButtonClick(Sender: TObject); +var + Msg: string; +{$IF FPC_FULLVERSION>30100} + FpcmkcfgExecutable, CompConfigFilename: string; + Proc: TProcessUTF8; + Fppkg: TFppkgHelper; +{$ENDIF} +begin + {$IF FPC_FULLVERSION>30100} + try + FpcmkcfgExecutable := FindFPCTool('fpcmkcfg'+GetExecutableExt, EnvironmentOptions.GetParsedCompilerFilename); + if FpcmkcfgExecutable<>'' then + begin + Proc := TProcessUTF8.Create(nil); + try + Proc.Options := proc.Options + [poWaitOnExit]; + // Write fppkg.cfg + Proc.Executable := FpcmkcfgExecutable; + proc.Parameters.Add('-p'); + proc.Parameters.Add('-3'); + proc.Parameters.Add('-o'); + proc.Parameters.Add(GetFppkgConfigFile(False, False)); + proc.Parameters.Add('-d'); + proc.Parameters.Add('globalpath='+fLastParsedFpcLibPath); + proc.Parameters.Add('-d'); + {$IFDEF WINDOWS} + proc.Parameters.Add('globalprefix='+fLastParsedFpcLibPath); + {$ELSE} + proc.Parameters.Add('globalprefix='+fLastParsedFpcPrefix); + {$ENDIF} + proc.Execute; + + Fppkg:=TFppkgHelper.Instance; + + if proc.ExitStatus <> 0 then + IDEMessageDialog(lisFppkgProblem, Format(lisFppkgCreateFileFailed, [GetFppkgConfigFile(False, False)]), mtWarning, [mbOK]) + else + begin + Fppkg:=TFppkgHelper.Instance; + Fppkg.ReInitialize; + + // Write default compiler configuration file + CompConfigFilename := Fppkg.GetCompilerConfigurationFileName; + if CompConfigFilename <> '' then + begin + proc.Parameters.Clear; + proc.Parameters.Add('-p'); + proc.Parameters.Add('-4'); + proc.Parameters.Add('-o'); + proc.Parameters.Add(CompConfigFilename); + proc.Parameters.Add('-d'); + proc.Parameters.Add('fpcbin='+EnvironmentOptions.GetParsedCompilerFilename); + proc.Execute; + + if proc.ExitStatus <> 0 then + IDEMessageDialog(lisFppkgProblem, Format(lisFppkgCreateFileFailed, [CompConfigFilename]), mtWarning, [mbOK]); + end; + end; + + Fppkg.ReInitialize; + finally + Proc.Free; + end; + end; + except + on E: Exception do + IDEMessageDialog(lisFppkgProblem, Format(lisFppkgWriteConfException, [E.Message]), mtWarning, [mbOK]); + end; + + fLastParsedFpcPrefix := ''; + UpdateFppkgNote; + {$ENDIF} + + if CheckFppkgConfiguration(Msg)<>sddqCompatible then + begin + IDEMessageDialog(lisFppkgProblem, Format(lisFppkgWriteConfFailed, [Msg]), + mtWarning, [mbOK]); + ModalResult := mrCancel; + end + else + ModalResult := mrOK; +end; + + +end. + diff --git a/ide/initialsetupdlgs.lfm b/ide/initialsetupdlgs.lfm index 9087eaa15b..ee48bceeeb 100644 --- a/ide/initialsetupdlgs.lfm +++ b/ide/initialsetupdlgs.lfm @@ -1,12 +1,13 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideBottom.Side = asrBottom Left = 311 - Height = 385 + Height = 770 Top = 238 - Width = 620 + Width = 1240 Caption = 'InitialSetupDialog' - ClientHeight = 385 - ClientWidth = 620 + ClientHeight = 770 + ClientWidth = 1240 + DesignTimePPI = 192 OnCreate = FormCreate OnDestroy = FormDestroy Position = poScreenCenter @@ -17,14 +18,15 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Splitter1 AnchorSideBottom.Control = BtnPanel - Left = 6 - Height = 284 - Top = 54 - Width = 159 + Left = 12 + Height = 570 + Top = 108 + Width = 318 Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Left = 6 - BorderSpacing.Top = 6 + BorderSpacing.Left = 12 + BorderSpacing.Top = 12 Images = ImageList1 + ParentFont = False ReadOnly = True ScrollBars = ssNone ShowButtons = False @@ -38,35 +40,37 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideTop.Control = PropertiesTreeView AnchorSideBottom.Control = PropertiesTreeView AnchorSideBottom.Side = asrBottom - Left = 165 - Height = 284 - Top = 54 - Width = 5 + Left = 330 + Height = 570 + Top = 108 + Width = 10 Align = alNone Anchors = [akTop, akLeft, akBottom] end object BtnPanel: TPanel - Left = 10 - Height = 27 - Top = 348 - Width = 600 + Left = 20 + Height = 52 + Top = 698 + Width = 1200 Align = alBottom AutoSize = True - BorderSpacing.Around = 10 + BorderSpacing.Around = 20 BevelOuter = bvNone - ClientHeight = 27 - ClientWidth = 600 + ClientHeight = 52 + ClientWidth = 1200 + ParentFont = False TabOrder = 2 object StartIDEBitBtn: TBitBtn - Left = 500 - Height = 27 + Left = 986 + Height = 52 Top = 0 - Width = 100 + Width = 214 Align = alRight AutoSize = True Caption = 'StartIDEBitBtn' - Constraints.MinWidth = 100 + Constraints.MinWidth = 200 OnClick = StartIDEBitBtnClick + ParentFont = False TabOrder = 0 end end @@ -78,13 +82,14 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Splitter1 AnchorSideBottom.Side = asrBottom - Left = 170 - Height = 284 - Top = 54 - Width = 444 + Left = 340 + Height = 570 + Top = 108 + Width = 888 ActivePage = FppkgTabSheet Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Right = 6 + BorderSpacing.Right = 12 + ParentFont = False TabIndex = 5 TabOrder = 3 OnChange = PropertiesPageControlChange @@ -95,8 +100,9 @@ object InitialSetupDialog: TInitialSetupDialog ChildSizing.TopBottomSpacing = 6 ChildSizing.HorizontalSpacing = 6 ChildSizing.VerticalSpacing = 6 - ClientHeight = 255 - ClientWidth = 440 + ClientHeight = 520 + ClientWidth = 878 + ParentFont = False object LazDirLabel: TLabel Left = 6 Height = 19 @@ -105,6 +111,7 @@ object InitialSetupDialog: TInitialSetupDialog Align = alTop Caption = 'LazDirLabel' ParentColor = False + ParentFont = False WordWrap = True end object LazDirComboBox: TComboBox @@ -113,13 +120,14 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideTop.Side = asrBottom AnchorSideRight.Control = LazarusTabSheet AnchorSideRight.Side = asrBottom - Left = 6 + Left = 12 Height = 36 - Top = 31 + Top = 62 Width = 422 Anchors = [akTop, akLeft, akRight] ItemHeight = 0 OnChange = LazDirComboBoxChange + ParentFont = False TabOrder = 0 Text = 'LazDirComboBox' end @@ -138,6 +146,7 @@ object InitialSetupDialog: TInitialSetupDialog '' '' ) + ParentFont = False ReadOnly = True TabOrder = 1 end @@ -146,13 +155,14 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideTop.Control = LazDirComboBox AnchorSideTop.Side = asrBottom AnchorSideRight.Side = asrBottom - Left = 6 + Left = 12 Height = 35 - Top = 73 + Top = 146 Width = 155 AutoSize = True Caption = 'LazDirBrowseButton' OnClick = LazDirBrowseButtonClick + ParentFont = False TabOrder = 2 end end @@ -162,8 +172,9 @@ object InitialSetupDialog: TInitialSetupDialog ChildSizing.TopBottomSpacing = 6 ChildSizing.HorizontalSpacing = 6 ChildSizing.VerticalSpacing = 6 - ClientHeight = 255 - ClientWidth = 440 + ClientHeight = 520 + ClientWidth = 878 + ParentFont = False object CompilerLabel: TLabel Left = 6 Height = 19 @@ -172,6 +183,7 @@ object InitialSetupDialog: TInitialSetupDialog Align = alTop Caption = 'CompilerLabel' ParentColor = False + ParentFont = False WordWrap = True end object CompilerComboBox: TComboBox @@ -180,13 +192,14 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideTop.Side = asrBottom AnchorSideRight.Control = CompilerTabSheet AnchorSideRight.Side = asrBottom - Left = 6 + Left = 12 Height = 36 - Top = 31 + Top = 62 Width = 422 Anchors = [akTop, akLeft, akRight] ItemHeight = 0 OnChange = CompilerComboBoxChange + ParentFont = False TabOrder = 0 Text = 'CompilerComboBox' end @@ -194,13 +207,14 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideLeft.Control = CompilerTabSheet AnchorSideTop.Control = CompilerComboBox AnchorSideTop.Side = asrBottom - Left = 6 + Left = 12 Height = 35 - Top = 73 + Top = 146 Width = 172 AutoSize = True Caption = 'CompilerBrowseButton' OnClick = CompilerBrowseButtonClick + ParentFont = False TabOrder = 1 end object CompilerMemo: TMemo @@ -211,9 +225,9 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = CompilerTabSheet AnchorSideBottom.Side = asrBottom - Left = 6 + Left = 12 Height = 106 - Top = 114 + Top = 228 Width = 422 Anchors = [akTop, akLeft, akRight, akBottom] Lines.Strings = ( @@ -221,6 +235,7 @@ object InitialSetupDialog: TInitialSetupDialog '' '' ) + ParentFont = False ReadOnly = True TabOrder = 2 end @@ -231,8 +246,9 @@ object InitialSetupDialog: TInitialSetupDialog ChildSizing.TopBottomSpacing = 6 ChildSizing.HorizontalSpacing = 6 ChildSizing.VerticalSpacing = 6 - ClientHeight = 255 - ClientWidth = 440 + ClientHeight = 520 + ClientWidth = 878 + ParentFont = False object FPCSrcDirLabel: TLabel Left = 6 Height = 19 @@ -241,6 +257,7 @@ object InitialSetupDialog: TInitialSetupDialog Align = alTop Caption = 'FPCSrcDirLabel' ParentColor = False + ParentFont = False WordWrap = True end object FPCSrcDirComboBox: TComboBox @@ -251,6 +268,7 @@ object InitialSetupDialog: TInitialSetupDialog Align = alTop ItemHeight = 0 OnChange = FPCSrcDirComboBoxChange + ParentFont = False TabOrder = 0 Text = 'FPCSrcDirComboBox' end @@ -258,13 +276,14 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideLeft.Control = FPCSourcesTabSheet AnchorSideTop.Control = FPCSrcDirComboBox AnchorSideTop.Side = asrBottom - Left = 6 + Left = 12 Height = 35 - Top = 73 + Top = 146 Width = 182 AutoSize = True Caption = 'FPCSrcDirBrowseButton' OnClick = FPCSrcDirBrowseButtonClick + ParentFont = False TabOrder = 1 end object FPCSrcDirMemo: TMemo @@ -281,6 +300,7 @@ object InitialSetupDialog: TInitialSetupDialog '' '' ) + ParentFont = False ReadOnly = True TabOrder = 2 end @@ -289,24 +309,26 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = FPCSrcDirBrowseButton AnchorSideTop.Side = asrCenter - Left = 200 + Left = 400 Height = 19 - Top = 81 + Top = 162 Width = 60 - BorderSpacing.Left = 12 + BorderSpacing.Left = 24 Caption = 'Scanning' ParentColor = False + ParentFont = False end object ScanProgressBar: TProgressBar AnchorSideLeft.Control = ScanLabel AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = ScanLabel AnchorSideTop.Side = asrCenter - Left = 266 - Height = 20 - Top = 80 - Width = 102 - BorderSpacing.Left = 6 + Left = 532 + Height = 40 + Top = 160 + Width = 204 + BorderSpacing.Left = 12 + ParentFont = False Style = pbstMarquee TabOrder = 3 end @@ -317,28 +339,31 @@ object InitialSetupDialog: TInitialSetupDialog AnchorSideTop.Side = asrCenter AnchorSideRight.Control = ScanProgressBar AnchorSideRight.Side = asrBottom - Left = 374 - Height = 25 - Top = 78 - Width = 78 + Left = 748 + Height = 50 + Top = 156 + Width = 156 Caption = 'Stop' OnClick = StopScanButtonClick + ParentFont = False TabOrder = 4 end end object MakeExeTabSheet: TTabSheet Caption = 'MakeExeTabSheet' - ClientHeight = 255 - ClientWidth = 440 + ClientHeight = 520 + ClientWidth = 878 + ParentFont = False object MakeExeComboBox: TComboBox Left = 6 Height = 36 Top = 31 Width = 422 Align = alTop - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 ItemHeight = 0 OnChange = MakeExeComboBoxChange + ParentFont = False TabOrder = 0 Text = 'MakeExeComboBox' end @@ -348,23 +373,25 @@ object InitialSetupDialog: TInitialSetupDialog Top = 6 Width = 422 Align = alTop - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Caption = 'MakeExeLabel' ParentColor = False + ParentFont = False WordWrap = True end object MakeExeBrowseButton: TButton AnchorSideLeft.Control = MakeExeTabSheet AnchorSideTop.Control = MakeExeComboBox AnchorSideTop.Side = asrBottom - Left = 6 + Left = 12 Height = 35 - Top = 73 + Top = 146 Width = 171 AutoSize = True - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Caption = 'MakeExeBrowseButton' OnClick = MakeExeBrowseButtonClick + ParentFont = False TabOrder = 1 end object MakeExeMemo: TMemo @@ -376,29 +403,32 @@ object InitialSetupDialog: TInitialSetupDialog Width = 422 Align = alBottom Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Lines.Strings = ( 'FPCSrcDirMemo' '' '' ) + ParentFont = False ReadOnly = True TabOrder = 2 end end object DebuggerTabSheet: TTabSheet Caption = 'DebuggerTabSheet' - ClientHeight = 255 - ClientWidth = 440 + ClientHeight = 520 + ClientWidth = 878 + ParentFont = False object DebuggerComboBox: TComboBox Left = 6 Height = 36 Top = 31 Width = 422 Align = alTop - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 ItemHeight = 0 OnChange = DebuggerComboBoxChange + ParentFont = False TabOrder = 0 Text = 'DebuggerComboBox' end @@ -408,23 +438,25 @@ object InitialSetupDialog: TInitialSetupDialog Top = 6 Width = 422 Align = alTop - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Caption = 'DebuggerLabel' ParentColor = False + ParentFont = False WordWrap = True end object DebuggerBrowseButton: TButton AnchorSideLeft.Control = DebuggerTabSheet AnchorSideTop.Control = DebuggerComboBox AnchorSideTop.Side = asrBottom - Left = 6 + Left = 12 Height = 35 - Top = 73 + Top = 146 Width = 176 AutoSize = True - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Caption = 'DebuggerBrowseButton' OnClick = DebuggerBrowseButtonClick + ParentFont = False TabOrder = 1 end object DebuggerMemo: TMemo @@ -436,103 +468,113 @@ object InitialSetupDialog: TInitialSetupDialog Width = 422 Align = alBottom Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Lines.Strings = ( 'FPCSrcDirMemo' '' '' ) + ParentFont = False ReadOnly = True TabOrder = 2 end end object FppkgTabSheet: TTabSheet Caption = 'FppkgTabSheet' - ClientHeight = 255 - ClientWidth = 440 + ClientHeight = 520 + ClientWidth = 878 + ParentFont = False object FppkgComboBox: TComboBox - Left = 6 - Height = 27 - Top = 27 - Width = 428 + Left = 12 + Height = 53 + Top = 12 + Width = 854 Align = alTop - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 ItemHeight = 0 OnChange = FppkgComboBoxChange + ParentFont = False TabOrder = 0 Text = 'FppkgComboBox' + Visible = False end object FppkgLabel: TLabel - Left = 6 - Height = 15 - Top = 6 - Width = 428 + Left = 12 + Height = 36 + Top = 77 + Width = 854 Align = alTop - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Caption = 'FppkgLabel' ParentColor = False + ParentFont = False WordWrap = True end object FppkgBrowseButton: TButton AnchorSideLeft.Control = FppkgTabSheet AnchorSideTop.Control = FppkgComboBox AnchorSideTop.Side = asrBottom - Left = 6 - Height = 27 - Top = 60 - Width = 125 + Left = 12 + Height = 52 + Top = 77 + Width = 289 AutoSize = True - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Caption = 'FppkgBrowseButton' OnClick = FppkgBrowseButtonClick + ParentFont = False TabOrder = 1 + Visible = False end object FppkgMemo: TMemo - AnchorSideTop.Control = FppkgBrowseButton + AnchorSideTop.Control = FppkgWriteConfigButton AnchorSideTop.Side = asrBottom - Left = 6 - Height = 156 - Top = 93 - Width = 428 + Left = 12 + Height = 319 + Top = 189 + Width = 854 Align = alBottom Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Lines.Strings = ( 'FPCSrcDirMemo' '' '' ) + ParentFont = False ReadOnly = True TabOrder = 2 end object FppkgWriteConfigButton: TButton AnchorSideLeft.Control = DebuggerTabSheet - AnchorSideTop.Control = FppkgComboBox + AnchorSideTop.Control = FppkgLabel AnchorSideTop.Side = asrBottom - Left = 283 - Height = 27 - Top = 60 - Width = 151 + Left = 515 + Height = 52 + Top = 125 + Width = 351 Anchors = [akTop, akRight] AutoSize = True - BorderSpacing.Around = 6 + BorderSpacing.Around = 12 Caption = 'FppkgWriteConfigButton' Enabled = False OnClick = FppkgWriteConfigButtonClick + ParentFont = False TabOrder = 3 end end end object WelcomePaintBox: TPaintBox Left = 0 - Height = 48 + Height = 96 Top = 0 - Width = 620 + Width = 1240 Align = alTop + ParentFont = False OnPaint = WelcomePaintBoxPaint end object ImageList1: TImageList - left = 55 - top = 145 + Left = 110 + Top = 290 end end diff --git a/ide/initialsetupdlgs.pas b/ide/initialsetupdlgs.pas index b37b1169f6..865ea45412 100644 --- a/ide/initialsetupdlgs.pas +++ b/ide/initialsetupdlgs.pas @@ -44,7 +44,6 @@ uses Classes, SysUtils, Forms, Controls, Buttons, Dialogs, Graphics, ComCtrls, ExtCtrls, StdCtrls, LCLProc, pkgglobals, process, - {$IF FPC_FULLVERSION>30100}UTF8Process,{$ENDIF} fpmkunit, // CodeTools FileProcs, CodeToolManager, DefineTemplates, @@ -54,7 +53,7 @@ uses MacroDefIntf, GDBMIDebugger, DbgIntfDebuggerBase, IDEDialogs, TransferMacros, LazarusIDEStrConsts, LazConf, EnvironmentOpts, IDEImagesIntf, AboutFrm, IDETranslations, BaseBuildManager, InitialSetupProc, FppkgHelper, - IDEProcs; + IDEProcs, GenerateFppkgConfigurationDlg; type TInitialSetupDialog = class; @@ -156,7 +155,6 @@ type fLastParsedMakeExe: string; fLastParsedDebugger: string; fLastParsedFppkgPrefix: string; - fLastParsedFppkgLibPath: string; FIdleConnected: boolean; ImgIDError: LongInt; ImgIDWarning: LongInt; @@ -194,7 +192,6 @@ type procedure ThreadTerminated(Sender: TObject); // called in main thread by fSearchFpcSourceThread.OnTerminate procedure TranslateResourceStrings; function CheckFppkgQuality(APrefix: string; out LibPath, Note: string): TSDFilenameQuality; - function CheckFpcmkcfgQuality(out Note: string): TSDFilenameQuality; public TVNodeLazarus: TTreeNode; TVNodeCompiler: TTreeNode; @@ -795,11 +792,7 @@ begin LazDirLabel.Caption:=SimpleFormat( lisTheLazarusDirectoryContainsTheSourcesOfTheIDEAndTh, [PathDelim]); - {$IFDEF WINDOWS} - FppkgLabel.Caption:=Format(lisFppkgInstallationPath, [GetFPCVer+PathDelim+'units', GetFPCVer+PathDelim+'fpmkinst']); - {$ELSE} - FppkgLabel.Caption:=Format(lisFppkgInstallationPath, ['lib/fpc', 'lib64/fpc']); - {$ENDIF WINDOWS} + FppkgLabel.Caption:=lisFppkgConfiguration; FppkgBrowseButton.Caption:=lisPathEditBrowse; FppkgWriteConfigButton.Caption:=lisCreateFppkgConfig; @@ -1377,7 +1370,7 @@ end; procedure TInitialSetupDialog.UpdateFppkgNote; var CurCaption: String; - Msg, FppkgMsg, Note: string; + FppkgMsg, Note: string; Quality: TSDFilenameQuality; {$IF FPC_FULLVERSION>30100} ImageIndex: Integer; @@ -1390,26 +1383,15 @@ begin Quality := CheckFppkgConfiguration(FppkgMsg); - Msg := ''; - if CheckFppkgQuality(CurCaption,fLastParsedFppkgLibPath,Note)<>sddqCompatible then - Msg := Note; - if (CheckFPCExeQuality(fLastParsedCompiler,Note, CodeToolBoss.CompilerDefinesCache.TestFilename)<>sddqCompatible) then - Msg := Msg + lisWarning + lisFppkgCompilerProblem +Note; - if CheckFpcmkcfgQuality(Note) <> sddqCompatible then - Msg := Msg + lisWarning + Note; - if Quality=sddqCompatible then - Note := lisOk - else - Note := lisError + Format(lisIncorrectFppkgConfiguration, [FppkgMsg]) + LineEnding; - - if Msg<>'' then begin - Note := Note + LineEnding + Msg; + Note := lisOk; FppkgWriteConfigButton.Enabled := False; end else begin + Note := lisError + Format(lisIncorrectFppkgConfiguration, [FppkgMsg]) + LineEnding; + Note := Note + LineEnding + lisFppkgFixConfiguration; FppkgWriteConfigButton.Enabled := True; end; @@ -1587,149 +1569,24 @@ begin end; procedure TInitialSetupDialog.FppkgWriteConfigButtonClick(Sender: TObject); -var - Msg: string; {$IF FPC_FULLVERSION>30100} - FpcmkcfgExecutable, CompConfigFilename: string; - Proc: TProcessUTF8; - Fppkg: TFppkgHelper; +var + Dialog: TGenerateFppkgConfigurationDialog; {$ENDIF} begin {$IF FPC_FULLVERSION>30100} + Dialog := TGenerateFppkgConfigurationDialog.Create(Self); try - FpcmkcfgExecutable := FindFPCTool('fpcmkcfg'+GetExecutableExt, EnvironmentOptions.GetParsedCompilerFilename); - if FpcmkcfgExecutable<>'' then - begin - Proc := TProcessUTF8.Create(nil); - try - Proc.Options := proc.Options + [poWaitOnExit]; - // Write fppkg.cfg - Proc.Executable := FpcmkcfgExecutable; - proc.Parameters.Add('-p'); - proc.Parameters.Add('-3'); - proc.Parameters.Add('-o'); - proc.Parameters.Add(GetFppkgConfigFile(False, False)); - proc.Parameters.Add('-d'); - proc.Parameters.Add('globalpath='+fLastParsedFppkgLibPath); - proc.Parameters.Add('-d'); - {$IFDEF WINDOWS} - proc.Parameters.Add('globalprefix='+fLastParsedFppkgLibPath); - {$ELSE} - proc.Parameters.Add('globalprefix='+fLastParsedFppkgPrefix); - {$ENDIF} - proc.Execute; - - Fppkg:=TFppkgHelper.Instance; - - if proc.ExitStatus <> 0 then - IDEMessageDialog(lisFppkgProblem, Format(lisFppkgCreateFileFailed, [GetFppkgConfigFile(False, False)]), mtWarning, [mbOK]) - else - begin - Fppkg:=TFppkgHelper.Instance; - Fppkg.ReInitialize; - - // Write default compiler configuration file - CompConfigFilename := Fppkg.GetCompilerConfigurationFileName; - if CompConfigFilename <> '' then - begin - proc.Parameters.Clear; - proc.Parameters.Add('-p'); - proc.Parameters.Add('-4'); - proc.Parameters.Add('-o'); - proc.Parameters.Add(CompConfigFilename); - proc.Parameters.Add('-d'); - proc.Parameters.Add('fpcbin='+EnvironmentOptions.GetParsedCompilerFilename); - proc.Execute; - - if proc.ExitStatus <> 0 then - IDEMessageDialog(lisFppkgProblem, Format(lisFppkgCreateFileFailed, [CompConfigFilename]), mtWarning, [mbOK]); - end; - end; - - Fppkg.ReInitialize; - finally - Proc.Free; - end; - end; - except - on E: Exception do - IDEMessageDialog(lisFppkgProblem, Format(lisFppkgWriteConfException, [E.Message]), mtWarning, [mbOK]); + Dialog.Compiler := fLastParsedCompiler; + Dialog.FppkgCfgFilename := GetFppkgConfigFile(False, False); + Dialog.ShowModal; + finally + Dialog.Free; end; fLastParsedFppkgPrefix := ''; UpdateFppkgNote; {$ENDIF} - - if CheckFppkgConfiguration(Msg)<>sddqCompatible then - begin - IDEMessageDialog(lisFppkgProblem, Format(lisFppkgWriteConfFailed, [Msg]), - mtWarning, [mbOK]); - end; -end; - -function TInitialSetupDialog.CheckFpcmkcfgQuality(out Note: string): TSDFilenameQuality; -{$IF FPC_FULLVERSION>30100} -var - FpcmkcfgExecutable: string; - Proc: TProcessUTF8; - S: string; - Ver: TFPVersion; -{$ENDIF} -begin - Result := sddqCompatible; - Note:=''; - {$IF FPC_FULLVERSION>30100} - FpcmkcfgExecutable := FindFPCTool('fpcmkcfg'+GetExecutableExt, EnvironmentOptions.GetParsedCompilerFilename); - if FpcmkcfgExecutable = '' then - begin - Note := lisFppkgFpcmkcfgMissing + ' ' + lisFppkgRecentFpcmkcfgNeeded; - Result := sddqInvalid; - end - else - begin - Proc := TProcessUTF8.Create(nil); - try - Proc.Options := proc.Options + [poWaitOnExit,poUsePipes]; - // Write fppkg.cfg - Proc.Executable := FpcmkcfgExecutable; - proc.Parameters.Add('-V'); - proc.Execute; - - if proc.ExitStatus <> 0 then - begin - Note := lisFppkgFpcmkcfgCheckFailed + ' ' + lisFppkgFpcmkcfgProbTooOld + ' ' + lisFppkgRecentFpcmkcfgNeeded; - Result := sddqInvalid; - end - else - begin - SetLength(S, Proc.Output.NumBytesAvailable); - Proc.Output.Read(S[1], Proc.Output.NumBytesAvailable); - Ver := TFPVersion.Create; - try - S := Copy(S, pos(':', S)+2); - Ver.AsString := Trim(S); - if Ver.Major = -1 then - begin - Note := lisFppkgFpcmkcfgCheckFailed + ' ' + lisFppkgFpcmkcfgNeeded + lisFppkgRecentFpcmkcfgNeeded; - Result := sddqInvalid; - end - else if not ((Ver.Major = 0) or (Ver.Major > 3) or (((Ver.Major = 3)) and (Ver.Minor>1))) then - begin - // fpcmkcfg's version must be > 3.1. Older versions need other - // parameters. Version 0 is also allowed, because it is probably - // self-built. - Note := Format( lisFppkgFpcmkcfgTooOld, [Ver.AsString]) + ' ' + lisFppkgFpcmkcfgNeeded + ' ' + lisFppkgRecentFpcmkcfgNeeded; - Result := sddqInvalid; - end; - finally - Ver.Free; - end; - end; - finally - Proc.Free; - end; - end; - {$ENDIF} end; end. diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index e712e56c10..2ea6b40b8c 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -1042,10 +1042,9 @@ resourcestring lisIncorrectFppkgConfiguration = 'there is a problem with the Fppkg configuration. (%s)'; lisFppkgCompilerProblem = 'there is a problem with the Free Pascal compiler executable, '; lisFppkgInstallationPath = 'The prefix of the Free Pascal Compiler installation ' + - 'is required to create new configuration files for Fppkg. For example it has ' + - 'the units "%s" and/or "%s"'; + 'is required. For example it has the units "%s" and/or "%s"'; lisSelectFPCPath = 'Select the path where FPC is installed'; - lisCreateFppkgConfig = 'Create new Fppkg configuration'; + lisCreateFppkgConfig = 'Restore Fppkg configuration'; lisFppkgProblem = 'Problem with Fppkg configuration'; lisFreePascalPrefix = 'Free Pascal compiler prefix'; lisFppkgWriteConfException = 'A problem occurred while trying to create a new ' + @@ -1068,6 +1067,21 @@ resourcestring lisFppkgCompilerNotFound = 'Could not find the compiler [%s] configured for Fppkg.'; lisFppkgCompilerNotExists = 'The compiler [%s] configured for Fppkg does not exist.'; lisFppkgCompilerNotExecutable = 'The compiler [%s] configured for Fppkg is not an executable.'; + lisGenerateFppkgConfigurationCaption = 'Generate new Fppkg configuration files.'; + lisGenerateFppkgConfiguration = 'Use this screen to generate new Fppkg configuration-files ' + + 'with the fpcmkcfg tool.'; + lisFppkgConfGenProblems = 'Warnings have to be resolved first'; + lisFppkgFilesToBeWritten = 'Files to be written:'; + lisGenerateFppkgCfg = 'Fppkg configuration: %s'; + lisGenerateFppkgCompCfg = 'Fppkg compiler configuration: %s'; + lisFppkgWriteConfigFile = 'Write new configuration files'; + lisFppkgPrefix = 'Fpc prefix: %s'; + lisFppkgLibPrefix = 'Fpc library prefix: %s'; + lisFppkgConfiguration = 'Fppkg is the Free Pascal package manager. When it is not ' + + 'configured properly, it may be impossible to resolve dependencies on Free Pascal ' + + 'packages.'; + lisFppkgFixConfiguration = 'You could try to restore the configuration files automatically, ' + + 'or adapt fppkg.cfg manually.'; // file dialogs lisOpenFile = 'Open File';