From cc3dd4cfbf1590a3c7ae349b7d369226f93a1e86 Mon Sep 17 00:00:00 2001 From: juha Date: Mon, 27 Aug 2018 19:03:16 +0000 Subject: [PATCH] IDE: Simplify and improve the Publish Project / Package feature. Issue #34102. git-svn-id: trunk@58785 - --- ide/buildmanager.pas | 22 +- ide/inputhistory.pas | 2 +- ide/lazarusidestrconsts.pas | 58 ++-- ide/main.pp | 15 +- ide/mainintf.pas | 6 +- ide/projectdefs.pas | 93 ++---- ide/publishmodule.pas | 176 ++++++----- ide/publishprojectdlg.lfm | 371 +++++++++++------------ ide/publishprojectdlg.pas | 576 +++++++++++++++++++++++++----------- ide/sourcefilemanager.pas | 167 +---------- packager/packagedefs.pas | 16 +- packager/pkgmanager.pas | 22 +- 12 files changed, 746 insertions(+), 778 deletions(-) diff --git a/ide/buildmanager.pas b/ide/buildmanager.pas index 5f943ceef4..30a09b029b 100644 --- a/ide/buildmanager.pas +++ b/ide/buildmanager.pas @@ -50,7 +50,7 @@ uses // IDE IDECmdLine, LazarusIDEStrConsts, DialogProcs, IDEProcs, InputHistory, EditDefineTree, ProjectResources, MiscOptions, LazConf, - EnvironmentOpts, TransferMacros, CompilerOptions, + EnvironmentOpts, TransferMacros, CompilerOptions, PublishModule, ExtTools, etMakeMsgParser, etFPCMsgParser, etPas2jsMsgParser, Compiler, FPCSrcScan, PackageDefs, PackageSystem, Project, ProjectIcon, ModeMatrixOpts, BaseBuildManager, ApplicationBundle, RunParamsOpts; @@ -198,7 +198,6 @@ type function GetCompilerFilename: string; override; function GetFPCompilerFilename: string; override; function GetFPCFrontEndOptions: string; override; - function GetProjectPublishDir: string; override; function GetProjectTargetFilename(aProject: TProject): string; override; function GetProjectUsesAppBundle: Boolean; override; function GetTestUnitFilename(AnUnitInfo: TUnitInfo): string; override; @@ -698,23 +697,6 @@ begin Result:=UTF8Trim(Result); end; -function TBuildManager.GetProjectPublishDir: string; -begin - Result:=''; - if Project1=nil then - exit; - Result:=Project1.PublishOptions.DestinationDirectory; - if GlobalMacroList.SubstituteStr(Result) then begin - if FilenameIsAbsolute(Result) then begin - Result:=AppendPathDelim(TrimFilename(Result)); - end else begin - Result:=''; - end; - end else begin - Result:=''; - end; -end; - function TBuildManager.GetProjectTargetFilename(aProject: TProject): string; var AMode: TRunParamsOptionsMode; @@ -2239,7 +2221,7 @@ function TBuildManager.MacroFuncProjPublishDir(const Param: string; const Data: PtrInt; var Abort: boolean): string; begin if Project1<>nil then - Result:=GetProjectPublishDir + Result:=RealPublishDir(Project1.PublishOptions) else Result:=''; end; diff --git a/ide/inputhistory.pas b/ide/inputhistory.pas index 6c9259396a..6977ef3087 100644 --- a/ide/inputhistory.pas +++ b/ide/inputhistory.pas @@ -56,7 +56,7 @@ uses const // these are the names of the various history lists in the IDE: hlPublishProjectDestDirs = 'PublishProjectDestinationDirectories'; - hlPublishProjectCommandsAfter = 'PublishProjectCommmandsAfter'; + //hlPublishProjectCommandsAfter = 'PublishProjectCommmandsAfter'; hlPublishProjectIncludeFileFilter = 'PublishProjectIncludeFileFilter'; hlPublishProjectExcludeFileFilter = 'PublishProjectExcludeFileFilter'; hlMakeResourceStringSections = 'MakeResourceStringSections'; diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 63c6d5a668..4e03c5361d 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -139,6 +139,8 @@ resourcestring lisExportSub = 'Export >>'; lisImport = 'Import'; lisDlgImport = 'Import ...'; + lisSuccess = 'Success'; + lisAborted = 'Aborted'; // *** Common sentence resources that can be safely shared around Lazarus *** // Be careful, sharing sentences can lead to wrong translations in some places. @@ -867,10 +869,8 @@ resourcestring lisSourceAndDestinationAreTheSame = 'Source and Destination are the same:%s%s'; lisInvalidCommand = 'Invalid command'; lisTheCommandAfterIsNotExecutable = 'The command after "%s" is not executable.'; - lisUnableToCleanUpDestinationDirectory = 'Unable to clean up destination directory'; lisCommandAfterInvalid = 'Command after invalid'; lisTheCommandAfterPublishingIsInvalid = 'The command after publishing is invalid:%s"%s"'; - lisUnableToCleanUpPleaseCheckPermissions = 'Unable to clean up "%s".%sPlease check permissions.'; lisCommandAfterPublishingModule = 'Command after publishing module'; lisUnableToAddToProjectBecauseThereIsAlreadyAUnitWith = 'Unable to add %s ' +'to project, because there is already a unit with the same name in the Project.'; @@ -1080,9 +1080,6 @@ resourcestring lisOpenPackageFile = 'Open Package File'; lisSaveSpace = 'Save '; lisSelectDFMFiles = 'Select Delphi form files (*.dfm)'; - lisChooseDirectory = 'Choose directory'; - lisDestinationDirectory = 'Destination directory'; - lisCommandAfter = 'Command after'; lisChooseLazarusSourceDirectory = 'Choose Lazarus Directory'; lisChooseCompilerExecutable = 'Choose compiler executable (%s)'; lisChooseFPCSourceDir = 'Choose FPC source directory'; @@ -1270,20 +1267,42 @@ resourcestring dlgFrmEditor = 'Form Editor'; dlgObjInsp = 'Object Inspector'; dlgEnvFiles = 'Files'; - lisIgnoreBinaries = 'Ignore binaries'; + + // Publish project / package + lisDestinationDirectory = 'Destination directory'; + lisChooseDirectory = 'Choose directory'; + //lisCommandAfter = 'Command after'; + lisCompress = 'Compress'; + lisCompressHint = 'The resulting directory will be compressed into a ZIP file.'; + lisPublishModuleNote = 'Files belonging to project / package will be included automatically.'; lisSimpleSyntax = 'Simple syntax'; lisNormallyTheFilterIsARegularExpressionInSimpleSynta = 'Normally the ' +'filter is a regular expression. In simple syntax a . is a normal ' +'character, a * stands for anything, a ? stands for any character, and ' +'comma and semicolon separates alternatives. For example: Simple ' +'syntax *.pas;*.pp corresponds to ^(.*\.pas|.*\.pp)$'; - lisUseExcludeFilter = 'Use exclude filter'; - lisExcludeFilter = 'Exclude filter'; - lisProjectInformation = 'Project information'; - lisSaveEditorInfoOfNonProjectFiles = 'Save editor info of non project files'; - lisSaveInfoOfClosedEditorFiles = 'Save info of closed editor files'; - lisUseIncludeFilter = 'Use include filter'; + //lisUseExcludeFilter = 'Use exclude filter'; + //lisProjectInformation = 'Project information'; + //lisSaveEditorInfoOfNonProjectFiles = 'Save editor info of non project files'; + //lisSaveInfoOfClosedEditorFiles = 'Save info of closed editor files'; + lisUseFiltersForExtraFiles = 'Use filters for extra files'; + //lisUseIncludeFilter = 'Use include filter'; lisIncludeFilter = 'Include filter'; + lisExcludeFilter = 'Exclude filter'; + lisInvalidPublishingDirectory = 'Invalid publishing Directory'; + lisSourceDirectoryAndDestinationDirectoryAreTheSameMa = 'Source directory "%s"' + +'%sand destination directory "%s"' + +'%sare the same. Maybe you misunderstand this feature.' + +'%sIt will clean/recreate the destination directory and copy the package/project into it.'; + lisClearDirectory = 'Clear Directory?'; + lisInOrderToCreateACleanCopyOfTheProjectPackageAllFil = 'In order to create ' + +'a clean copy of the project/package, all files in the following ' + +'directory will be deleted and all its content will be lost.' + +'%sDelete all files in "%s"?'; + lisUnableToCleanUpDestinationDirectory = 'Unable to clean up destination directory'; + lisUnableToCleanUpPleaseCheckPermissions = 'Unable to clean up "%s".%sPlease check permissions.'; + + // dlgEnvBckup = 'Backup'; dlgNaming = 'Naming'; lisInformation = 'Information'; @@ -3789,16 +3808,13 @@ resourcestring lisMakeResStrInsertContexttSensitive = 'Insert context sensitive'; lisMakeResStrSourcePreview = 'Source preview'; lisNoStringConstantFound = 'No string constant found'; - lisSuccess = 'Success'; lisFailedToResolveMacros = 'failed to resolve macros'; lisToolHasNoExecutable = 'tool "%s" has no executable'; lisCanNotFindExecutable = 'cannot find executable "%s"'; lisMissingExecutable = 'missing executable "%s"'; lisExecutableIsADirectory = 'executable "%s" is a directory'; - lisExecutableLacksThePermissionToRun = 'executable "%s" lacks the permission' - +' to run'; + lisExecutableLacksThePermissionToRun = 'executable "%s" lacks the permission to run'; lisParser = 'parser "%s": %s'; - lisAborted = 'Aborted'; lisInvalidMacrosIn = 'Invalid macros in "%s"'; lisAllBlocksLooksOk = 'All blocks look ok.'; lisTheApplicationBundleWasCreatedFor = 'The Application Bundle was created for "%s"'; @@ -5581,16 +5597,6 @@ resourcestring lisTheComponentCanNotBeDeletedBecauseItIsNotOwnedBy = 'The component %s can ' +'not be deleted, because it is not owned by %s.'; lisFilter3 = 'Filter: %s'; - lisInvalidPublishingDirectory = 'Invalid publishing Directory'; - lisSourceDirectoryAndDestinationDirectoryAreTheSameMa = 'Source directory "%s"' - +'%sand destination directory "%s"' - +'%sare the same. Maybe you misunderstand this feature.' - +'%sIt will clean/recreate the destination directory and copy the package/project into it.'; - lisClearDirectory = 'Clear Directory?'; - lisInOrderToCreateACleanCopyOfTheProjectPackageAllFil = 'In order to create ' - +'a clean copy of the project/package, all files in the following ' - +'directory will be deleted and all its content will be lost.' - +'%sDelete all files in "%s"?'; lisFileExtensionOfPrograms = 'File extension of programs'; lisEveryNThLineNumber = 'Every n-th line number'; lisShowOverviewGutter = 'Show overview gutter'; diff --git a/ide/main.pp b/ide/main.pp index f6b9b358a1..b5de0e335e 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -144,7 +144,7 @@ uses // rest of the ide Splash, IDEDefs, LazarusIDEStrConsts, LazConf, SearchResultView, CodeTemplatesDlg, CodeBrowser, FindUnitDlg, InspectChksumChangedDlg, - IdeOptionsDlg, EditDefineTree, PublishModule, EnvironmentOpts, TransferMacros, + IdeOptionsDlg, EditDefineTree, EnvironmentOpts, TransferMacros, KeyMapping, IDETranslations, IDEProcs, ExtToolDialog, ExtToolEditDlg, JumpHistoryView, DesktopManager, ExampleManager, BuildLazDialog, BuildProfileManager, BuildManager, CheckCompOptsForNewUnitDlg, @@ -878,8 +878,8 @@ type function FindSourceFile(const AFilename, BaseDirectory: string; Flags: TFindSourceFlags): string; override; function DoCheckFilesOnDisk(Instantaneous: boolean = false): TModalResult; override; - function DoPublishModule(Options: TPublishModuleOptions; - const SrcDirectory, DestDirectory: string): TModalResult; override; + //function DoPublishModule(Options: TPublishModuleOptions; + // const SrcDirectory, DestDirectory: string): TModalResult; override; procedure PrepareBuildTarget(Quiet: boolean; ScanFPCSrc: TScanModeFPCSources = smsfsBackground); override; procedure AbortBuild; override; @@ -6417,7 +6417,7 @@ begin // show the publish project dialog if ShowDialog then begin - Result:=ShowPublishProjectDialog(Project1.PublishOptions); + Result:=ShowPublishDialog(Project1.PublishOptions); Project1.Modified:=Project1.PublishOptions.Modified; if Result<>mrOk then exit; IncreaseCompilerParseStamp; @@ -6430,8 +6430,7 @@ begin // publish project //debugln('TMainIDE.DoPublishProject B'); - Result:=SourceFileMgr.PublishModule(Project1.PublishOptions, - Project1.Directory, MainBuildBoss.GetProjectPublishDir); + Result:=PublishAModule(Project1.PublishOptions); end; procedure TMainIDE.DoShowProjectInspector(State: TIWGetFormState); @@ -8352,13 +8351,13 @@ function TMainIDE.DoCheckFilesOnDisk(Instantaneous: boolean): TModalResult; begin Result:=SourceFileMgr.CheckFilesOnDisk(Instantaneous); end; - +{ function TMainIDE.DoPublishModule(Options: TPublishModuleOptions; const SrcDirectory, DestDirectory: string): TModalResult; begin Result:=SourceFileMgr.PublishModule(Options, SrcDirectory, DestDirectory); end; - +} procedure TMainIDE.PrepareBuildTarget(Quiet: boolean; ScanFPCSrc: TScanModeFPCSources); begin MainBuildBoss.SetBuildTargetProject1(Quiet,ScanFPCSrc); diff --git a/ide/mainintf.pas b/ide/mainintf.pas index 3d7769e722..f30687513d 100644 --- a/ide/mainintf.pas +++ b/ide/mainintf.pas @@ -154,9 +154,9 @@ type function DoExampleManager: TModalResult; virtual; abstract; function DoBuildLazarus(Flags: TBuildLazarusFlags): TModalResult; virtual; abstract; function DoSaveForBuild(AReason: TCompileReason): TModalResult; virtual; abstract; - function DoPublishModule(Options: TPublishModuleOptions; - const SrcDirectory, DestDirectory: string - ): TModalResult; virtual; abstract; + //function DoPublishModule(Options: TPublishModuleOptions; + // const SrcDirectory, DestDirectory: string + // ): TModalResult; virtual; abstract; function DoFixupComponentReferences(RootComponent: TComponent; OpenFlags: TOpenFlags): TModalResult; virtual; abstract; diff --git a/ide/projectdefs.pas b/ide/projectdefs.pas index 83f98f174a..9dc53a4e8f 100644 --- a/ide/projectdefs.pas +++ b/ide/projectdefs.pas @@ -287,25 +287,15 @@ type TPublishProjectOptions = class(TPublishModuleOptions) private - FSaveClosedEditorFilesInfo: boolean; - FSaveEditorInfoOfNonProjectFiles: boolean; - procedure SetSaveClosedEditorFilesInfo(const AValue: boolean); - procedure SetSaveEditorInfoOfNonProjectFiles(const AValue: boolean); + FBackupDir, FUnitOutputDir: String; // Backup and unit output directories. public - procedure LoadDefaults; override; - procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const APath: string; - AdjustPathDelims: boolean); override; - procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const APath: string; - UsePathDelim: TPathDelimSwitch); override; + function GetDefaultDestinationDir: string; override; + function FileCanBePublished(const AFilename: string): boolean; override; function WriteFlags: TProjectWriteFlags; + procedure InitValues(const ABackupDir, AUnitOutputDir: String); public - // project info - property SaveEditorInfoOfNonProjectFiles: boolean - read FSaveEditorInfoOfNonProjectFiles - write SetSaveEditorInfoOfNonProjectFiles; - property SaveClosedEditorFilesInfo: boolean - read FSaveClosedEditorFilesInfo - write SetSaveClosedEditorFilesInfo; + property BackupDir: String read FBackupDir; // write FBackupDir; + property UnitOutputDir: String read FUnitOutputDir; // write FUnitOutputDir; end; implementation @@ -752,66 +742,35 @@ end; { TPublishProjectOptions } -procedure TPublishProjectOptions.SetSaveClosedEditorFilesInfo( - const AValue: boolean); +function TPublishProjectOptions.GetDefaultDestinationDir: string; begin - if FSaveClosedEditorFilesInfo=AValue then exit; - FSaveClosedEditorFilesInfo:=AValue; + Result:='$(TestDir)/publishedproject/'; end; -procedure TPublishProjectOptions.SetSaveEditorInfoOfNonProjectFiles( - const AValue: boolean); +function TPublishProjectOptions.FileCanBePublished(const AFilename: string): boolean; begin - if FSaveEditorInfoOfNonProjectFiles=AValue then exit; - FSaveEditorInfoOfNonProjectFiles:=AValue; -end; - -procedure TPublishProjectOptions.LoadDefaults; -begin - inherited LoadDefaults; - DestinationDirectory:='$(TestDir)/publishedproject/'; - CommandAfter:=''; - UseIncludeFileFilter:=true; - IncludeFilterSimpleSyntax:=true; - IncludeFileFilter:=DefPublModIncFilter; - UseExcludeFileFilter:=false; - ExcludeFilterSimpleSyntax:=true; - ExcludeFileFilter:=DefPublModExcFilter; - SaveClosedEditorFilesInfo:=false; - SaveEditorInfoOfNonProjectFiles:=false; -end; - -procedure TPublishProjectOptions.LoadFromXMLConfig(XMLConfig: TXMLConfig; - const APath: string; AdjustPathDelims: boolean); -//var -// XMLVersion: integer; -begin - inherited LoadFromXMLConfig(XMLConfig,APath,AdjustPathDelims); - //XMLVersion:=XMLConfig.GetValue(APath+'Version/Value',0); - FSaveClosedEditorFilesInfo:=XMLConfig.GetValue( - APath+'SaveClosedEditorFilesInfo/Value',SaveClosedEditorFilesInfo); - FSaveEditorInfoOfNonProjectFiles:=XMLConfig.GetValue( - APath+'SaveEditorInfoOfNonProjectFiles/Value', - SaveEditorInfoOfNonProjectFiles); -end; - -procedure TPublishProjectOptions.SaveToXMLConfig(XMLConfig: TXMLConfig; - const APath: string; UsePathDelim: TPathDelimSwitch); -begin - inherited SaveToXMLConfig(XMLConfig,APath,UsePathDelim); - XMLConfig.SetDeleteValue(APath+'SaveClosedEditorFilesInfo/Value', - SaveClosedEditorFilesInfo,false); - XMLConfig.SetDeleteValue(APath+'SaveEditorInfoOfNonProjectFiles/Value', - SaveEditorInfoOfNonProjectFiles,false); + Result:=inherited FileCanBePublished(AFilename); + // ToDo: filter also based on FBackupDir and FUnitOutputDir end; function TPublishProjectOptions.WriteFlags: TProjectWriteFlags; begin Result:=[]; - if not SaveEditorInfoOfNonProjectFiles then - Include(Result,pwfSaveOnlyProjectUnits); - if not SaveClosedEditorFilesInfo then - Include(Result,pwfSkipClosedUnits); + Include(Result,pwfSaveOnlyProjectUnits); + Include(Result,pwfSkipClosedUnits); +end; + +procedure TPublishProjectOptions.InitValues(const ABackupDir, AUnitOutputDir: String); +var + P: Integer; +begin + FBackupDir := ABackupDir; + FUnitOutputDir := AUnitOutputDir; + P := Pos(DirectorySeparator, FUnitOutputDir); + if P > 0 then + FUnitOutputDir := Copy(FUnitOutputDir, 1, P - 1); + DebugLn(['TPublishProjectOptions.InitValues: BackupDir=', FBackupDir, + ', UnitOutputDir=', FUnitOutputDir, ', Raw UnitOutputDir=', AUnitOutputDir]); end; diff --git a/ide/publishmodule.pas b/ide/publishmodule.pas index 666abe06a5..aedb0830a8 100644 --- a/ide/publishmodule.pas +++ b/ide/publishmodule.pas @@ -25,7 +25,7 @@ * * *************************************************************************** - Author: Mattias Gaertner + Author: Mattias Gaertner, Juha Manninen } unit PublishModule; @@ -37,20 +37,23 @@ interface uses Classes, SysUtils, RegExpr, // LazUtils - LazFileUtils, Laz2_XMLCfg, LazLoggerBase, LazTracer, LazStringUtils; + LazFileUtils, LazLoggerBase, LazTracer, LazStringUtils, Laz2_XMLCfg, UITypes, + // IdeIntf + MacroIntf, IDEDialogs, + // IDE + IDEProcs, LazarusIDEStrConsts; type { TPublishModuleOptions } TPublishModuleOptions = class private - FCommandAfter: string; + FCompressFinally: boolean; FDestinationDirectory: string; FExcludeFileFilter: string; FExcludeFilterRegExpr: TRegExpr; FExcludeFilterSimpleSyntax: boolean; FExcludeFilterValid: boolean; - FIgnoreBinaries: boolean; FIncludeFileFilter: string; FIncludeFilterRegExpr: TRegExpr; FIncludeFilterSimpleSyntax: boolean; @@ -58,18 +61,15 @@ type FModified: boolean; FModifiedLock: integer; FOwner: TObject; - FUseExcludeFileFilter: boolean; - FUseIncludeFileFilter: boolean; - procedure SetCommandAfter(const AValue: string); + FUseFileFilters: boolean; + procedure SetCompressFinally(const AValue: boolean); procedure SetDestinationDirectory(const AValue: string); procedure SetExcludeFileFilter(const AValue: string); procedure SetExcludeFilterSimpleSyntax(const AValue: boolean); - procedure SetIgnoreBinaries(const AValue: boolean); procedure SetIncludeFileFilter(const AValue: string); procedure SetIncludeFilterSimpleSyntax(const AValue: boolean); procedure SetModified(const AValue: boolean); - procedure SetUseExcludeFileFilter(const AValue: boolean); - procedure SetUseIncludeFileFilter(const AValue: boolean); + procedure SetUseFileFilters(const AValue: boolean); procedure UpdateIncludeFilter; procedure UpdateExcludeFilter; protected @@ -86,7 +86,7 @@ type function FileCanBePublished(const AFilename: string): boolean; virtual; procedure LockModified; procedure UnlockModified; - function GetDefaultDestinationDir: string; virtual; + function GetDefaultDestinationDir: string; virtual; abstract; public property Owner: TObject read FOwner; property Modified: boolean read FModified write SetModified; @@ -94,19 +94,15 @@ type // destination property DestinationDirectory: string read FDestinationDirectory write SetDestinationDirectory; - property CommandAfter: string read FCommandAfter write SetCommandAfter; - - // file filter - property IgnoreBinaries: boolean read FIgnoreBinaries write SetIgnoreBinaries; - property UseIncludeFileFilter: boolean - read FUseIncludeFileFilter write SetUseIncludeFileFilter; + property CompressFinally: boolean read FCompressFinally write SetCompressFinally; + property UseFileFilters: boolean read FUseFileFilters write SetUseFileFilters; + // Include Filter property IncludeFilterSimpleSyntax: boolean read FIncludeFilterSimpleSyntax write SetIncludeFilterSimpleSyntax; property IncludeFileFilter: string read FIncludeFileFilter write SetIncludeFileFilter; property IncludeFilterValid: boolean read FIncludeFilterValid; - property UseExcludeFileFilter: boolean - read FUseExcludeFileFilter write SetUseExcludeFileFilter; + // Exclude Filter property ExcludeFilterSimpleSyntax: boolean read FExcludeFilterSimpleSyntax write SetExcludeFilterSimpleSyntax; property ExcludeFileFilter: string @@ -119,16 +115,32 @@ const DefPublModIncFilter = '*.(pas|pp|inc|lpr|lfm|lrs|lpi|lpk|xml|sh)'; DefPublModExcFilter = '*.(bak|ppu|ppl|a|o|so);*~;backup'; - DefPublishDirectory = '$(TestDir)/publishedproject/'; + +function RealPublishDir(AOptions: TPublishModuleOptions): string; + implementation +function RealPublishDir(AOptions: TPublishModuleOptions): string; +begin + Result:=AOptions.DestinationDirectory; + if IDEMacros.SubstituteMacros(Result) then begin + if FilenameIsAbsolute(Result) then begin + Result:=AppendPathDelim(TrimFilename(Result)); + end else begin + Result:=''; + end; + end else begin + Result:=''; + end; +end; + { TPublishModuleOptions } -procedure TPublishModuleOptions.SetCommandAfter(const AValue: string); +procedure TPublishModuleOptions.SetCompressFinally(const AValue: boolean); begin - if FCommandAfter=AValue then exit; - FCommandAfter:=AValue; + if FCompressFinally=AValue then exit; + FCompressFinally:=AValue; Modified:=true; end; @@ -147,8 +159,7 @@ begin Modified:=true; end; -procedure TPublishModuleOptions.SetExcludeFilterSimpleSyntax( - const AValue: boolean); +procedure TPublishModuleOptions.SetExcludeFilterSimpleSyntax(const AValue: boolean); begin if FExcludeFilterSimpleSyntax=AValue then exit; FExcludeFilterSimpleSyntax:=AValue; @@ -156,13 +167,6 @@ begin Modified:=true; end; -procedure TPublishModuleOptions.SetIgnoreBinaries(const AValue: boolean); -begin - if FIgnoreBinaries=AValue then exit; - FIgnoreBinaries:=AValue; - Modified:=true; -end; - procedure TPublishModuleOptions.SetIncludeFileFilter(const AValue: string); begin if FIncludeFileFilter=AValue then exit; @@ -171,8 +175,7 @@ begin Modified:=true; end; -procedure TPublishModuleOptions.SetIncludeFilterSimpleSyntax( - const AValue: boolean); +procedure TPublishModuleOptions.SetIncludeFilterSimpleSyntax(const AValue: boolean); begin if FIncludeFilterSimpleSyntax=AValue then exit; FIncludeFilterSimpleSyntax:=AValue; @@ -188,17 +191,10 @@ begin DoOnModifyChange; end; -procedure TPublishModuleOptions.SetUseExcludeFileFilter(const AValue: boolean); +procedure TPublishModuleOptions.SetUseFileFilters(const AValue: boolean); begin - if FUseExcludeFileFilter=AValue then exit; - FUseExcludeFileFilter:=AValue; - Modified:=true; -end; - -procedure TPublishModuleOptions.SetUseIncludeFileFilter(const AValue: boolean); -begin - if FUseIncludeFileFilter=AValue then exit; - FUseIncludeFileFilter:=AValue; + if FUseFileFilters=AValue then exit; + FUseFileFilters:=AValue; Modified:=true; end; @@ -271,12 +267,10 @@ end; procedure TPublishModuleOptions.LoadDefaults; begin DestinationDirectory:=GetDefaultDestinationDir; - CommandAfter:=''; - IgnoreBinaries:=true; - UseIncludeFileFilter:=true; + CompressFinally:=true; + UseFileFilters:=true; IncludeFilterSimpleSyntax:=true; IncludeFileFilter:=DefPublModIncFilter; - UseExcludeFileFilter:=false; ExcludeFilterSimpleSyntax:=true; ExcludeFileFilter:=DefPublModExcFilter; end; @@ -294,24 +288,17 @@ var begin XMLVersion:=XMLConfig.GetValue(APath+'Version/Value',0); FDestinationDirectory:=f(XMLConfig.GetValue(APath+'DestinationDirectory/Value', - GetDefaultDestinationDir)); - FCommandAfter:=f(XMLConfig.GetValue(APath+'CommandAfter/Value','')); - IgnoreBinaries:=XMLConfig.GetValue(APath+'IgnoreBinaries/Value',true); - UseIncludeFileFilter:=XMLConfig.GetValue(APath+'UseIncludeFileFilter/Value', - true); - IncludeFilterSimpleSyntax:= - XMLConfig.GetValue(APath+'IncludeFilterSimpleSyntax/Value',true); - if XMLVersion>=2 then + GetDefaultDestinationDir)); + CompressFinally:=XMLConfig.GetValue(APath+'CompressFinally/Value',true); + UseFileFilters:=XMLConfig.GetValue(APath+'UseFileFilters/Value',false); + IncludeFilterSimpleSyntax:=XMLConfig.GetValue(APath+'IncludeFilterSimpleSyntax/Value',true); + ExcludeFilterSimpleSyntax:=XMLConfig.GetValue(APath+'ExcludeFilterSimpleSyntax/Value',true); + if XMLVersion>=2 then begin IncludeFileFilter:=XMLConfig.GetValue(APath+'IncludeFileFilter/Value', DefPublModIncFilter); - UseExcludeFileFilter:=XMLConfig.GetValue(APath+'UseExcludeFileFilter/Value', - false); - ExcludeFilterSimpleSyntax:= - XMLConfig.GetValue(APath+'ExcludeFilterSimpleSyntax/Value', - true); - if XMLVersion>=2 then ExcludeFileFilter:=XMLConfig.GetValue(APath+'ExcludeFileFilter/Value', DefPublModExcFilter); + end; end; procedure TPublishModuleOptions.SaveToXMLConfig(XMLConfig: TXMLConfig; @@ -327,43 +314,32 @@ begin XMLConfig.SetDeleteValue(APath+'DestinationDirectory/Value', f(DestinationDirectory), f(GetDefaultDestinationDir)); - XMLConfig.SetDeleteValue(APath+'CommandAfter/Value',f(CommandAfter),''); - XMLConfig.SetDeleteValue(APath+'IgnoreBinaries/Value',IgnoreBinaries,true); - XMLConfig.SetDeleteValue(APath+'UseIncludeFileFilter/Value', - UseIncludeFileFilter,true); + XMLConfig.SetDeleteValue(APath+'CompressFinally/Value',CompressFinally,true); + XMLConfig.SetDeleteValue(APath+'UseFileFilters/Value',UseFileFilters,false); XMLConfig.SetDeleteValue(APath+'IncludeFilterSimpleSyntax/Value', - IncludeFilterSimpleSyntax,true); - XMLConfig.SetDeleteValue(APath+'IncludeFileFilter/Value', - IncludeFileFilter,DefPublModIncFilter); - XMLConfig.SetDeleteValue(APath+'UseExcludeFileFilter/Value', - UseExcludeFileFilter,false); + IncludeFilterSimpleSyntax,true); + XMLConfig.SetDeleteValue(APath+'IncludeFileFilter/Value',IncludeFileFilter, + DefPublModIncFilter); XMLConfig.SetDeleteValue(APath+'ExcludeFilterSimpleSyntax/Value', - ExcludeFilterSimpleSyntax,true); - XMLConfig.SetDeleteValue(APath+'ExcludeFileFilter/Value', - ExcludeFileFilter,DefPublModExcFilter); + ExcludeFilterSimpleSyntax,true); + XMLConfig.SetDeleteValue(APath+'ExcludeFileFilter/Value',ExcludeFileFilter, + DefPublModExcFilter); end; -function TPublishModuleOptions.FileCanBePublished( - const AFilename: string): boolean; +function TPublishModuleOptions.FileCanBePublished(const AFilename: string): boolean; begin Result:=false; - // check include filter - if UseIncludeFileFilter - and (FIncludeFilterRegExpr<>nil) + if (FIncludeFilterRegExpr<>nil) and (not FIncludeFilterRegExpr.Exec(ExtractFilename(AFilename))) then exit; - // check exclude filter - if UseExcludeFileFilter - and (FExcludeFilterRegExpr<>nil) + if (FExcludeFilterRegExpr<>nil) and (FExcludeFilterRegExpr.Exec(ExtractFilename(AFilename))) then exit; - // check binaries - if IgnoreBinaries and (not DirPathExists(AFilename)) - and (not FileIsText(AFilename)) then exit; - + //if IgnoreBinaries and (not DirPathExists(AFilename)) + //and (not FileIsText(AFilename)) then exit; Result:=true; end; @@ -378,11 +354,33 @@ begin RaiseGDBException('TPublishModuleOptions.UnlockModified'); dec(FModifiedLock); end; - -function TPublishModuleOptions.GetDefaultDestinationDir: string; +{ +procedure TPublishModuleOptions.OnCopyFile(const Filename: string; var Copy: boolean; Data: TObject); begin - Result:=DefPublishDirectory; + //if Data=nil then exit; + Assert(Data is TPublishModuleOptions, 'TPublishModuleOptions.OnCopyFile: Data type is wrong.'); + Copy:=TPublishModuleOptions(Data).FileCanBePublished(Filename); + //debugln('TLazSourceFileManager.OnCopyFile "',Filename,'" ',Copy); end; +procedure TPublishModuleOptions.OnCopyError(const ErrorData: TCopyErrorData; + var Handled: boolean; Data: TObject); +begin + case ErrorData.Error of + ceSrcDirDoesNotExists: + IDEMessageDialog(lisCopyError2, + Format(lisSourceDirectoryDoesNotExist, [ErrorData.Param1]), + mtError,[mbCancel]); + ceCreatingDirectory: + IDEMessageDialog(lisCopyError2, + Format(lisUnableToCreateDirectory, [ErrorData.Param1]), + mtError,[mbCancel]); + ceCopyFileError: + IDEMessageDialog(lisCopyError2, + Format(lisUnableToCopyFileTo, [ErrorData.Param1, LineEnding, ErrorData.Param1]), + mtError,[mbCancel]); + end; +end; +} end. diff --git a/ide/publishprojectdlg.lfm b/ide/publishprojectdlg.lfm index 2d7d496790..30f4929edb 100644 --- a/ide/publishprojectdlg.lfm +++ b/ide/publishprojectdlg.lfm @@ -1,51 +1,37 @@ object PublishProjectDialog: TPublishProjectDialog - Left = 371 - Height = 476 - Top = 171 - Width = 498 + Left = 391 + Height = 442 + Top = 56 + Width = 642 BorderIcons = [biSystemMenu] Caption = 'Publish Project' - ClientHeight = 476 - ClientWidth = 498 + ClientHeight = 442 + ClientWidth = 642 OnClose = FormClose OnCreate = FormCreate Position = poScreenCenter LCLVersion = '1.9.0.0' object DestDirGroupBox: TGroupBox Left = 6 - Height = 99 + Height = 66 Top = 6 - Width = 486 - Align = alTop - AutoSize = True + Width = 630 + Anchors = [akTop, akLeft, akRight] BorderSpacing.Around = 6 Caption = 'Destination directory' ChildSizing.LeftRightSpacing = 6 ChildSizing.TopBottomSpacing = 6 - ClientHeight = 79 - ClientWidth = 482 + ClientHeight = 46 + ClientWidth = 628 TabOrder = 0 - OnResize = DestDirGroupBoxRESIZE - object CommandAfterLabel: TLabel - AnchorSideTop.Control = DestDirComboBox - AnchorSideTop.Side = asrBottom - Left = 6 - Height = 15 - Top = 35 - Width = 456 - Anchors = [akTop, akLeft, akRight] - BorderSpacing.Top = 6 - Caption = 'Command after:' - ParentColor = False - end object DestDirComboBox: TComboBox AnchorSideRight.Control = BrowseDestDirBitBtn Left = 6 - Height = 23 + Height = 31 Top = 6 - Width = 445 + Width = 591 Anchors = [akTop, akLeft, akRight] - ItemHeight = 15 + ItemHeight = 0 TabOrder = 0 Text = 'DestDirComboBox' end @@ -54,8 +40,8 @@ object PublishProjectDialog: TPublishProjectDialog AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = DestDirComboBox AnchorSideBottom.Side = asrBottom - Left = 451 - Height = 23 + Left = 597 + Height = 31 Top = 6 Width = 25 Anchors = [akTop, akRight, akBottom] @@ -64,196 +50,51 @@ object PublishProjectDialog: TPublishProjectDialog OnClick = BrowseDestDirBitBtnCLICK TabOrder = 1 end - object CommandAfterCombobox: TComboBox - AnchorSideTop.Control = CommandAfterLabel - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = DestDirGroupBox - AnchorSideRight.Side = asrBottom - Left = 6 - Height = 23 - Top = 50 - Width = 470 - Anchors = [akTop, akLeft, akRight] - ItemHeight = 15 - TabOrder = 2 - Text = 'CommandAfterCombobox' - end end - object FilesGroupbox: TGroupBox + object OptionsGroupbox: TGroupBox + AnchorSideTop.Control = FiltersPanel + AnchorSideTop.Side = asrBottom Left = 6 - Height = 51 - Top = 111 - Width = 486 - Align = alTop + Height = 53 + Top = 279 + Width = 628 + Anchors = [akTop, akLeft, akRight] AutoSize = True BorderSpacing.Around = 6 - Caption = 'Files' + Caption = 'Options' ChildSizing.TopBottomSpacing = 6 - ClientHeight = 31 - ClientWidth = 482 + ClientHeight = 33 + ClientWidth = 626 TabOrder = 1 - object IgnoreBinariesCheckbox: TCheckBox + object CompressCheckbox: TCheckBox AnchorSideRight.Side = asrBottom Left = 6 - Height = 19 + Height = 21 + Hint = 'Compress the whole directory into a ZIP file.' Top = 6 - Width = 98 + Width = 87 BorderSpacing.Around = 6 - Caption = 'Ignore binaries' - TabOrder = 0 - end - end - object ProjectInfoGroupbox: TGroupBox - Left = 6 - Height = 76 - Top = 328 - Width = 486 - Align = alTop - AutoSize = True - BorderSpacing.Around = 6 - Caption = 'Project Information' - ChildSizing.LeftRightSpacing = 6 - ChildSizing.TopBottomSpacing = 6 - ClientHeight = 56 - ClientWidth = 482 - TabOrder = 4 - object SaveClosedEditorFilesInfoCheckbox: TCheckBox - AnchorSideLeft.Control = ProjectInfoGroupbox - AnchorSideTop.Control = ProjectInfoGroupbox - Left = 6 - Height = 19 - Top = 6 - Width = 177 - BorderSpacing.Around = 6 - Caption = 'Save editor info of closed files' - TabOrder = 0 - end - object SaveEditorInfoOfNonProjectFilesCheckbox: TCheckBox - AnchorSideLeft.Control = ProjectInfoGroupbox - AnchorSideTop.Control = SaveClosedEditorFilesInfoCheckbox - AnchorSideTop.Side = asrBottom - Left = 6 - Height = 19 - Top = 31 - Width = 204 - BorderSpacing.Around = 6 - Caption = 'Save editor info of non project files' - TabOrder = 1 - end - end - object IncludeFilterGroupbox: TGroupBox - Left = 6 - Height = 74 - Top = 168 - Width = 486 - Align = alTop - AutoSize = True - BorderSpacing.Around = 6 - Caption = 'Include Filter' - ChildSizing.LeftRightSpacing = 6 - ChildSizing.TopBottomSpacing = 6 - ClientHeight = 54 - ClientWidth = 482 - TabOrder = 2 - TabStop = True - object UseIncludeFilterCheckbox: TCheckBox - AnchorSideTop.Control = IncludeFilterGroupbox - Left = 6 - Height = 19 - Top = 6 - Width = 110 - Caption = 'Use Include Filter' - TabOrder = 0 - end - object IncFilterSimpleSyntaxCheckbox: TCheckBox - AnchorSideLeft.Control = UseIncludeFilterCheckbox - AnchorSideLeft.Side = asrBottom - AnchorSideTop.Control = IncludeFilterGroupbox - Left = 128 - Height = 19 - Top = 6 - Width = 93 - BorderSpacing.Left = 12 - Caption = 'Simple Syntax' + Caption = 'Compress' ParentShowHint = False ShowHint = True - TabOrder = 1 - end - object IncludeFilterCombobox: TComboBox - AnchorSideLeft.Control = IncludeFilterGroupbox - AnchorSideTop.Control = UseIncludeFilterCheckbox - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = IncludeFilterGroupbox - AnchorSideRight.Side = asrBottom - Left = 6 - Height = 23 - Top = 25 - Width = 470 - Anchors = [akTop, akLeft, akRight] - ItemHeight = 15 - TabOrder = 2 - Text = 'IncludeFilterCombobox' - end - end - object ExcludeFilterGroupbox: TGroupBox - Left = 6 - Height = 74 - Top = 248 - Width = 486 - Align = alTop - AutoSize = True - BorderSpacing.Around = 6 - Caption = 'Exclude Filter' - ChildSizing.LeftRightSpacing = 6 - ChildSizing.TopBottomSpacing = 6 - ClientHeight = 54 - ClientWidth = 482 - TabOrder = 3 - TabStop = True - object UseExcludeFilterCheckbox: TCheckBox - AnchorSideTop.Control = ExcludeFilterGroupbox - Left = 6 - Height = 19 - Top = 6 - Width = 111 - Caption = 'Use Exclude Filter' TabOrder = 0 end - object ExcFilterSimpleSyntaxCheckbox: TCheckBox - AnchorSideLeft.Control = UseExcludeFilterCheckbox - AnchorSideLeft.Side = asrBottom - AnchorSideTop.Control = ExcludeFilterGroupbox - Left = 129 + object Label1: TLabel + Left = 168 Height = 19 - Top = 6 - Width = 93 - BorderSpacing.Left = 12 - Caption = 'Simple Syntax' - ParentShowHint = False - ShowHint = True - TabOrder = 1 - end - object ExcludeFilterCombobox: TComboBox - AnchorSideLeft.Control = ExcludeFilterGroupbox - AnchorSideTop.Control = UseExcludeFilterCheckbox - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = ExcludeFilterGroupbox - AnchorSideRight.Side = asrBottom - Left = 6 - Height = 23 - Top = 25 - Width = 470 - Anchors = [akTop, akLeft, akRight] - ItemHeight = 15 - TabOrder = 2 - Text = 'ExcludeFilterCombobox' + Top = 8 + Width = 138 + Caption = 'Not implemented yet.' + Font.Color = clRed + ParentColor = False + ParentFont = False end end object ButtonPanel1: TButtonPanel Left = 6 Height = 26 - Top = 444 - Width = 486 + Top = 410 + Width = 630 OKButton.Name = 'OKButton' OKButton.DefaultCaption = True HelpButton.Name = 'HelpButton' @@ -262,7 +103,135 @@ object PublishProjectDialog: TPublishProjectDialog CloseButton.DefaultCaption = True CancelButton.Name = 'CancelButton' CancelButton.DefaultCaption = True - TabOrder = 5 + TabOrder = 3 ShowBevel = False end + object UseFiltersCheckbox: TCheckBox + AnchorSideTop.Control = NoteLabel + AnchorSideTop.Side = asrBottom + Left = 6 + Height = 21 + Top = 103 + Width = 174 + BorderSpacing.Around = 6 + Caption = 'Use filters for extra files' + OnClick = UseFiltersCheckboxClick + TabOrder = 4 + end + object FiltersPanel: TPanel + AnchorSideLeft.Control = UseFiltersCheckbox + AnchorSideTop.Control = UseFiltersCheckbox + AnchorSideTop.Side = asrBottom + Left = 21 + Height = 143 + Top = 130 + Width = 615 + Anchors = [akTop, akLeft, akRight] + AutoSize = True + BorderSpacing.Left = 15 + ChildSizing.LeftRightSpacing = 6 + ChildSizing.TopBottomSpacing = 6 + ClientHeight = 143 + ClientWidth = 615 + TabOrder = 2 + TabStop = True + object IncFilterSimpleSyntaxCheckbox: TCheckBox + AnchorSideLeft.Control = IncludeFilterCombobox + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = IncludeFilterCombobox + AnchorSideTop.Side = asrCenter + Left = 462 + Height = 21 + Top = 37 + Width = 111 + BorderSpacing.Around = 6 + Caption = 'Simple Syntax' + ParentShowHint = False + ShowHint = True + TabOrder = 0 + end + object IncludeFilterCombobox: TComboBox + AnchorSideLeft.Control = IncludeFilterLabel + AnchorSideTop.Control = IncludeFilterLabel + AnchorSideTop.Side = asrBottom + AnchorSideRight.Side = asrBottom + Left = 7 + Height = 31 + Top = 32 + Width = 449 + Anchors = [akTop, akLeft, akRight] + AutoSize = False + ItemHeight = 0 + TabOrder = 1 + Text = 'IncludeFilterCombobox' + end + object IncludeFilterLabel: TLabel + AnchorSideLeft.Control = FiltersPanel + AnchorSideTop.Control = FiltersPanel + Left = 7 + Height = 19 + Top = 7 + Width = 112 + BorderSpacing.Around = 6 + Caption = 'IncludeFilterLabel' + ParentColor = False + end + object ExcludeFilterLabel: TLabel + AnchorSideLeft.Control = FiltersPanel + AnchorSideTop.Control = IncludeFilterCombobox + AnchorSideTop.Side = asrBottom + Left = 7 + Height = 19 + Top = 80 + Width = 113 + BorderSpacing.Top = 11 + BorderSpacing.Around = 6 + Caption = 'ExcludeFilterLabel' + ParentColor = False + end + object ExcludeFilterCombobox: TComboBox + AnchorSideLeft.Control = ExcludeFilterLabel + AnchorSideTop.Control = ExcludeFilterLabel + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = IncludeFilterCombobox + AnchorSideRight.Side = asrBottom + Left = 7 + Height = 31 + Top = 105 + Width = 449 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 0 + TabOrder = 2 + Text = 'ExcludeFilterCombobox' + end + object ExcFilterSimpleSyntaxCheckbox: TCheckBox + AnchorSideLeft.Control = ExcludeFilterCombobox + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = ExcludeFilterCombobox + AnchorSideTop.Side = asrCenter + Left = 462 + Height = 21 + Top = 110 + Width = 111 + BorderSpacing.Around = 6 + Caption = 'Simple Syntax' + ParentShowHint = False + ShowHint = True + TabOrder = 3 + end + end + object NoteLabel: TLabel + AnchorSideTop.Control = DestDirGroupBox + AnchorSideTop.Side = asrBottom + Left = 6 + Height = 19 + Top = 78 + Width = 391 + BorderSpacing.Around = 6 + Caption = 'Files belonging to project / package will be included automatically.' + Font.Color = clMaroon + Font.Style = [fsItalic] + ParentColor = False + ParentFont = False + end end diff --git a/ide/publishprojectdlg.pas b/ide/publishprojectdlg.pas index ca566cca09..04b8132dcb 100644 --- a/ide/publishprojectdlg.pas +++ b/ide/publishprojectdlg.pas @@ -23,7 +23,7 @@ * * *************************************************************************** - Author: Mattias Gaertner + Author: Juha Manninen Abstract: - TPublishProjectDialog @@ -37,12 +37,16 @@ unit PublishProjectDlg; interface uses - Classes, SysUtils, - LazFileUtils, Forms, Controls, Graphics, Buttons, - StdCtrls, Dialogs, LCLType, ExtCtrls, ButtonPanel, - IDEWindowIntf, IDEHelpIntf, IDEDialogs, IDEImagesIntf, - ProjectDefs, PackageDefs, PublishModule, IDEOptionDefs, InputHistory, - LazarusIDEStrConsts, IDEProcs; + Classes, SysUtils, StrUtils, + // LCL + LCLType, Forms, Controls, StdCtrls, Dialogs, ExtCtrls, Buttons, ButtonPanel, + // LazUtils + FileUtil, LazFileUtils, LazLoggerBase, + // IdeIntf + IDEWindowIntf, IDEHelpIntf, IDEDialogs, IDEImagesIntf, ProjPackIntf, CompOptsIntf, + // IDE + ProjectDefs, Project, PackageDefs, PublishModule, IDEOptionDefs, InputHistory, + LazarusIDEStrConsts, IDEProcs, EnvironmentOpts; type { TPublishProjectDialog } @@ -52,33 +56,25 @@ type DestDirGroupBox: TGroupBox; DestDirComboBox: TComboBox; BrowseDestDirBitBtn: TBitBtn; - CommandAfterLabel: TLabel; - CommandAfterCombobox: TComboBox; - - FilesGroupbox: TGroupBox; - IgnoreBinariesCheckbox: TCheckBox; - - IncludeFilterCombobox: TComboBox; - IncFilterSimpleSyntaxCheckbox: TCheckBox; - UseIncludeFilterCheckbox: TCheckBox; - IncludeFilterGroupbox: TGroupBox; - - ExcludeFilterCombobox: TComboBox; ExcFilterSimpleSyntaxCheckbox: TCheckBox; - UseExcludeFilterCheckbox: TCheckBox; - ExcludeFilterGroupbox: TGroupBox; - - ProjectInfoGroupbox: TGroupBox; - SaveEditorInfoOfNonProjectFilesCheckbox: TCheckBox; - SaveClosedEditorFilesInfoCheckbox: TCheckBox; - + ExcludeFilterCombobox: TComboBox; + ExcludeFilterLabel: TLabel; + FiltersPanel: TPanel; + IncFilterSimpleSyntaxCheckbox: TCheckBox; + IncludeFilterCombobox: TComboBox; + IncludeFilterLabel: TLabel; + Label1: TLabel; + NoteLabel: TLabel; + OptionsGroupbox: TGroupBox; + CompressCheckbox: TCheckBox; + UseFiltersCheckbox: TCheckBox; procedure BrowseDestDirBitBtnCLICK(Sender: TObject); - procedure DestDirGroupBoxRESIZE(Sender: TObject); procedure FormClose(Sender: TObject; var {%H-}CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); procedure HelpButtonClick(Sender: TObject); procedure OkButtonCLICK(Sender: TObject); procedure SaveSettingsButtonClick(Sender: TObject); + procedure UseFiltersCheckboxClick(Sender: TObject); private FOptions: TPublishModuleOptions; procedure SetComboBox(AComboBox: TComboBox; const NewText: string; @@ -95,38 +91,350 @@ type property Options: TPublishModuleOptions read FOptions write SetOptions; end; -function ShowPublishProjectDialog( - PublishOptions: TPublishModuleOptions): TModalResult; + { TPublisher } + + TPublisher = class(TFileSearcher) + private + FOptions: TPublishModuleOptions; + FProjPack: TIDEProjPackBase; + FSrcDir, FDestDir: string; + // TopDir contains all project/package directories. + // Some of them may be above the main project/package directory. + FTopDir: string; + // Project/package member files already copied. Not copied again by filters. + FCopiedFiles: TStringList; + // Copying by filters failed. + FCopyFailedCount: Integer; + procedure AdjustTopDir(const AFileName: string); + function CopyAFile(const AFileName: string): TModalResult; + function CopyProjectFiles: TModalResult; + function CopyPackageFiles: TModalResult; + function WriteProjectInfo: TModalResult; + function WritePackageInfo: TModalResult; + function Compress: TModalResult; + protected + procedure DoFileFound; override; // Called by TFileSearcher.Search. + procedure DoDirectoryFound; override; + public + constructor Create(AOptions: TPublishModuleOptions); + destructor Destroy; override; + function Run: TModalResult; + end; + + +function ShowPublishDialog(AOptions: TPublishModuleOptions): TModalResult; +function PublishAModule(AOptions: TPublishModuleOptions): TModalResult; implementation {$R *.lfm} -function ShowPublishProjectDialog( - PublishOptions: TPublishModuleOptions): TModalResult; +function ShowPublishDialog(AOptions: TPublishModuleOptions): TModalResult; var PublishProjectDialog: TPublishProjectDialog; begin PublishProjectDialog:=TPublishProjectDialog.Create(nil); - with PublishProjectDialog do begin - Options:=PublishOptions; + with PublishProjectDialog do + begin + Options:=AOptions; Result:=ShowModal; Free; end; end; +function PublishAModule(AOptions: TPublishModuleOptions): TModalResult; +begin + with TPublisher.Create(AOptions) do + try + Result := Run; + finally + Free; + end; +end; + +{ TPublisher } + +constructor TPublisher.Create(AOptions: TPublishModuleOptions); +begin + inherited Create; + FOptions := AOptions; + FProjPack := FOptions.Owner as TIDEProjPackBase; + FTopDir := FProjPack.Directory; // Initial value for TopDir. It may change. + FSrcDir := FTopDir; + FDestDir:=TrimAndExpandDirectory(RealPublishDir(FOptions)); + DebugLn(['TPublisher: Source Directory = ', FSrcDir]); + DebugLn(['TPublisher: Destination Directory = ', FDestDir]); + FCopiedFiles := TStringList.Create; +end; + +destructor TPublisher.Destroy; +begin + FCopiedFiles.Free; + inherited Destroy; +end; + +// The next 2 methods will be called from TFileSearcher.Search. + +procedure TPublisher.DoFileFound; +// Copy a found file if it passes the filter. +var + NewPath: string; +begin + if FCopiedFiles.IndexOf(FileName) >= 0 then + DebugLn(['DoFileFound: Already copied file ', FileName]) + else if FOptions.FileCanBePublished(FileName) then + begin + NewPath:=StringReplace(FileName, FSrcDir, FDestDir, []); + DebugLn(['DoFileFound: Copying file ', FileName, ' -> ', NewPath]); + if not CopyFile(FileName, NewPath, [cffCreateDestDirectory,cffPreserveTime]) then + Inc(FCopyFailedCount); + end + else begin + DebugLn(['DoFileFound: Rejected file ', FileName]); + end; +end; + +procedure TPublisher.DoDirectoryFound; +begin + DebugLn(['DoDirectoryFound: ', FileName]); + // Directory is already created by the cffCreateDestDirectory flag. +end; + +// Methods below are for copying project/package members. + +procedure TPublisher.AdjustTopDir(const AFileName: string); +// Adjust the actual top directory. It will differ from the +// main dir when project/package has files up in directory structure. +var + RelPath: string; + Adjusted: Boolean; +begin + RelPath := ExtractRelativePath(FTopDir, AFilename); + Adjusted := False; + while Copy(RelPath, 1, 3) = '../' do + begin + FTopDir := FTopDir + '../'; // This file is in upper dir. Move TopDir up, too. + Delete(RelPath, 1, 3); + Adjusted := True; + end; + if Adjusted then + begin + FTopDir := ResolveDots(FTopDir); + DebugLn(['Adjusted TopDir: ', FTopDir, ' based on file ', AFilename]); + end; +end; + +function TPublisher.CopyAFile(const AFileName: string): TModalResult; +var + RelPath, LfmFile: string; +begin + Result := mrOK; + if FCopiedFiles.IndexOf(AFilename) >= 0 then exit; // Already copied. + RelPath := ExtractRelativePath(FTopDir, AFilename); + DebugLn(['CopyAFile: File ', AFilename, ' -> ', FDestDir+RelPath]); + if CopyFile(AFilename, FDestDir+RelPath, + [cffCreateDestDirectory,cffPreserveTime]) then + begin + FCopiedFiles.Add(AFilename); + if FilenameIsPascalUnit(AFilename) then + begin // Copy .lfm file even if it is not part of project/package. + LfmFile := ChangeFileExt(AFilename, '.lfm'); + if FileExistsUTF8(LfmFile) then + Result := CopyAFile(LfmFile); // Recursive call. + end; + end + else + Result := mrCancel; +end; + +function TPublisher.CopyProjectFiles: TModalResult; +var + CurProject: TProject; + CurUnitInfo: TUnitInfo; + i: Integer; + ResFile: String; +begin + Result := mrOK; + CurProject := TProject(FProjPack); + // First adjust the TopDir based on relative file paths. + for i:=0 to CurProject.UnitCount-1 do + begin + CurUnitInfo := CurProject.Units[i]; + if CurUnitInfo.IsPartOfProject then + AdjustTopDir(CurUnitInfo.Filename); + end; + // Then copy the project files + for i:=0 to CurProject.UnitCount-1 do + begin + CurUnitInfo := CurProject.Units[i]; + if CurUnitInfo.IsPartOfProject then + begin + CopyAFile(CurUnitInfo.Filename); + if CurUnitInfo.IsMainUnit then + begin // Copy the main resource file in any case. + ResFile := ChangeFileExt(CurUnitInfo.Filename, '.res'); + if FileExistsUTF8(ResFile) then + Result := CopyAFile(ResFile); + end; + end; + end; +end; + +function TPublisher.CopyPackageFiles: TModalResult; +var + CurPackage: TLazPackage; + PkgFile: TPkgFile; + i: Integer; +begin + // Copy Package + Result := mrOK; + CurPackage := TLazPackage(FProjPack); + // First adjust the TopDir based on relative file paths. + for i:=0 to CurPackage.FileCount-1 do + begin + PkgFile := CurPackage.Files[i]; + AdjustTopDir(PkgFile.Filename); + end; + // Then copy the package files + for i:=0 to CurPackage.FileCount-1 do + begin + PkgFile := CurPackage.Files[i]; + CopyAFile(PkgFile.Filename); + end; +end; + +function TPublisher.WriteProjectInfo: TModalResult; +var + CurProject: TProject; + NewProjFilename: string; +begin + CurProject := TProject(FOptions.Owner); + NewProjFilename := FDestDir + ExtractRelativePath(FTopDir, CurProject.ProjectInfoFile); + DeleteFileUTF8(NewProjFilename); + DebugLn(['WriteProjectInfo: ProjectInfo = ', CurProject.ProjectInfoFile, + ', NewProjFilename = ', NewProjFilename]); + Assert(CurProject.PublishOptions = FOptions, 'CurProject.PublishOptions <> FOptions'); + FCopiedFiles.Add(CurProject.ProjectInfoFile); // Do not later by filter. + Result := CurProject.WriteProject( + CurProject.PublishOptions.WriteFlags+pwfSkipSessionInfo+[pwfIgnoreModified], + NewProjFilename,nil); + if Result<>mrOk then + DebugLn('Hint: [TPublisher] CurProject.WriteProject failed'); +end; + +function TPublisher.WritePackageInfo: TModalResult; +begin + Result := mrOK; + // ToDo +end; + +function TPublisher.Compress: TModalResult; +begin + Result := mrOK; + // ToDo +end; + +function TPublisher.Run: TModalResult; +begin + Result:=mrCancel; + + if FDestDir='' then begin + IDEMessageDialog('Invalid publishing Directory', + 'Destination directory for publishing is empty.',mtError, + [mbCancel]); + exit; + end; + // Don't try to copy to a subdirectory of FSrcDir. + if (CompareFilenames(FSrcDir,FDestDir)=0) + {$ifdef CaseInsensitiveFilenames} + or AnsiStartsText(FSrcDir, FDestDir) + {$ELSE} + or AnsiStartsStr(FSrcDir, FDestDir) + {$ENDIF} + then begin + IDEMessageDialog(lisInvalidPublishingDirectory, + Format(lisSourceDirectoryAndDestinationDirectoryAreTheSameMa, + [FSrcDir, LineEnding, FDestDir, LineEnding, LineEnding]), + mtError, [mbCancel]); + exit; + end; + + // checking "command after" was here + + // clear destination directory + if DirPathExists(FDestDir) then + begin + // ask user, if destination can be deleted + if IDEMessageDialog(lisClearDirectory, + Format(lisInOrderToCreateACleanCopyOfTheProjectPackageAllFil, + [LineEnding+LineEnding, FDestDir]), + mtConfirmation, [mbYes,mbNo])<>mrYes + then + exit; + + if (not DeleteDirectory(ChompPathDelim(FDestDir),true)) then + begin + IDEMessageDialog(lisUnableToCleanUpDestinationDirectory, + Format(lisUnableToCleanUpPleaseCheckPermissions, [FDestDir, LineEnding]), + mtError,[mbOk]); + exit; + end; + end; + + // Write a project/package files and then info file + if FOptions is TPublishProjectOptions then + begin + Result := CopyProjectFiles; + if Result<>mrOk then exit; + Result := WriteProjectInfo; + // Store project's BackupDir and UnitOutputDir for filtering files. + TPublishProjectOptions(FOptions).InitValues( + EnvironmentOptions.BackupInfoProjectFiles.SubDirectory, + TProject(FOptions.Owner).CompilerOptions.GetUnitOutPath(True,coptUnparsed) + ); + end + else begin + Result := CopyPackageFiles; + if Result<>mrOk then exit; + Result := WritePackageInfo; + end; + if Result<>mrOk then exit; + + // Copy extra files in project/package directory + if FOptions.UseFileFilters then + begin + FCopyFailedCount:=0; + Search(FSrcDir); // Copy only under project/package main dir (FSrcDir). + if FCopyFailedCount <> 0 then + begin + DebugLn('Hint: [TPublisher] Copying files failed'); + exit(mrCancel); + end; + end; + + // Compress the resulting project/package + if FOptions.CompressFinally then + Result := Compress; + + if Result = mrOK then + IDEMessageDialog(lisSuccess, 'Published to '+FDestDir, mtInformation,[mbOk]); +end; + { TPublishProjectDialog } -procedure TPublishProjectDialog.DestDirGroupBoxRESIZE(Sender: TObject); +constructor TPublishProjectDialog.Create(TheOwner: TComponent); begin - with DestDirComboBox do - SetBounds(Left,Top, - Parent.ClientWidth-2*Left-BrowseDestDirBitBtn.Width-5,Height); - with BrowseDestDirBitBtn do - Left:=DestDirComboBox.Left+DestDirComboBox.Width+5; - with CommandAfterCombobox do - SetBounds(Left,Top,Parent.ClientWidth-2*Left,Height); + inherited Create(TheOwner); + Position:=poScreenCenter; + IDEDialogLayoutList.ApplyLayout(Self, 600, 400); + LoadHistoryLists; +end; + +destructor TPublishProjectDialog.Destroy; +begin + SaveHistoryLists; + inherited Destroy; end; procedure TPublishProjectDialog.FormClose(Sender: TObject; var CloseAction: TCloseAction); @@ -134,45 +442,25 @@ begin IDEDialogLayoutList.SaveLayout(Self); end; -procedure TPublishProjectDialog.BrowseDestDirBitBtnCLICK(Sender: TObject); -var - SelectDirDialog: TSelectDirectoryDialog; - NewDir: String; -begin - SelectDirDialog:=TSelectDirectoryDialog.Create(Self); - InputHistories.ApplyFileDialogSettings(SelectDirDialog); - SelectDirDialog.Title:=lisChooseDirectory; - if SelectDirDialog.Execute then begin - NewDir:=ExpandFileNameUTF8(SelectDirDialog.Filename); - SeTComboBox(DestDirComboBox,NewDir,20); - end; - SelectDirDialog.Free; -end; - procedure TPublishProjectDialog.FormCreate(Sender: TObject); begin DestDirGroupBox.Caption:=lisDestinationDirectory; - CommandAfterLabel.Caption:=lisCommandAfter; - - FilesGroupbox.Caption:=dlgEnvFiles; - IgnoreBinariesCheckbox.Caption:=lisIgnoreBinaries; + NoteLabel.Caption:=lisPublishModuleNote; + UseFiltersCheckbox.Caption:=lisUseFiltersForExtraFiles; + IncludeFilterLabel.Caption:=lisIncludeFilter; IncFilterSimpleSyntaxCheckbox.Caption:=lisSimpleSyntax; IncFilterSimpleSyntaxCheckbox.Hint:= lisNormallyTheFilterIsARegularExpressionInSimpleSynta; - UseIncludeFilterCheckbox.Caption:=lisUseIncludeFilter; - IncludeFilterGroupbox.Caption:=lisIncludeFilter; + ExcludeFilterLabel.Caption:=lisExcludeFilter; ExcFilterSimpleSyntaxCheckbox.Caption:=lisSimpleSyntax; ExcFilterSimpleSyntaxCheckbox.Hint:= lisNormallyTheFilterIsARegularExpressionInSimpleSynta; - UseExcludeFilterCheckbox.Caption:=lisUseExcludeFilter; - ExcludeFilterGroupbox.Caption:=lisExcludeFilter; - ProjectInfoGroupbox.Caption:=lisProjectInformation; - SaveEditorInfoOfNonProjectFilesCheckbox.Caption:= - lisSaveEditorInfoOfNonProjectFiles; - SaveClosedEditorFilesInfoCheckbox.Caption:=lisSaveInfoOfClosedEditorFiles; + OptionsGroupbox.Caption:=lisOptions; + CompressCheckbox.Caption:=lisCompress; + CompressCheckbox.Hint:=lisCompressHint; ButtonPanel1.OkButton.Caption := lisMenuOk; ButtonPanel1.OKButton.OnClick := @OkButtonCLICK; @@ -188,6 +476,21 @@ begin ButtonPanel1.HelpButton.OnClick := @HelpButtonClick; end; +procedure TPublishProjectDialog.BrowseDestDirBitBtnCLICK(Sender: TObject); +var + SelectDirDialog: TSelectDirectoryDialog; + NewDir: String; +begin + SelectDirDialog:=TSelectDirectoryDialog.Create(Self); + InputHistories.ApplyFileDialogSettings(SelectDirDialog); + SelectDirDialog.Title:=lisChooseDirectory; + if SelectDirDialog.Execute then begin + NewDir:=ExpandFileNameUTF8(SelectDirDialog.Filename); + SetComboBox(DestDirComboBox,NewDir,20); + end; + SelectDirDialog.Free; +end; + procedure TPublishProjectDialog.HelpButtonClick(Sender: TObject); begin LazarusHelp.ShowHelpForIDEControl(Self); @@ -205,6 +508,11 @@ begin if Options<>nil then SaveToOptions(Options); end; +procedure TPublishProjectDialog.UseFiltersCheckboxClick(Sender: TObject); +begin + FiltersPanel.Enabled := (Sender as TCheckBox).Checked; +end; + procedure TPublishProjectDialog.SetComboBox(AComboBox: TComboBox; const NewText: string; MaxItemCount: integer); begin @@ -213,60 +521,45 @@ end; procedure TPublishProjectDialog.LoadHistoryLists; var - List: THistoryList; + hl: THistoryList; begin // destination directories - List:=InputHistories.HistoryLists.GetList(hlPublishProjectDestDirs,true,rltFile); - List.AppendEntry(GetForcedPathDelims('$(TestDir)/publishedproject/')); - List.AppendEntry(GetForcedPathDelims('$(TestDir)/publishedpackage/')); - List.AppendEntry(GetForcedPathDelims('$(ProjPath)/published/')); - DestDirComboBox.Items.Assign(List); - - // command after - List:=InputHistories.HistoryLists.GetList(hlPublishProjectCommandsAfter,true,rltCaseSensitive); - List.AppendEntry(GetForcedPathDelims( - 'tar czf $MakeFile($(ProjPublishDir)).tgz $(ProjPublishDir)')); - List.AppendEntry(GetForcedPathDelims( - 'tar czf $(TestDir)/project.tgz -C $(TestDir) publishedproject')); - List.AppendEntry(GetForcedPathDelims( - 'tar czf $(TestDir)/package.tgz -C $(TestDir) publishedpackage')); - CommandAfterCombobox.Items.Assign(List); + hl:=InputHistories.HistoryLists.GetList(hlPublishProjectDestDirs,true,rltFile); + hl.AppendEntry(GetForcedPathDelims('$(TestDir)/publishedproject/')); + hl.AppendEntry(GetForcedPathDelims('$(TestDir)/publishedpackage/')); + hl.AppendEntry(GetForcedPathDelims('$(ProjPath)/published/')); + DestDirComboBox.Items.Assign(hl); - // file filter - List:=InputHistories.HistoryLists.GetList(hlPublishProjectIncludeFileFilter, - true,rltFile); - if List.Count=0 then begin - List.Add(DefPublModIncFilter); - end; - IncludeFilterCombobox.Items.Assign(List); + // file filters + hl:=InputHistories.HistoryLists.GetList(hlPublishProjectIncludeFileFilter, + true,rltFile); + if hl.Count=0 then + hl.Add(DefPublModIncFilter); + IncludeFilterCombobox.Items.Assign(hl); - List:=InputHistories.HistoryLists.GetList(hlPublishProjectExcludeFileFilter, - true,rltFile); - if List.Count=0 then begin - List.Add(DefPublModExcFilter); - end; - ExcludeFilterCombobox.Items.Assign(List); + hl:=InputHistories.HistoryLists.GetList(hlPublishProjectExcludeFileFilter, + true,rltFile); + if hl.Count=0 then + hl.Add(DefPublModExcFilter); + ExcludeFilterCombobox.Items.Assign(hl); end; procedure TPublishProjectDialog.SaveHistoryLists; +var + hl: THistoryList; begin // destination directories SetComboBox(DestDirComboBox,DestDirComboBox.Text,20); - InputHistories.HistoryLists.GetList(hlPublishProjectDestDirs,true,rltFile).Assign( - DestDirComboBox.Items); - - // command after - SetComboBox(CommandAfterCombobox,CommandAfterCombobox.Text,20); - InputHistories.HistoryLists.GetList(hlPublishProjectCommandsAfter,true, - rltCaseSensitive).Assign(CommandAfterCombobox.Items); + hl:=InputHistories.HistoryLists.GetList(hlPublishProjectDestDirs,true,rltFile); + hl.Assign(DestDirComboBox.Items); - // file filter + // file filters SetComboBox(IncludeFilterCombobox,IncludeFilterCombobox.Text,20); - InputHistories.HistoryLists.GetList(hlPublishProjectIncludeFileFilter,true, - rltFile).Assign(IncludeFilterCombobox.Items); + hl:=InputHistories.HistoryLists.GetList(hlPublishProjectIncludeFileFilter,true,rltFile); + hl.Assign(IncludeFilterCombobox.Items); SetComboBox(ExcludeFilterCombobox,ExcludeFilterCombobox.Text,20); - InputHistories.HistoryLists.GetList(hlPublishProjectExcludeFileFilter,true, - rltFile).Assign(ExcludeFilterCombobox.Items); + hl:=InputHistories.HistoryLists.GetList(hlPublishProjectExcludeFileFilter,true,rltFile); + hl.Assign(ExcludeFilterCombobox.Items); end; procedure TPublishProjectDialog.SetOptions(const AValue: TPublishModuleOptions); @@ -286,91 +579,44 @@ begin if Options<>nil then begin if not Options.IncludeFilterValid then begin if IDEMessageDialog(lisCCOErrorCaption, lisPublProjInvalidIncludeFilter, - mtError, [mbIgnore, - mbCancel]) - =mrCancel + mtError, [mbIgnore,mbCancel]) = mrCancel then exit; end; if not Options.ExcludeFilterValid then begin if IDEMessageDialog(lisCCOErrorCaption, lisPublProjInvalidExcludeFilter, - mtError, [mbIgnore, - mbCancel]) - =mrCancel + mtError, [mbIgnore,mbCancel]) = mrCancel then exit; end; end; Result:=true; end; -constructor TPublishProjectDialog.Create(TheOwner: TComponent); -begin - inherited Create(TheOwner); - Position:=poScreenCenter; - IDEDialogLayoutList.ApplyLayout(Self); - LoadHistoryLists; -end; - -destructor TPublishProjectDialog.Destroy; -begin - SaveHistoryLists; - inherited Destroy; -end; - procedure TPublishProjectDialog.LoadFromOptions(SrcOpts: TPublishModuleOptions); -var - ProjSrcOpts: TPublishProjectOptions; begin // destination SeTComboBox(DestDirComboBox,SrcOpts.DestinationDirectory,20); - SeTComboBox(CommandAfterCombobox,SrcOpts.CommandAfter,20); - // file filter - IgnoreBinariesCheckbox.Checked:=SrcOpts.IgnoreBinaries; - UseIncludeFilterCheckbox.Checked:=SrcOpts.UseIncludeFileFilter; + // file filters + CompressCheckbox.Checked:=SrcOpts.CompressFinally; + UseFiltersCheckbox.Checked:=SrcOpts.UseFileFilters; IncFilterSimpleSyntaxCheckbox.Checked:=SrcOpts.IncludeFilterSimpleSyntax; SeTComboBox(IncludeFilterCombobox,SrcOpts.IncludeFileFilter,20); - UseExcludeFilterCheckbox.Checked:=SrcOpts.UseExcludeFileFilter; ExcFilterSimpleSyntaxCheckbox.Checked:=SrcOpts.ExcludeFilterSimpleSyntax; SeTComboBox(ExcludeFilterCombobox,SrcOpts.ExcludeFileFilter,20); - - // project info - if SrcOpts is TPublishProjectOptions then begin - ProjSrcOpts:=TPublishProjectOptions(SrcOpts); - SaveEditorInfoOfNonProjectFilesCheckbox.Checked:= - ProjSrcOpts.SaveEditorInfoOfNonProjectFiles; - SaveClosedEditorFilesInfoCheckbox.Checked:= - ProjSrcOpts.SaveClosedEditorFilesInfo; - ProjectInfoGroupbox.Enabled:=true; - end else begin - ProjectInfoGroupbox.Enabled:=false; - end; end; procedure TPublishProjectDialog.SaveToOptions(DestOpts: TPublishModuleOptions); -var - ProjDestOpts: TPublishProjectOptions; begin // destination DestOpts.DestinationDirectory:=DestDirComboBox.Text; - DestOpts.CommandAfter:=CommandAfterCombobox.Text; - - // file filter - DestOpts.IgnoreBinaries:=IgnoreBinariesCheckbox.Checked; - DestOpts.UseIncludeFileFilter:=UseIncludeFilterCheckbox.Checked; + + // file filters + DestOpts.CompressFinally:=CompressCheckbox.Checked; + DestOpts.UseFileFilters:=UseFiltersCheckbox.Checked; DestOpts.IncludeFilterSimpleSyntax:=IncFilterSimpleSyntaxCheckbox.Checked; DestOpts.IncludeFileFilter:=IncludeFilterCombobox.Text; - DestOpts.UseExcludeFileFilter:=UseExcludeFilterCheckbox.Checked; DestOpts.ExcludeFilterSimpleSyntax:=ExcFilterSimpleSyntaxCheckbox.Checked; DestOpts.ExcludeFileFilter:=ExcludeFilterCombobox.Text; - - // project info - if DestOpts is TPublishProjectOptions then begin - ProjDestOpts:=TPublishProjectOptions(DestOpts); - ProjDestOpts.SaveEditorInfoOfNonProjectFiles:= - SaveEditorInfoOfNonProjectFilesCheckbox.Checked; - ProjDestOpts.SaveClosedEditorFilesInfo:= - SaveClosedEditorFilesInfoCheckbox.Checked; - end; end; end. diff --git a/ide/sourcefilemanager.pas b/ide/sourcefilemanager.pas index ed52b1ae6b..27040d82f7 100644 --- a/ide/sourcefilemanager.pas +++ b/ide/sourcefilemanager.pas @@ -53,7 +53,7 @@ uses SourceSynEditor, SourceEditor, EditorOptions, EnvironmentOpts, CustomFormEditor, ControlSelection, FormEditor, EmptyMethodsDlg, BaseDebugManager, TransferMacros, BuildManager, EditorMacroListViewer, FindRenameIdentifier, GenericCheckList, - ViewUnit_Dlg, DiskDiffsDialog, InputHistory, CheckLFMDlg, PublishModule, etMessagesWnd, + ViewUnit_Dlg, DiskDiffsDialog, InputHistory, CheckLFMDlg, etMessagesWnd, ConvCodeTool, BasePkgManager, PackageDefs, PackageSystem, Designer, DesignerProcs; type @@ -179,10 +179,6 @@ type SearchFlags: TProjectFileSearchFlags): boolean; procedure RemovePathFromBuildModes(ObsoletePaths: String; pcos: TParsedCompilerOptString); function ShowCheckListBuildModes(DlgMsg: String): Boolean; - // methods for publish project - procedure OnCopyFile(const Filename: string; var Copy: boolean; Data: TObject); - procedure OnCopyError(const ErrorData: TCopyErrorData; - var {%H-}Handled: boolean; {%H-}Data: TObject); public constructor Create; destructor Destroy; override; @@ -210,8 +206,6 @@ type Flags: TCloseFlags):TModalResult; function CloseEditorFile(const Filename: string; Flags: TCloseFlags): TModalResult; - function PublishModule(Options: TPublishModuleOptions; - const SrcDirectory, DestDirectory: string): TModalResult; // interactive unit selection function SelectProjectItems(ItemList: TViewUnitEntries; ItemType: TIDEProjectItem; @@ -3480,165 +3474,6 @@ begin end; end; -procedure TLazSourceFileManager.OnCopyFile(const Filename: string; var Copy: boolean; Data: TObject); -begin - if Data=nil then exit; - if Data is TPublishModuleOptions then begin - Copy:=TPublishModuleOptions(Data).FileCanBePublished(Filename); - //debugln('TLazSourceFileManager.OnCopyFile "',Filename,'" ',Copy); - end; -end; - -procedure TLazSourceFileManager.OnCopyError(const ErrorData: TCopyErrorData; - var Handled: boolean; Data: TObject); -begin - case ErrorData.Error of - ceSrcDirDoesNotExists: - IDEMessageDialog(lisCopyError2, - Format(lisSourceDirectoryDoesNotExist, [ErrorData.Param1]), - mtError,[mbCancel]); - ceCreatingDirectory: - IDEMessageDialog(lisCopyError2, - Format(lisUnableToCreateDirectory, [ErrorData.Param1]), - mtError,[mbCancel]); - ceCopyFileError: - IDEMessageDialog(lisCopyError2, - Format(lisUnableToCopyFileTo, [ErrorData.Param1, LineEnding, ErrorData.Param1]), - mtError,[mbCancel]); - end; -end; - -function TLazSourceFileManager.PublishModule(Options: TPublishModuleOptions; - const SrcDirectory, DestDirectory: string): TModalResult; -var - SrcDir, DestDir: string; - NewProjectFilename: string; - Tool: TIDEExternalToolOptions; - CommandAfter, CmdAfterExe, CmdAfterParams: string; - CurProject: TProject; - TempCmd: String; - - procedure ShowErrorForCommandAfter; - begin - IDEMessageDialog(lisInvalidCommand, - Format(lisTheCommandAfterIsNotExecutable, [CmdAfterExe]), - mtError,[mbCancel]); - end; - -begin - //DebugLn('Hint: (lazarus) [TLazSourceFileManager.PublishModule] START'); - Result:=mrCancel; - - // do not delete project/package files - DestDir:=TrimAndExpandDirectory(DestDirectory); - SrcDir:=TrimAndExpandDirectory(SrcDirectory); - if (DestDir='') then begin - IDEMessageDialog('Invalid publishing Directory', - 'Destination directory for publishing is empty.',mtError, - [mbCancel]); - Result:=mrCancel; - exit; - end; - //DebugLn('Hint: (lazarus) [TLazSourceFileManager.PublishModule] SrcDir="',SrcDir,'" DestDir="',DestDir,'"'); - if CompareFilenames(SrcDir,DestDir)=0 - then begin - IDEMessageDialog(lisInvalidPublishingDirectory, - Format(lisSourceDirectoryAndDestinationDirectoryAreTheSameMa, - [SrcDir, LineEnding, DestDir, LineEnding, LineEnding]), - mtError, [mbCancel]); - Result:=mrCancel; - exit; - end; - - // check command after - CommandAfter:=Options.CommandAfter; - if not GlobalMacroList.SubstituteStr(CommandAfter) then begin - Result:=mrCancel; - exit; - end; - SplitCmdLine(CommandAfter,CmdAfterExe,CmdAfterParams); - if (CmdAfterExe<>'') then begin - //DebugLn('Hint: (lazarus) [TLazSourceFileManager.PublishModule] CmdAfterExe="',CmdAfterExe,'"'); - // first look in the project directory - TempCmd:=CmdAfterExe; - if not FilenameIsAbsolute(TempCmd) then - TempCmd:=TrimFilename(AppendPathDelim(Project1.Directory)+TempCmd); - if FileExistsCached(TempCmd) then begin - CmdAfterExe:=TempCmd; - end else begin - TempCmd:=FindDefaultExecutablePath(CmdAfterExe); - if TempCmd<>'' then - CmdAfterExe:=TempCmd; - end; - if not FileIsExecutableCached(CmdAfterExe) then begin - IDEMessageDialog(lisCommandAfterInvalid, - Format(lisTheCommandAfterPublishingIsInvalid, [LineEnding, CmdAfterExe]), - mtError, [mbCancel]); - Result:=mrCancel; - exit; - end; - end; - - // clear destination directory - if DirPathExists(DestDir) then begin - // ask user, if destination can be deleted - if IDEMessageDialog(lisClearDirectory, - Format(lisInOrderToCreateACleanCopyOfTheProjectPackageAllFil, - [LineEnding+LineEnding, DestDir]), - mtConfirmation, [mbYes,mbNo])<>mrYes - then - exit(mrCancel); - - if (not DeleteDirectory(ChompPathDelim(DestDir),true)) then begin - IDEMessageDialog(lisUnableToCleanUpDestinationDirectory, - Format(lisUnableToCleanUpPleaseCheckPermissions, [DestDir, LineEnding]), - mtError,[mbOk]); - Result:=mrCancel; - exit; - end; - end; - - // copy the directory - if not CopyDirectoryWithMethods(SrcDir,DestDir,@OnCopyFile,@OnCopyError,Options) then - begin - debugln('Hint: (lazarus) [TLazSourceFileManager.PublishModule] CopyDirectoryWithMethods failed'); - Result:=mrCancel; - exit; - end; - - // write a filtered .lpi file - if Options is TPublishProjectOptions then begin - CurProject:=TProject(TPublishProjectOptions(Options).Owner); - NewProjectFilename:=DestDir+ExtractFilename(CurProject.ProjectInfoFile); - DeleteFileUTF8(NewProjectFilename); - Result:=CurProject.WriteProject(CurProject.PublishOptions.WriteFlags - +pwfSkipSessionInfo+[pwfIgnoreModified], - NewProjectFilename,nil); - if Result<>mrOk then begin - debugln('Hint: (lazarus) [TLazSourceFileManager.PublishModule] CurProject.WriteProject failed'); - exit; - end; - end; - - // execute 'CommandAfter' - if (CmdAfterExe<>'') then begin - if FileIsExecutableCached(CmdAfterExe) then begin - Tool:=TIDEExternalToolOptions.Create; - Tool.Title:=lisCommandAfterPublishingModule; - Tool.WorkingDirectory:=DestDir; - Tool.CmdLineParams:=CmdAfterParams; - Tool.Executable:=CmdAfterExe; - if RunExternalTool(Tool) then - Result:=mrOk - else - Result:=mrCancel; - end else begin - ShowErrorForCommandAfter; - exit(mrCancel); - end; - end; -end; - function TLazSourceFileManager.SelectProjectItems(ItemList: TViewUnitEntries; ItemType: TIDEProjectItem; MultiSelect: boolean; var MultiSelectCheckedState: Boolean): TModalResult; diff --git a/packager/packagedefs.pas b/packager/packagedefs.pas index 79a4849500..3ac5888e48 100644 --- a/packager/packagedefs.pas +++ b/packager/packagedefs.pas @@ -404,14 +404,10 @@ type { TPublishPackageOptions } TPublishPackageOptions = class(TPublishModuleOptions) - private - FLazPackage: TLazPackage; protected procedure DoOnModifyChange; override; public - constructor Create(TheLazPackage: TLazPackage); function GetDefaultDestinationDir: string; override; - property LazPackage: TLazPackage read FLazPackage; end; @@ -4520,13 +4516,8 @@ end; procedure TPublishPackageOptions.DoOnModifyChange; begin - if Modified then LazPackage.Modified:=true; -end; - -constructor TPublishPackageOptions.Create(TheLazPackage: TLazPackage); -begin - FLazPackage:=TheLazPackage; - inherited Create(FLazPackage); + if Modified then + TLazPackage(Owner).Modified:=true; end; function TPublishPackageOptions.GetDefaultDestinationDir: string; @@ -4552,8 +4543,7 @@ begin inherited Destroy; end; -function TPkgPairTree.FindPair(Pkg1, Pkg2: TLazPackage; IgnoreOrder: boolean - ): TPkgPair; +function TPkgPairTree.FindPair(Pkg1, Pkg2: TLazPackage; IgnoreOrder: boolean): TPkgPair; var Comp: integer; ANode: TAVLTreeNode; diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index a1744b6d5d..945903d91c 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -62,7 +62,7 @@ uses IDEMsgIntf, SrcEditorIntf, ComponentReg, PropEdits, IDEDialogs, UnitResources, // IDE IDECmdLine, LazarusIDEStrConsts, IDEProcs, ObjectLists, - DialogProcs, IDEOptionDefs, EnvironmentOpts, + DialogProcs, IDEOptionDefs, EnvironmentOpts, SourceFileManager, MiscOptions, InputHistory, Project, PackageEditor, AddToPackageDlg, PackageDefs, PackageLinks, PackageSystem, OpenInstalledPkgDlg, PkgGraphExplorer, BrokenDependenciesDlg, CompilerOptions, IDETranslations, @@ -223,7 +223,6 @@ type // files function GetDefaultSaveDirectoryForFile(const Filename: string): string; override; - function GetPublishPackageDir(APackage: TLazPackage): string; function OnRenameFile(const OldFilename, NewFilename: string; IsPartOfProject: boolean): TModalResult; override; function FindIncludeFileInProjectDependencies(aProject: TProject; @@ -3063,20 +3062,6 @@ begin Result:=APackage.Directory; end; -function TPkgManager.GetPublishPackageDir(APackage: TLazPackage): string; -begin - Result:=APackage.PublishOptions.DestinationDirectory; - if IDEMacros.SubstituteMacros(Result) then begin - if FilenameIsAbsolute(Result) then begin - Result:=AppendPathDelim(TrimFilename(Result)); - end else begin - Result:=''; - end; - end else begin - Result:=''; - end; -end; - procedure TPkgManager.LoadInstalledPackages; begin IDEComponentPalette.BeginUpdate(true); @@ -6068,7 +6053,7 @@ function TPkgManager.DoPublishPackage(APackage: TLazPackage; begin // show the publish dialog if ShowDialog then begin - Result:=ShowPublishProjectDialog(APackage.PublishOptions); + Result:=ShowPublishDialog(APackage.PublishOptions); if Result<>mrOk then exit; end; @@ -6077,8 +6062,7 @@ begin if Result<>mrOk then exit; // publish package - Result:=MainIDE.DoPublishModule(APackage.PublishOptions,APackage.Directory, - GetPublishPackageDir(APackage)); + Result:=PublishAModule(APackage.PublishOptions); end; function TPkgManager.GetUsableComponentUnits(CurRoot: TPersistent): TFPList;