{ /*************************************************************************** imexportcompilerOpts.pas ------------------------ ***************************************************************************/ *************************************************************************** * * * This source is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This code is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * A copy of the GNU General Public License is available on the World * * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also * * obtain it by writing to the Free Software Foundation, * * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * * * *************************************************************************** Author: Mattias Gaertner, Juha Manninen } unit ImExportCompilerOpts; {$mode objfpc}{$H+} interface uses SysUtils, // LCL LCLType, Forms, Controls, Dialogs, StdCtrls, Buttons, ExtCtrls, ButtonPanel, // LazUtils FileUtil, LazFileUtils, Laz2_XMLCfg, // IdeIntf IDEOptEditorIntf, IDEImagesIntf, InputHistory, // IdeConfig IDEProcs, LazarusIDEStrConsts, Project, CompilerOptions, RecentListProcs; type { TImExportCompOptsDlg } TImExportCompOptsDlg = class(TForm) ButtonBrowse: TButton; ButtonPanel1: TButtonPanel; ExportRadioGroup: TRadioGroup; FileLabel: TLabel; FileNameEdit: TComboBox; OpenDlg: TOpenDialog; SaveDlg: TSaveDialog; procedure ButtonBrowseClick(Sender: TObject); procedure FileNameEditChange(Sender: TObject); procedure ImExportCompOptsDlgCLOSE(Sender: TObject; var {%H-}CloseAction: TCloseAction); procedure ImExportCompOptsDlgCREATE(Sender: TObject); procedure OpenButtonCLICK(Sender: TObject); procedure SaveButtonCLICK(Sender: TObject); private FFilename: string; FParentDialog: TAbstractOptionsEditorDialog; FExport: boolean; procedure InitExport(AOptions: TBaseCompilerOptions); procedure InitImport; procedure LoadRecentList; //procedure SaveRecentList; procedure SetFilename(const AValue: string); procedure DoOpenFile(const AFilename: string); procedure DoSaveFile(const AFilename: string); public property Filename: string read FFilename write SetFilename; end; { TOptsImExport } TOptsImExport = class private fOptions: TBaseCompilerOptions; // TProjectCompilerOptions or TPkgCompilerOptions fImExportDlg: TImExportCompOptsDlg; fXMLConfig: TXMLConfig; function GetXMLPathForCompilerOptions: string; function OpenXML(const Filename: string): TModalResult; public function DoImport(const Filename: string): TModalResult; function DoExportOptions(const Filename: string): TModalResult; function DoExportBuildModes(const Filename: string): TModalResult; constructor Create(AOptions: TBaseCompilerOptions; aImExportDlg: TImExportCompOptsDlg); destructor Destroy; override; end; function ShowImportCompilerOptionsDialog(AOptions: TBaseCompilerOptions; aDialog: TAbstractOptionsEditorDialog): TModalResult; function ShowExportCompilerOptionsDialog(AOptions: TBaseCompilerOptions; aDialog: TAbstractOptionsEditorDialog): TModalResult; implementation {$R *.lfm} const DefaultCompilerOptPath = 'CompilerOptions/'; function ShowImportCompilerOptionsDialog(AOptions: TBaseCompilerOptions; aDialog: TAbstractOptionsEditorDialog): TModalResult; var ImExportCompOptsDlg: TImExportCompOptsDlg; Importer: TOptsImExport; begin ImExportCompOptsDlg := TImExportCompOptsDlg.Create(nil); try ImExportCompOptsDlg.FParentDialog := aDialog; ImExportCompOptsDlg.InitImport; Result := ImExportCompOptsDlg.ShowModal; if Result <> mrOk then Exit; Importer := TOptsImExport.Create(AOptions, ImExportCompOptsDlg); try Result := Importer.DoImport(ImExportCompOptsDlg.Filename); finally Importer.Free; end; finally ImExportCompOptsDlg.Free; end; end; function ShowExportCompilerOptionsDialog(AOptions: TBaseCompilerOptions; aDialog: TAbstractOptionsEditorDialog): TModalResult; var ImExportCompOptsDlg: TImExportCompOptsDlg; Exporter: TOptsImExport; begin ImExportCompOptsDlg := TImExportCompOptsDlg.Create(nil); try ImExportCompOptsDlg.FParentDialog := aDialog; ImExportCompOptsDlg.InitExport(AOptions); Result := ImExportCompOptsDlg.ShowModal; if Result <> mrOk then Exit; Exporter := TOptsImExport.Create(AOptions, ImExportCompOptsDlg); try case ImExportCompOptsDlg.ExportRadioGroup.ItemIndex of 0: Result := Exporter.DoExportOptions(ImExportCompOptsDlg.Filename); 1: Result := Exporter.DoExportBuildModes(ImExportCompOptsDlg.Filename); end; finally Exporter.Free; end; finally ImExportCompOptsDlg.Free; end; end; { TOptsImExport } constructor TOptsImExport.Create(AOptions: TBaseCompilerOptions; aImExportDlg: TImExportCompOptsDlg); begin inherited Create; fOptions := AOptions; fImExportDlg := aImExportDlg; end; destructor TOptsImExport.Destroy; begin fXMLConfig.Free; inherited Destroy; end; function TOptsImExport.OpenXML(const Filename: string): TModalResult; begin Result := mrOk; try fXMLConfig:=TXMLConfig.Create(Filename); except on E: Exception do begin Result:=MessageDlg(lisIECOErrorOpeningXml, Format(lisIECOErrorOpeningXmlFile, [Filename, LineEnding, E.Message]), mtError, [mbCancel], 0); end; end; end; function TOptsImExport.GetXMLPathForCompilerOptions: string; const OptPathSuffix = 'SearchPaths/CompilerPath/Value'; PkgCompilerOptPath = 'Package/CompilerOptions/'; PkgVersionPath = 'Package/Version'; var FileVersion: Integer; begin if fXMLConfig.GetValue(OptPathSuffix,'')<>'' then // old lpi file Result:='' else if fXMLConfig.GetValue(DefaultCompilerOptPath+OptPathSuffix,'')<>'' then // current lpi file Result:=DefaultCompilerOptPath else if fXMLConfig.GetValue(PkgCompilerOptPath+OptPathSuffix,'')<>'' then // current lpk file Result:=PkgCompilerOptPath else begin // default: depending on file type Result:=DefaultCompilerOptPath; if FilenameExtIs(fXMLConfig.Filename,'lpk',true) then begin try FileVersion:=fXMLConfig.GetValue(PkgVersionPath,2); except FileVersion:=2; // On error assume version 2. end; if FileVersion>=2 then Result:=PkgCompilerOptPath; // current lpk file end; end; end; function TOptsImExport.DoImport(const Filename: string): TModalResult; // Import options to project or package. Only projects support BuildModes. var CompOptPath: String; begin Result := OpenXML(Filename); if Result <> mrOK then Exit; CompOptPath := GetXMLPathForCompilerOptions; if Assigned(fXMLConfig.FindNode('BuildModes',False)) then begin // The import file has BuildModes. if fOptions is TProjectCompilerOptions then begin // Project options Project1.BuildModes.LoadProjOptsFromXMLConfig(fXMLConfig, ''); fImExportDlg.FParentDialog.UpdateBuildModeGUI; ShowMessageFmt(lisSuccessfullyImportedBuildModes, [Project1.BuildModes.Count, Filename]); end else begin // Package options ShowMessage(lisImportingBuildModesNotSupported); Result := mrAbort; end; end else if Assigned(fXMLConfig.FindNode(CompOptPath,False)) then begin fOptions.LoadFromXMLConfig(fXMLConfig, CompOptPath); ShowMessageFmt(lisSuccessfullyImportedCompilerOptions, [Filename]); end else ShowMessageFmt(lisIECONoCompilerOptionsInFile, [Filename]); end; function TOptsImExport.DoExportOptions(const Filename: string): TModalResult; // Export options of project or package. begin Result := OpenXML(Filename); if Result <> mrOK then Exit; fOptions.SaveToXMLConfig(fXMLConfig, DefaultCompilerOptPath); fXMLConfig.Flush; ShowMessageFmt(lisSuccessfullyExportedCompilerOptions, [Filename]); end; function TOptsImExport.DoExportBuildModes(const Filename: string): TModalResult; // Export options of project's BuildModes. Packages don't have BuildModes. begin Result := OpenXML(Filename); if Result <> mrOK then Exit; Project1.BuildModes.SaveProjOptsToXMLConfig(fXMLConfig, '', False, True); fXMLConfig.Flush; ShowMessageFmt(lisSuccessfullyExportedBuildModes, [Project1.BuildModes.Count, Filename]); end; { TImExportCompOptsDlg } procedure TImExportCompOptsDlg.InitImport; begin FExport:=false; Caption:=lisIECOImportCompilerOptions; // ToDo: Later when the XML file is selected, ExportRadioGroup can be made // Visible but disabled. Then ItemIndex must be set according to file contents. // If file contains one mode -> ItemIndex:=0. If more modes -> ItemIndex:=1. ExportRadioGroup.Visible:=False; OpenDlg.Filter:=Format('%s|*.xml|' +'%s|*.lpi|' +'%s|*.lpk|' +'%s|*.lps|' +'%s|%s', [dlgFilterXML, dlgFilterLazarusProject, dlgFilterLazarusPackage, dlgFilterLazarusSession, dlgFilterAll, GetAllFilesMask]); with ButtonPanel1 do begin OKButton.Caption:=lisIECOLoadFromFile; IDEImages.AssignImage(OKButton, 'laz_open'); OKButton.Enabled:=False; OKButton.OnClick:=@OpenButtonCLICK; end; end; procedure TImExportCompOptsDlg.InitExport(AOptions: TBaseCompilerOptions); begin FExport:=true; Caption:=lisIECOExportCompilerOptions; SaveDlg.Filter:=Format('%s|*.xml|%s|%s', [dlgFilterXML, dlgFilterAll, GetAllFilesMask]); if not (AOptions is TProjectCompilerOptions) then ExportRadioGroup.Visible:=False else if Project1.BuildModes.Count <= 1 then ExportRadioGroup.Enabled:=False; with ButtonPanel1 do begin OKButton.Caption:=lisIECOSaveToFile; IDEImages.AssignImage(OKButton, 'laz_save'); OKButton.Enabled:=False; OKButton.OnClick:=@SaveButtonCLICK; end; end; procedure TImExportCompOptsDlg.ImExportCompOptsDlgCREATE(Sender: TObject); begin FileLabel.Caption:=lisFile; ExportRadioGroup.Caption:=lisIECOCompilerOptionsOf; ExportRadioGroup.Items.Strings[0]:=lisIECOCurrentBuildMode; ExportRadioGroup.Items.Strings[1]:=lisIECOAllBuildModes; LoadRecentList; end; procedure TImExportCompOptsDlg.ButtonBrowseClick(Sender: TObject); var Dlg: TFileDialog; begin if FExport then Dlg:= SaveDlg else Dlg:= OpenDlg; with Dlg do begin FileName := ''; if Execute then begin FileNameEdit.Text := FileName; FileNameEditChange(nil); end; end; end; procedure TImExportCompOptsDlg.FileNameEditChange(Sender: TObject); begin if FExport then ButtonPanel1.OKButton.Enabled := FileNameEdit.Text <> '' else ButtonPanel1.OKButton.Enabled := FileExistsUTF8(FileNameEdit.Text); end; procedure TImExportCompOptsDlg.OpenButtonCLICK(Sender: TObject); begin DoOpenFile(CleanAndExpandFilename(FileNameEdit.Text)); end; procedure TImExportCompOptsDlg.SaveButtonCLICK(Sender: TObject); begin DoSaveFile(CleanAndExpandFilename(FileNameEdit.Text)); end; procedure TImExportCompOptsDlg.ImExportCompOptsDlgCLOSE(Sender: TObject; var CloseAction: TCloseAction); begin //SaveRecentList; end; procedure TImExportCompOptsDlg.LoadRecentList; begin FileNameEdit.Items.Assign( InputHistories.HistoryLists.GetList(hlCompilerOptsImExport,true,rltFile)); end; { procedure TImExportCompOptsDlg.SaveRecentList; begin InputHistories.HistoryLists.GetList(hlCompilerOptsImExport,true,rltFile).Assign( FileNameEdit.Items); InputHistories.Save; end; } procedure TImExportCompOptsDlg.SetFilename(const AValue: string); begin if FFilename=AValue then exit; FFilename:=AValue; InputHistories.HistoryLists.GetList(hlCompilerOptsImExport,true,rltFile).AppendEntry(FFilename); LoadRecentList; end; procedure TImExportCompOptsDlg.DoOpenFile(const AFilename: string); begin if DirPathExists(AFilename) then exit; Filename := AFilename; ModalResult := mrOk; end; procedure TImExportCompOptsDlg.DoSaveFile(const AFilename: string); var MsgResult: TModalResult; begin if DirPathExists(AFilename) then exit; if ExtractFileExt(AFilename) = '' then Filename:=AFilename + '.xml' else Filename:=AFilename; if FileExistsUTF8(Filename) then begin MsgResult:=MessageDlg(lisIECOExportFileExists, Format(lisIECOExportFileExistsOpenFileAndReplaceOnlyCompilerOpti, [Filename, LineEnding, LineEnding]), mtConfirmation,[mbYes,mbCancel],0); if MsgResult<>mrYes then exit; end; ModalResult := mrOk; end; end.