diff --git a/.gitattributes b/.gitattributes
index 493acf97ae..fcc50b47e6 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1446,6 +1446,8 @@ components/fppkg/src/fppkg_aboutfrm.pas svneol=native#text/plain
components/fppkg/src/fppkg_const.pas svneol=native#text/plain
components/fppkg/src/fppkg_details.lfm svneol=native#text/plain
components/fppkg/src/fppkg_details.pas svneol=native#text/plain
+components/fppkg/src/fppkg_initializeoptionsfrm.lfm svneol=native#text/plain
+components/fppkg/src/fppkg_initializeoptionsfrm.pas svneol=native#text/pascal
components/fppkg/src/fppkg_lpk.pas svneol=native#text/plain
components/fppkg/src/fppkg_mainfrm.lfm svneol=native#text/plain
components/fppkg/src/fppkg_mainfrm.lrj svneol=native#text/plain
diff --git a/components/fppkg/languages/lazarusfppkg.po b/components/fppkg/languages/lazarusfppkg.po
index a121c8de10..ee3e90ffb0 100644
--- a/components/fppkg/languages/lazarusfppkg.po
+++ b/components/fppkg/languages/lazarusfppkg.po
@@ -200,3 +200,49 @@ msgstr ""
msgid "Update packages list"
msgstr ""
+#: tinitializeoptionsform.advancedcheckbox.caption
+msgid "Advanced"
+msgstr ""
+
+#: tinitializeoptionsform.buttonpanel.closebutton.caption
+msgctxt "tinitializeoptionsform.buttonpanel.closebutton.caption"
+msgid "&Close"
+msgstr ""
+
+#: tinitializeoptionsform.buttonpanel.okbutton.caption
+msgctxt "tinitializeoptionsform.buttonpanel.okbutton.caption"
+msgid "&Write Fppkg configuration files"
+msgstr ""
+
+#: tinitializeoptionsform.caption
+msgid "Create configuration files"
+msgstr ""
+
+#: tinitializeoptionsform.compilerlabel.caption
+msgid "Compiler:"
+msgstr ""
+
+#: tinitializeoptionsform.edit1.text
+msgid "Edit1"
+msgstr ""
+
+#: tinitializeoptionsform.fpcdirectoryedit.texthint
+msgid "This location normally contains the compiler-executable along with a 'units' and 'fpmkinst' directory."
+msgstr ""
+
+#: tinitializeoptionsform.initializefppkglabel.caption
+msgid "Create new configuration files for fppkg."
+msgstr ""
+
+#: tinitializeoptionsform.label1.caption
+msgid "Please give the location where FPC is installed."
+msgstr ""
+
+#: tinitializeoptionsform.pathlabel.caption
+msgid "Path:"
+msgstr ""
+
+#: tinitializeoptionsform.prefixlabel.caption
+msgid "Prefix:"
+msgstr ""
+
diff --git a/components/fppkg/languages/lazarusfppkg.ru.po b/components/fppkg/languages/lazarusfppkg.ru.po
index aa6e2ab987..b0be224a46 100644
--- a/components/fppkg/languages/lazarusfppkg.ru.po
+++ b/components/fppkg/languages/lazarusfppkg.ru.po
@@ -213,3 +213,49 @@ msgstr "Обновить"
msgid "Update packages list"
msgstr "Обновить список пакетов"
+#: tinitializeoptionsform.advancedcheckbox.caption
+msgid "Advanced"
+msgstr ""
+
+#: tinitializeoptionsform.buttonpanel.closebutton.caption
+msgctxt "tinitializeoptionsform.buttonpanel.closebutton.caption"
+msgid "&Close"
+msgstr ""
+
+#: tinitializeoptionsform.buttonpanel.okbutton.caption
+msgctxt "tinitializeoptionsform.buttonpanel.okbutton.caption"
+msgid "&Write Fppkg configuration files"
+msgstr ""
+
+#: tinitializeoptionsform.caption
+msgid "Create configuration files"
+msgstr ""
+
+#: tinitializeoptionsform.compilerlabel.caption
+msgid "Compiler:"
+msgstr ""
+
+#: tinitializeoptionsform.edit1.text
+msgid "Edit1"
+msgstr ""
+
+#: tinitializeoptionsform.fpcdirectoryedit.texthint
+msgid "This location normally contains the compiler-executable along with a 'units' and 'fpmkinst' directory."
+msgstr ""
+
+#: tinitializeoptionsform.initializefppkglabel.caption
+msgid "Create new configuration files for fppkg."
+msgstr ""
+
+#: tinitializeoptionsform.label1.caption
+msgid "Please give the location where FPC is installed."
+msgstr ""
+
+#: tinitializeoptionsform.pathlabel.caption
+msgid "Path:"
+msgstr ""
+
+#: tinitializeoptionsform.prefixlabel.caption
+msgid "Prefix:"
+msgstr ""
+
diff --git a/components/fppkg/src/fppkg_initializeoptionsfrm.lfm b/components/fppkg/src/fppkg_initializeoptionsfrm.lfm
new file mode 100644
index 0000000000..44f24bade4
--- /dev/null
+++ b/components/fppkg/src/fppkg_initializeoptionsfrm.lfm
@@ -0,0 +1,190 @@
+object InitializeOptionsForm: TInitializeOptionsForm
+ Left = 2095
+ Height = 451
+ Top = 274
+ Width = 473
+ Caption = 'Create configuration files'
+ ClientHeight = 451
+ ClientWidth = 473
+ LCLVersion = '1.9.0.0'
+ object FppkgConfigPanel: TPanel
+ Left = 0
+ Height = 451
+ Top = 0
+ Width = 473
+ Align = alClient
+ BevelOuter = bvNone
+ ClientHeight = 451
+ ClientWidth = 473
+ TabOrder = 0
+ Visible = False
+ object InitializeFppkgLabel: TLabel
+ Left = 5
+ Height = 20
+ Top = 5
+ Width = 463
+ Align = alTop
+ BorderSpacing.Around = 5
+ Caption = 'Create new configuration files for fppkg.'
+ ParentColor = False
+ end
+ object Label1: TLabel
+ Left = 30
+ Height = 20
+ Top = 40
+ Width = 438
+ Align = alTop
+ BorderSpacing.Left = 25
+ BorderSpacing.Top = 10
+ BorderSpacing.Around = 5
+ Caption = 'Please give the location where FPC is installed.'
+ ParentColor = False
+ end
+ object Edit1: TEdit
+ Left = -2368
+ Height = 37
+ Top = 119
+ Width = 80
+ TabOrder = 0
+ Text = 'Edit1'
+ end
+ object FPCDirectoryEdit: TDirectoryEdit
+ Left = 30
+ Height = 37
+ Top = 65
+ Width = 413
+ ShowHidden = False
+ ButtonWidth = 23
+ NumGlyphs = 1
+ Align = alTop
+ BorderSpacing.Left = 25
+ BorderSpacing.Right = 25
+ BorderSpacing.Around = 5
+ BorderSpacing.CellAlignHorizontal = ccaCenter
+ MaxLength = 0
+ TabOrder = 1
+ OnChange = FPCDirectoryEditChange
+ TextHint = 'This location normally contains the compiler-executable along with a ''units'' and ''fpmkinst'' directory.'
+ end
+ object FPCDirValidationLabel: TLabel
+ Left = 30
+ Height = 20
+ Top = 107
+ Width = 438
+ Align = alTop
+ AutoSize = False
+ BorderSpacing.Left = 25
+ BorderSpacing.Around = 5
+ Font.Color = clMaroon
+ ParentColor = False
+ ParentFont = False
+ end
+ object ButtonPanel: TButtonPanel
+ Left = 6
+ Height = 46
+ Top = 399
+ Width = 461
+ OKButton.Name = 'OKButton'
+ OKButton.Caption = '&Write Fppkg configuration files'
+ OKButton.DefaultCaption = False
+ OKButton.Enabled = False
+ OKButton.OnClick = OKButtonClick
+ HelpButton.Name = 'HelpButton'
+ HelpButton.DefaultCaption = True
+ CloseButton.Name = 'CloseButton'
+ CloseButton.Caption = '&Close'
+ CloseButton.DefaultCaption = False
+ CloseButton.OnClick = CloseButtonClick
+ CancelButton.Name = 'CancelButton'
+ CancelButton.DefaultCaption = True
+ TabOrder = 2
+ ShowButtons = [pbOK, pbClose]
+ end
+ object AdvancedCheckbox: TCheckBox
+ Left = 5
+ Height = 24
+ Top = 132
+ Width = 463
+ Align = alTop
+ BorderSpacing.Around = 5
+ Caption = 'Advanced'
+ OnChange = AdvancedCheckboxChange
+ TabOrder = 3
+ end
+ object PathLabel: TLabel
+ Left = 30
+ Height = 20
+ Top = 171
+ Width = 438
+ Align = alTop
+ BorderSpacing.Left = 25
+ BorderSpacing.Top = 10
+ BorderSpacing.Around = 5
+ Caption = 'Path:'
+ Enabled = False
+ ParentColor = False
+ end
+ object PathEdit: TEdit
+ Left = 30
+ Height = 37
+ Top = 196
+ Width = 413
+ Align = alTop
+ BorderSpacing.Left = 25
+ BorderSpacing.Right = 25
+ BorderSpacing.Around = 5
+ Enabled = False
+ TabOrder = 4
+ end
+ object PrefixLabel: TLabel
+ Left = 30
+ Height = 20
+ Top = 248
+ Width = 438
+ Align = alTop
+ BorderSpacing.Left = 25
+ BorderSpacing.Top = 10
+ BorderSpacing.Around = 5
+ Caption = 'Prefix:'
+ Enabled = False
+ ParentColor = False
+ end
+ object PrefixEdit: TEdit
+ Left = 30
+ Height = 37
+ Top = 273
+ Width = 413
+ Align = alTop
+ BorderSpacing.Left = 25
+ BorderSpacing.Right = 25
+ BorderSpacing.Around = 5
+ Enabled = False
+ TabOrder = 5
+ end
+ object CompilerLabel: TLabel
+ Left = 30
+ Height = 20
+ Top = 325
+ Width = 438
+ Align = alTop
+ BorderSpacing.Left = 25
+ BorderSpacing.Top = 10
+ BorderSpacing.Around = 5
+ Caption = 'Compiler:'
+ Enabled = False
+ ParentColor = False
+ end
+ object CompilerEdit: TEdit
+ Left = 30
+ Height = 37
+ Top = 350
+ Width = 413
+ Align = alTop
+ BorderSpacing.Left = 25
+ BorderSpacing.Right = 25
+ BorderSpacing.Around = 5
+ Enabled = False
+ TabOrder = 6
+ end
+ end
+end
diff --git a/components/fppkg/src/fppkg_initializeoptionsfrm.pas b/components/fppkg/src/fppkg_initializeoptionsfrm.pas
new file mode 100644
index 0000000000..fad2a1e8c5
--- /dev/null
+++ b/components/fppkg/src/fppkg_initializeoptionsfrm.pas
@@ -0,0 +1,206 @@
+unit fppkg_initializeoptionsfrm;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, EditBtn,
+ ButtonPanel,
+ // fppkg
+ pkgglobals, pkgFppkg, pkgoptions;
+
+type
+
+ { TInitializeOptionsForm }
+
+ TInitializeOptionsForm = class(TForm)
+ ButtonPanel: TButtonPanel;
+ AdvancedCheckbox: TCheckBox;
+ CompilerEdit: TEdit;
+ PrefixLabel: TLabel;
+ PathEdit: TEdit;
+ FPCDirectoryEdit: TDirectoryEdit;
+ Edit1: TEdit;
+ FppkgConfigPanel: TPanel;
+ InitializeFppkgLabel: TLabel;
+ Label1: TLabel;
+ FPCDirValidationLabel: TLabel;
+ PathLabel: TLabel;
+ PrefixEdit: TEdit;
+ CompilerLabel: TLabel;
+ procedure AdvancedCheckboxChange(Sender: TObject);
+ procedure CloseButtonClick(Sender: TObject);
+ procedure FPCDirectoryEditChange(Sender: TObject);
+ procedure OKButtonClick(Sender: TObject);
+ private
+ function IsVersionStr(AString: string): Boolean;
+ public
+ class function CheckInitialConfiguration: Boolean;
+ class function RecreateFppkgConfiguration: Boolean;
+ end;
+
+var
+ InitializeOptionsForm: TInitializeOptionsForm;
+
+implementation
+
+{$R *.lfm}
+
+{ TInitializeOptionsForm }
+
+procedure TInitializeOptionsForm.FPCDirectoryEditChange(Sender: TObject);
+var
+ SR: TSearchRec;
+ Dir: string;
+ Prefix, s: RawByteString;
+begin
+ Dir := IncludeTrailingPathDelimiter(FPCDirectoryEdit.Text);
+ if not DirectoryExists(Dir) then
+ FPCDirValidationLabel.Caption := 'Directory does not exist'
+ else
+ begin
+ if FindFirst(Dir+'ppc*'+ExeExt, faAnyFile-faDirectory, SR) = 0 then
+ begin
+ FindClose(SR);
+ if FileExists(Dir+'units') and FileExists(Dir+'fpmkinst') then
+ begin
+ FPCDirValidationLabel.Caption := '';
+ ButtonPanel.OKButton.Enabled := True;
+
+ s := ExtractFileName(ExcludeTrailingPathDelimiter(Dir));
+ Prefix := ExtractFilePath(ExcludeTrailingPathDelimiter(Dir));
+
+ if IsVersionStr(s) then
+ PathEdit.Text := Prefix + '{CompilerVersion}' + PathDelim
+ else
+ PathEdit.Text := Dir;
+
+ Prefix := ExtractFilePath(ExcludeTrailingPathDelimiter(Prefix));
+ Prefix := ExtractFilePath(ExcludeTrailingPathDelimiter(Prefix));
+ PrefixEdit.Text := Prefix;
+
+ s := ConcatPaths([Prefix, 'bin', 'fpc'+ExeExt]);
+ if FileExists(s) then
+ CompilerEdit.Text := s
+ else
+ CompilerEdit.Text := ExeSearch('fpc'+ExeExt,GetEnvironmentVariable('PATH'));
+ end
+ else
+ FPCDirValidationLabel.Caption := 'This location does not seems to contain a valid fpc-installation'
+ end
+ else
+ begin
+ FPCDirValidationLabel.Caption := 'Compiler not found at given location'
+ end;
+ end
+end;
+
+procedure TInitializeOptionsForm.CloseButtonClick(Sender: TObject);
+begin
+ ModalResult := mrClose;
+end;
+
+procedure TInitializeOptionsForm.AdvancedCheckboxChange(Sender: TObject);
+begin
+ PathLabel.Enabled := AdvancedCheckbox.Checked;
+ PrefixLabel.Enabled := AdvancedCheckbox.Checked;
+ PathEdit.Enabled := AdvancedCheckbox.Checked;
+ PrefixEdit.Enabled := AdvancedCheckbox.Checked;
+end;
+
+procedure TInitializeOptionsForm.OKButtonClick(Sender: TObject);
+var
+ FPpkg: TpkgFPpkg;
+ FileName: string;
+ CurrentSection: TFppkgRepositoryOptionSection;
+ Dir: string;
+begin
+ Dir := IncludeTrailingPathDelimiter(FPCDirectoryEdit.Text);
+ FPpkg := TpkgFPpkg.Create(Self);
+ try
+ CurrentSection := FPpkg.Options.AddRepositoryOptionSection(TFppkgRepositoryOptionSection);
+ CurrentSection.RepositoryName := 'fpc';
+ CurrentSection.Description := 'Packages which are installed along with the Free Pascal Compiler';
+ CurrentSection.Path := PathEdit.Text;
+ CurrentSection.Prefix := PrefixEdit.Text;
+
+ FPpkg.Options.AddIncludeFilesOptionSection('{LocalRepository}config/conf.d/*.conf');
+
+ CurrentSection := FPpkg.Options.AddRepositoryOptionSection(TFppkgRepositoryOptionSection);
+ CurrentSection.RepositoryName := 'user';
+ CurrentSection.Description := 'User-installed packages';
+ CurrentSection.Path := '{LocalRepository}lib/fpc/{CompilerVersion}/';
+ CurrentSection.Prefix := '{LocalRepository}';
+
+ FileName := GetFppkgConfigFile(False, False);
+ ForceDirectories(ExtractFilePath(FileName));
+ FPpkg.Options.SaveToFile(FileName);
+
+ // Load the just created configuration-file.
+ FPpkg.InitializeGlobalOptions(FileName);
+ FPpkg.CompilerOptions.Compiler := CompilerEdit.Text;
+ // Remove the default configuration-file, so a new one will be generated
+ FileName:=FPpkg.Options.GlobalSection.CompilerConfigDir+FPpkg.Options.CommandLineSection.CompilerConfig;
+ if FileExists(FileName) then
+ DeleteFile(FileName);
+ // This will create the compiler-configuration file
+ FPpkg.InitializeCompilerOptions;
+ finally
+ FPpkg.Free;
+ end;
+end;
+
+function TInitializeOptionsForm.IsVersionStr(AString: string): Boolean;
+var
+ i: Integer;
+begin
+ Result := length(AString) > 0;
+ for i := 1 to length(AString) do
+ begin
+ // only allow digits or a dot.
+ if AString[i] in ['0'..'9'] then
+ Continue
+ // allow dots, but not as first or last character
+ else if (AString[i] = '.') and (i > 1) and (i < length(AString)) then
+ begin
+ // do not allow two consecutive dots
+ if (i > 1) and (AString[i-1]='.') then
+ Result := False;
+ end
+ else
+ begin
+ Result := False;
+ Exit;
+ end;
+ end;
+end;
+
+class function TInitializeOptionsForm.CheckInitialConfiguration: Boolean;
+begin
+ Result := true;
+ if not FileExists(GetFppkgConfigFile(False, False)) and
+ not FileExists(GetFppkgConfigFile(True, False)) then
+ begin
+ Result := RecreateFppkgConfiguration;
+ end;
+end;
+
+class function TInitializeOptionsForm.RecreateFppkgConfiguration: Boolean;
+var
+ Frm: TInitializeOptionsForm;
+begin
+ Frm := TInitializeOptionsForm.Create(nil);
+ try
+ Frm.FppkgConfigPanel.Visible := True;
+ if Frm.ShowModal in [mrClose, mrCancel] then
+ Result := False
+ else
+ Result := True;
+ finally
+ Frm.Free;
+ end;
+end;
+
+end.
+
diff --git a/components/fppkg/src/fppkg_mainfrm.pas b/components/fppkg/src/fppkg_mainfrm.pas
index 8a29be91d1..54e4809cbc 100644
--- a/components/fppkg/src/fppkg_mainfrm.pas
+++ b/components/fppkg/src/fppkg_mainfrm.pas
@@ -154,6 +154,7 @@ type
procedure UpdatePackageListView;
procedure ListPackages;
+ procedure LoadFppkgConfiguration;
procedure RescanPackages;
procedure SetupColumns;
@@ -172,7 +173,7 @@ implementation
{$R *.lfm}
uses
- Masks, fppkg_aboutfrm;
+ Masks, fppkg_aboutfrm, fppkg_initializeoptionsfrm;
resourcestring
SErrActionFailed = 'Failed to %s: ' + sLineBreak + sLineBreak + '%s';
@@ -333,8 +334,6 @@ begin
end;
procedure TFppkgForm.FormCreate(Sender: TObject);
-var
- i: Integer;
begin
//setup log callback function
@@ -351,24 +350,15 @@ begin
//setup error callback function
ErrorHandler := @LazError;
+ if not TInitializeOptionsForm.CheckInitialConfiguration then
+ begin
+ Application.Terminate;
+ Exit;
+ end;
+
FFPpkg := TpkgFPpkg.Create(Self);
- FFPpkg.InitializeGlobalOptions('');
-
- FFPpkg.Options.GlobalSection.Downloader := 'FPC';
-
- SetLength(FPMKUnitDeps,FPMKUnitDepDefaultCount);
- for i := 0 to FPMKUnitDepDefaultCount-1 do
- FPMKUnitDeps[i]:=FPMKUnitDepsDefaults[i];
-
- FFPpkg.InitializeCompilerOptions;
-
- FFPpkg.CompilerOptions.InitCompilerDefaults;
- FFPpkg.FpmakeCompilerOptions.InitCompilerDefaults;
- FFPpkg.CompilerOptions.CheckCompilerValues;
- FFPpkg.FpmakeCompilerOptions.CheckCompilerValues;
-
- FFPpkg.LoadLocalAvailableMirrors;
+ LoadFppkgConfiguration;
Caption := rsFreePascalPackageManagerForLazarus;
@@ -834,6 +824,37 @@ begin
CategoryCheckListBox.Checked[i] := True;
end;
+procedure TFppkgForm.LoadFppkgConfiguration;
+var
+ i: Integer;
+begin
+ FFPpkg.InitializeGlobalOptions('');
+
+ FFPpkg.Options.GlobalSection.Downloader := 'FPC';
+
+ SetLength(FPMKUnitDeps,FPMKUnitDepDefaultCount);
+ for i := 0 to FPMKUnitDepDefaultCount-1 do
+ FPMKUnitDeps[i]:=FPMKUnitDepsDefaults[i];
+
+ FFPpkg.InitializeCompilerOptions;
+
+ FFPpkg.CompilerOptions.CheckCompilerValues;
+ FFPpkg.FpmakeCompilerOptions.CheckCompilerValues;
+
+ FFPpkg.ScanPackages;
+
+ if not Assigned(FFPpkg.FindPackage('rtl', pkgpkInstalled)) then
+ begin
+ ShowMessage('Fppkg seems to be configured, but the RTL could not be found. Please fix the Fppkg-configuration with the wizard or manualy.');
+ if TInitializeOptionsForm.RecreateFppkgConfiguration then
+ begin
+ LoadFppkgConfiguration;
+ end;
+ end
+ else
+ FFPpkg.LoadLocalAvailableMirrors;
+end;
+
procedure TFppkgForm.RescanPackages;
begin
FFPpkg.ScanAvailablePackages;
diff --git a/components/fppkg/standalone/lazarusfppkg.lpi b/components/fppkg/standalone/lazarusfppkg.lpi
index cb89628af7..304c65903e 100644
--- a/components/fppkg/standalone/lazarusfppkg.lpi
+++ b/components/fppkg/standalone/lazarusfppkg.lpi
@@ -47,7 +47,7 @@
-
+
@@ -67,6 +67,13 @@
+
+
+
+
+
+
+
diff --git a/components/fppkg/standalone/lazarusfppkg.pas b/components/fppkg/standalone/lazarusfppkg.pas
index 99401492de..c3b173f317 100644
--- a/components/fppkg/standalone/lazarusfppkg.pas
+++ b/components/fppkg/standalone/lazarusfppkg.pas
@@ -11,7 +11,8 @@ uses
pkgDownload,
fppkg_lpk,
pkgfpmake,
- pkgfphttp;
+ pkgfphttp,
+ fppkg_initializeoptionsfrm;
{$R *.res}