├── Utils.pas ├── DelphiPI.res ├── assemble.exe ├── DelphiPI_Icon.ico ├── DelphiPIConsole.res ├── Test ├── DelphiPITests.res ├── DelphiPITests_Icon.ico ├── dunit.ini ├── TestDelphiVersionGuess.pas ├── TestPackageInfo.pas ├── DelphiPITests.dpr ├── TestPackageList.pas ├── TestDelphiVersionTreeViewModel.pas ├── TestPackageDependencyVerifier.pas ├── TestTreeModel.pas └── DelphiPITests.dproj ├── po ├── readme.txt └── default.po ├── .gitignore ├── PageBase.dfm ├── CustomTypes.pas ├── ProgressMonitor.pas ├── README.md ├── WizardIntfs.pas ├── i18n.bat ├── setup ├── README.TXT ├── setup.iss └── LICENSE.txt ├── DelphiPIConsole.dpr ├── ListViewModel.pas ├── PageSummary.dfm ├── TreeModel.pas ├── PageInstallHelpFiles.dfm ├── PageBase.pas ├── DelphiPI.dpr ├── PackageList.pas ├── PackageInfo.pas ├── FormAbout.pas ├── DelphiPIProject.groupproj ├── PackageDependencyVerifier.pas ├── PageProgress.dfm ├── PageInstallHelpFiles.pas ├── PageCompilerOptions.dfm ├── TreeNodes.pas ├── PageSelectFolders.dfm ├── PackageLoadThread.pas ├── ConsoleProgressMonitor.pas ├── MonitoredPackageCompiler.pas ├── CompileThread.pas ├── ConsoleRunner.pas ├── PackageInfoFactory.pas ├── TreeViewModel.pas ├── CompilationData.pas ├── PageCompilerOptions.pas ├── InstalledPackageResolver.pas ├── PageSummary.pas ├── DelphiVersionTreeViewModel.pas ├── PageSelectFolders.pas ├── PageProgress.pas ├── FormWizard.pas ├── PackageCompiler.pas ├── ScriptPersister.pas └── DelphiPIConsole.dproj /Utils.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idursun/delphipi/HEAD/Utils.pas -------------------------------------------------------------------------------- /DelphiPI.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idursun/delphipi/HEAD/DelphiPI.res -------------------------------------------------------------------------------- /assemble.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idursun/delphipi/HEAD/assemble.exe -------------------------------------------------------------------------------- /DelphiPI_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idursun/delphipi/HEAD/DelphiPI_Icon.ico -------------------------------------------------------------------------------- /DelphiPIConsole.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idursun/delphipi/HEAD/DelphiPIConsole.res -------------------------------------------------------------------------------- /Test/DelphiPITests.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idursun/delphipi/HEAD/Test/DelphiPITests.res -------------------------------------------------------------------------------- /Test/DelphiPITests_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idursun/delphipi/HEAD/Test/DelphiPITests_Icon.ico -------------------------------------------------------------------------------- /po/readme.txt: -------------------------------------------------------------------------------- 1 | Download Poedit (Gettext Translations Editor) and install 2 | http://poedit.net/ 3 | 4 | Download dxgettext and install 5 | http://sourceforge.net/projects/dxgettext/ 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | *.dcu 3 | *.exe 4 | __history 5 | *.orig 6 | *.local 7 | *.identcache 8 | *.todo 9 | *.tvsconfig 10 | ModelSupport* 11 | *.cbk 12 | LibrarySupport 13 | *.mo 14 | *.drc 15 | *.map 16 | -------------------------------------------------------------------------------- /PageBase.dfm: -------------------------------------------------------------------------------- 1 | object WizardPage: TWizardPage 2 | Left = 0 3 | Top = 0 4 | Align = alClient 5 | BorderStyle = bsNone 6 | Caption = 'WizardPage' 7 | ClientHeight = 250 8 | ClientWidth = 500 9 | Color = clBtnFace 10 | Font.Charset = DEFAULT_CHARSET 11 | Font.Color = clWindowText 12 | Font.Height = -11 13 | Font.Name = 'Tahoma' 14 | Font.Style = [] 15 | OldCreateOrder = False 16 | WindowState = wsMaximized 17 | ExplicitWidth = 320 18 | ExplicitHeight = 240 19 | PixelsPerInch = 96 20 | TextHeight = 13 21 | end 22 | -------------------------------------------------------------------------------- /CustomTypes.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit CustomTypes; 7 | 8 | interface 9 | type 10 | 11 | TString = class 12 | private 13 | fStr: string; 14 | public 15 | constructor Create(const str: string); 16 | property Value: string read fStr write fStr; 17 | end; 18 | 19 | implementation 20 | 21 | { TString } 22 | 23 | constructor TString.Create(const str: string); 24 | begin 25 | fStr := str; 26 | end; 27 | 28 | end. 29 | -------------------------------------------------------------------------------- /ProgressMonitor.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit ProgressMonitor; 7 | 8 | interface 9 | uses PackageInfo; 10 | type 11 | IProgressMonitor = interface 12 | ['{04616FA5-F839-4ADC-A4FF-2DDAAC02E597}'] 13 | procedure Started; 14 | procedure Finished; 15 | procedure PackageProcessed(const packageInfo: TPackageInfo; status: TPackageStatus); 16 | procedure Log(const text: string); 17 | procedure CompilerOutput(const line: string); 18 | end; 19 | 20 | implementation 21 | end. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DelphiPI 2 | ======== 3 | 4 | Delphi Package Installer 5 | 6 | 7 | Delphi Package Installer (DelphiPI) is a tool which aids you installing components to your Delphi IDE. DelphiPI automatically resolves dependencies between packages, compiles, installs and adds source paths to your IDE. 8 | 9 | ### How to compile 10 | 11 | You need to download and install two packages to be able to compile DelphiPI. 12 | 13 | * Download and install [JCL](https://github.com/project-jedi/jcl). Version used is jcl-2.6.0.5178 14 | * Download and install [Softgem's Virtual TreeView](www.soft-gems.net). Instructions for installing are in the INSTALL.txt file. Version used is V5.41 15 | * Open DelphiPI Package Group and build. -------------------------------------------------------------------------------- /WizardIntfs.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit WizardIntfs; 7 | 8 | interface 9 | uses Classes, StdCtrls, ActnList; 10 | type 11 | TWizardButtonType = (wbtNone, wbtNext, wbtBack, wbtHelp); 12 | IWizard = interface 13 | ['{82A45FE8-CCA1-4DED-91DB-67F1D2989D56}'] 14 | procedure UpdateInterface; 15 | function GetAction(buttonType: TWizardButtonType): TAction; 16 | // function GetData: TInterfacedObject; 17 | procedure SetHeader(const header:String); 18 | procedure SetDescription(const desc: String); 19 | function GetState(const key:string):TObject; 20 | procedure SetState(const key: string; const value:TObject); 21 | end; 22 | 23 | implementation 24 | 25 | end. 26 | -------------------------------------------------------------------------------- /i18n.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | ECHO Building GUI PO template file... 4 | dxgettext -r -b . -b . --delphi --so .\po\delphipi.pot 5 | 6 | ECHO . 7 | ECHO Merging GUI translation files with template... 8 | 9 | msgmerge -o .\po\tr.po -D .\po\tr.po .\po\delphipi.pot 10 | msgmerge -o .\po\ru_RU.po -D .\po\ru_RU.po .\po\delphipi.pot 11 | msgmerge -o .\po\default.po -D .\po\default.po .\po\delphipi.pot 12 | 13 | ECHO . 14 | ECHO Building MO file... 15 | mkdir .\locale\TR\LC_MESSAGES 16 | msgfmt .\po\tr.po -o .\locale\TR\LC_MESSAGES\default.mo 17 | mkdir .\locale\RU\LC_MESSAGES 18 | msgfmt .\po\ru_RU.po -o .\locale\RU\LC_MESSAGES\default.mo 19 | mkdir .\locale\EN\LC_MESSAGES 20 | msgfmt .\po\default.po -o .\locale\EN\LC_MESSAGES\default.mo 21 | ECHO . 22 | 23 | ECHO Embedding MO files into EXE 24 | assemble --dxgettext .\delphipi.exe 25 | assemble --dxgettext .\delphipi.x64.exe 26 | 27 | ECHO . 28 | ECHO Done. 29 | 30 | PAUSE -------------------------------------------------------------------------------- /Test/dunit.ini: -------------------------------------------------------------------------------- 1 | [GUITestRunner Config] 2 | AutoSave=1 3 | Left=104 4 | Top=34 5 | Width=797 6 | Height=692 7 | Maximized=0 8 | UseRegistry=0 9 | ResultsPanel.Height=198 10 | ErrorMessage.Height=105 11 | ErrorMessage.Visible=1 12 | FailureList.ColumnWidth[0]=120 13 | FailureList.ColumnWidth[1]=100 14 | FailureList.ColumnWidth[2]=262 15 | FailureList.ColumnWidth[3]=287 16 | HideTestNodesOnOpen=0 17 | BreakOnFailures=0 18 | FailOnNoChecksExecuted=0 19 | FailOnMemoryLeaked=0 20 | IgnoreSetUpTearDownLeaks=0 21 | ReportMemoryLeakTypes=0 22 | SelectTestedNode=1 23 | WarnOnFailTestOverride=0 24 | PopupX=350 25 | PopupY=30 26 | 27 | [Tests.DelphiPITests.exe] 28 | 29 | [Tests.DelphiPITests.exe.TestTPackageList] 30 | 31 | [Tests.DelphiPITests.exe.TestTPackageInfo] 32 | 33 | [Tests.DelphiPITests.exe.TestTPackageDependencyVerifier] 34 | 35 | [Tests.DelphiPITests.exe.TestTTreeModel] 36 | 37 | [Tests.DelphiPITests.exe.TestTDelphiVersionTreeViewModel] 38 | 39 | -------------------------------------------------------------------------------- /setup/README.TXT: -------------------------------------------------------------------------------- 1 | Description: 2 | 3 | Delphi Package Installer (DelphiPI) is a tool which aids you installing components to your Delphi IDE. 4 | DelphiPI automatically resolves dependencies between packages, compiles, installs and 5 | adds source paths to your IDE and also registers if there are any help file suitable for 6 | OpenHelp (Delphi 7 and previous versions). 7 | 8 | 9 | How To Use: 10 | * Start DelphiPI 11 | * Select the folder where both package file (*.dpk) and source files (*.pas) reside. 12 | 13 | If the directory structure is like: 14 | 15 | SuperLibrary\packages SuperLibrary\source 16 | 17 | then just select SuperLibrary folder. 18 | 19 | * Specify a pattern that matches for your delphi installation. 20 | If you don't want to use a pattern just leave it as *.dpk and unselect the packages that are not suitable for 21 | your delphi installation. 22 | 23 | 24 | Websites: 25 | http://www.thexpot.net 26 | http://code.google.com/p/delphipi/ -------------------------------------------------------------------------------- /DelphiPIConsole.dpr: -------------------------------------------------------------------------------- 1 | program DelphiPIConsole; 2 | 3 | {$APPTYPE CONSOLE} 4 | 5 | uses 6 | SysUtils, 7 | CompilationData in 'CompilationData.pas', 8 | CompileThread in 'CompileThread.pas', 9 | ConsoleRunner in 'ConsoleRunner.pas', 10 | MonitoredPackageCompiler in 'MonitoredPackageCompiler.pas', 11 | PackageCompiler in 'PackageCompiler.pas', 12 | PackageDependencyVerifier in 'PackageDependencyVerifier.pas', 13 | PackageInfo in 'PackageInfo.pas', 14 | PackageInfoFactory in 'PackageInfoFactory.pas', 15 | PackageList in 'PackageList.pas', 16 | ProgressMonitor in 'ProgressMonitor.pas', 17 | ScriptPersister in 'ScriptPersister.pas', 18 | Utils in 'Utils.pas', 19 | gnugettext in 'libs\gnugettext.pas', 20 | ConsoleProgressMonitor in 'ConsoleProgressMonitor.pas'; 21 | 22 | var 23 | consoleRunner : TConsoleRunner; 24 | begin 25 | try 26 | consoleRunner := TConsoleRunner.Create; 27 | try 28 | consoleRunner.Run; 29 | Readln; 30 | finally 31 | consoleRunner.Free; 32 | end; 33 | except 34 | on E:Exception do 35 | Writeln(E.Classname, ': ', E.Message); 36 | end; 37 | end. 38 | 39 | -------------------------------------------------------------------------------- /ListViewModel.pas: -------------------------------------------------------------------------------- 1 | { ** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | ** } 6 | unit ListViewModel; 7 | 8 | interface 9 | uses Classes, Generics.Collections, TreeModel, PackageInfo; 10 | type 11 | TListViewModel = class(TTreeModelBase) 12 | private 13 | fList: TList; 14 | public 15 | constructor Create(list: TList); virtual; 16 | function GetChild(const parent: T; index: Integer): T; override; 17 | function GetChildCount(const parent: T): Integer; override; 18 | end; 19 | 20 | implementation 21 | 22 | { TListViewModel } 23 | 24 | constructor TListViewModel.Create(list: TList); 25 | begin 26 | fList := list; 27 | end; 28 | 29 | function TListViewModel.GetChild(const parent: T; index: Integer): T; 30 | begin 31 | Result := default(T); 32 | if index < fList.Count then 33 | Result := fList[index]; 34 | end; 35 | 36 | function TListViewModel.GetChildCount(const parent: T): Integer; 37 | begin 38 | Result := 0; 39 | if parent = nil then 40 | Result := fList.Count 41 | end; 42 | 43 | end. 44 | -------------------------------------------------------------------------------- /Test/TestDelphiVersionGuess.pas: -------------------------------------------------------------------------------- 1 | unit TestDelphiVersionGuess; 2 | 3 | interface 4 | uses TestFramework; 5 | 6 | type 7 | TestDelphiDelphiVersionGuess = class(TTestCase) 8 | published 9 | procedure Should_guess_Delphi6; 10 | procedure Should_guess_DelphiXE2; 11 | end; 12 | 13 | implementation 14 | uses Utils; 15 | { TestDelphiDelphiVersionGuess } 16 | 17 | procedure TestDelphiDelphiVersionGuess.Should_guess_Delphi6; 18 | var 19 | actual: integer; 20 | begin 21 | CheckEquals(DELPHI_VERSION_6, Utils.GuessDelphiVersion('pack60')); 22 | CheckEquals(DELPHI_VERSION_6, Utils.GuessDelphiVersion('pack6')); 23 | CheckEquals(DELPHI_VERSION_6, Utils.GuessDelphiVersion('packD6')); 24 | CheckEquals(DELPHI_VERSION_6, Utils.GuessDelphiVersion('packD60')); 25 | end; 26 | 27 | procedure TestDelphiDelphiVersionGuess.Should_guess_DelphiXE2; 28 | begin 29 | CheckEquals(DELPHI_XE2, Utils.GuessDelphiVersion('pack160')); 30 | CheckEquals(DELPHI_XE2, Utils.GuessDelphiVersion('pack16')); 31 | CheckEquals(DELPHI_XE2, Utils.GuessDelphiVersion('packD16')); 32 | CheckEquals(DELPHI_XE2, Utils.GuessDelphiVersion('packD160')); 33 | end; 34 | 35 | initialization 36 | RegisterTest(TestDelphiDelphiVersionGuess.Suite); 37 | end. 38 | -------------------------------------------------------------------------------- /PageSummary.dfm: -------------------------------------------------------------------------------- 1 | inherited SummaryPage: TSummaryPage 2 | Left = 328 3 | Top = 271 4 | Caption = 'SummaryPage' 5 | ClientHeight = 232 6 | ClientWidth = 412 7 | OnCreate = FormCreate 8 | ExplicitWidth = 412 9 | ExplicitHeight = 232 10 | PixelsPerInch = 96 11 | TextHeight = 13 12 | object Label1: TLabel 13 | Left = 8 14 | Top = 183 15 | Width = 312 16 | Height = 34 17 | Anchors = [akLeft, akRight, akBottom] 18 | AutoSize = False 19 | Caption = 20 | 'Would you like to save this installation as a script so that you' + 21 | ' can automate installation of these packages?' 22 | WordWrap = True 23 | end 24 | object Label2: TLabel 25 | Left = 8 26 | Top = 8 27 | Width = 48 28 | Height = 13 29 | Caption = 'Summary:' 30 | end 31 | object btnSave: TButton 32 | Left = 324 33 | Top = 183 34 | Width = 80 35 | Height = 25 36 | Anchors = [akRight, akBottom] 37 | Caption = 'Save' 38 | TabOrder = 0 39 | OnClick = btnSaveClick 40 | end 41 | object edtSummary: TMemo 42 | Left = 8 43 | Top = 27 44 | Width = 396 45 | Height = 150 46 | Anchors = [akLeft, akTop, akRight, akBottom] 47 | ReadOnly = True 48 | ScrollBars = ssBoth 49 | TabOrder = 1 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /TreeModel.pas: -------------------------------------------------------------------------------- 1 | { ** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | ** } 6 | 7 | unit TreeModel; 8 | interface 9 | 10 | uses Classes, StrUtils, Generics.Collections; 11 | type 12 | TDynStrArray = array of string; 13 | 14 | INode = interface 15 | function GetDisplayName: string; 16 | function GetData: TObject; 17 | function GetNodePath: string; 18 | end; 19 | 20 | TCreateLogicalNodeHandler = reference to function(name, path:string):T; 21 | TTreeModelBase = class 22 | private 23 | fOnCreateLogicalNode: TCreateLogicalNodeHandler; 24 | protected 25 | function DoCreateLogicalNode(name, path:string):T; virtual; 26 | public 27 | function GetChild(const parent: T; index: Integer): T; virtual; abstract; 28 | function GetChildCount(const parent: T): integer; virtual; abstract; 29 | property OnCreateLogicalNode: TCreateLogicalNodeHandler read fOnCreateLogicalNode write fOnCreateLogicalNode; 30 | end; 31 | 32 | implementation 33 | 34 | uses JclStrings; 35 | 36 | function TTreeModelBase.DoCreateLogicalNode(name, path: string): T; 37 | begin 38 | if Assigned(fOnCreateLogicalNode) then 39 | Result := fOnCreateLogicalNode(name,path) 40 | else 41 | Result := default(T); 42 | end; 43 | 44 | end. 45 | -------------------------------------------------------------------------------- /PageInstallHelpFiles.dfm: -------------------------------------------------------------------------------- 1 | inherited InstallHelpFilesPage: TInstallHelpFilesPage 2 | Left = 202 3 | Top = 166 4 | Caption = 'InstallHelpFilesPage' 5 | ClientHeight = 240 6 | ClientWidth = 412 7 | OnCreate = FormCreate 8 | ExplicitWidth = 412 9 | PixelsPerInch = 96 10 | TextHeight = 13 11 | object Label1: TLabel 12 | Left = 8 13 | Top = 8 14 | Width = 484 15 | Height = 26 16 | Anchors = [akLeft, akTop, akRight] 17 | Caption = 18 | 'DelphiPI has found some help files in the folder that you have s' + 19 | 'elected. Would you like to install them as well?' 20 | WordWrap = True 21 | end 22 | object helpFileList: TListView 23 | Left = 8 24 | Top = 50 25 | Width = 396 26 | Height = 159 27 | Anchors = [akLeft, akTop, akRight, akBottom] 28 | Checkboxes = True 29 | Columns = < 30 | item 31 | AutoSize = True 32 | Caption = 'Help File Name' 33 | MinWidth = 200 34 | end> 35 | GridLines = True 36 | ParentShowHint = False 37 | ShowHint = True 38 | TabOrder = 0 39 | ViewStyle = vsReport 40 | end 41 | object btnInstallHelpFiles: TButton 42 | Left = 290 43 | Top = 215 44 | Width = 114 45 | Height = 25 46 | Anchors = [akRight, akBottom] 47 | Caption = 'Install Help Files' 48 | TabOrder = 1 49 | OnClick = btnInstallHelpFilesClick 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /Test/TestPackageInfo.pas: -------------------------------------------------------------------------------- 1 | unit TestPackageInfo; 2 | interface 3 | 4 | uses 5 | TestFramework, Classes, StrUtils, PackageInfo; 6 | 7 | type 8 | // Test methods for class TPackageInfo 9 | 10 | TestTPackageInfo = class(TTestCase) 11 | strict private 12 | FPackageInfo: TPackageInfo; 13 | base1, base2: TPackageInfo; 14 | public 15 | procedure SetUp; override; 16 | procedure TearDown; override; 17 | published 18 | procedure TestDependsOn; 19 | end; 20 | 21 | implementation 22 | 23 | procedure TestTPackageInfo.SetUp; 24 | begin 25 | FPackageInfo := TPackageInfo.Create('package1'); 26 | base1 := TPackageInfo.Create('base1'); 27 | base2 := TPackageInfo.Create('base2'); 28 | 29 | FPackageInfo.RequiredPackageList.Add(base1.PackageName); 30 | FPackageInfo.RequiredPackageList.Add(base2.PackageName); 31 | end; 32 | 33 | procedure TestTPackageInfo.TearDown; 34 | begin 35 | base1.Free; 36 | base2.Free; 37 | FPackageInfo.Free; 38 | FPackageInfo := nil; 39 | end; 40 | 41 | procedure TestTPackageInfo.TestDependsOn; 42 | var 43 | ReturnValue: Boolean; 44 | begin 45 | ReturnValue := FPackageInfo.DependsOn(base1); 46 | CheckTrue(ReturnValue, 'should confirm dependency to base1'); 47 | 48 | ReturnValue := FPackageInfo.DependsOn(base2); 49 | CheckTrue(ReturnValue, 'should confirm dependency base2'); 50 | 51 | end; 52 | 53 | initialization 54 | // Register any test cases with the test runner 55 | RegisterTest(TestTPackageInfo.Suite); 56 | end. 57 | 58 | -------------------------------------------------------------------------------- /Test/DelphiPITests.dpr: -------------------------------------------------------------------------------- 1 | program DelphiPITests; 2 | { 3 | 4 | Delphi DUnit Test Project 5 | ------------------------- 6 | This project contains the DUnit test framework and the GUI/Console test runners. 7 | Add "CONSOLE_TESTRUNNER" to the conditional defines entry in the project options 8 | to use the console test runner. Otherwise the GUI test runner will be used by 9 | default. 10 | 11 | } 12 | 13 | {$IFDEF CONSOLE_TESTRUNNER} 14 | {$APPTYPE CONSOLE} 15 | {$ENDIF} 16 | 17 | uses 18 | Forms, 19 | TestFramework, 20 | GUITestRunner, 21 | TextTestRunner, 22 | TestPackageList in 'TestPackageList.pas', 23 | PackageInfo in '..\PackageInfo.pas', 24 | PackageList in '..\PackageList.pas', 25 | TestPackageInfo in 'TestPackageInfo.pas', 26 | TestPackageDependencyVerifier in 'TestPackageDependencyVerifier.pas', 27 | PackageDependencyVerifier in '..\PackageDependencyVerifier.pas', 28 | CompilationData in '..\CompilationData.pas', 29 | gnugettext in '..\libs\gnugettext.pas', 30 | InstalledPackageResolver in '..\InstalledPackageResolver.pas', 31 | TestTreeModel in 'TestTreeModel.pas', 32 | TreeModel in '..\TreeModel.pas', 33 | TreeViewModel in '..\TreeViewModel.pas', 34 | DelphiVersionTreeViewModel in '..\DelphiVersionTreeViewModel.pas', 35 | TestDelphiVersionTreeViewModel in 'TestDelphiVersionTreeViewModel.pas', 36 | Utils in '..\Utils.pas', 37 | TestDelphiVersionGuess in 'TestDelphiVersionGuess.pas'; 38 | 39 | {$R *.RES} 40 | 41 | begin 42 | Application.Initialize; 43 | if IsConsole then 44 | TextTestRunner.RunRegisteredTests 45 | else 46 | GUITestRunner.RunRegisteredTests; 47 | end. 48 | 49 | -------------------------------------------------------------------------------- /PageBase.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PageBase; 7 | 8 | interface 9 | 10 | uses 11 | CompilationData, Windows, Messages, SysUtils, Variants, Classes, Graphics, Vcl.Controls, Forms, 12 | Dialogs, WizardIntfs; 13 | 14 | type 15 | TWizardPage = class(TForm) 16 | private 17 | function GetWizardController: IWizard; 18 | procedure SetWizardController(const Value: IWizard); 19 | protected 20 | fWizardController: IWizard; 21 | fCompilationData: TCompilationData; 22 | public 23 | constructor Create(Owner: TComponent; const compilationData: TCompilationData); reintroduce; virtual; 24 | procedure UpdateWizardState; virtual; 25 | function CanShowPage: Boolean; virtual; 26 | property Wizard: IWizard read GetWizardController write SetWizardController; 27 | end; 28 | 29 | TPageClass = class of TWizardPage; 30 | 31 | implementation 32 | 33 | uses FormWizard; 34 | {$R *.dfm} 35 | 36 | function TWizardPage.CanShowPage: Boolean; 37 | begin 38 | Result := true; 39 | end; 40 | 41 | constructor TWizardPage.Create(Owner: TComponent; const compilationData: TCompilationData); 42 | begin 43 | inherited Create(Owner); 44 | fCompilationData := compilationData; 45 | end; 46 | 47 | function TWizardPage.GetWizardController: IWizard; 48 | begin 49 | Result := TFrmWizard.Wizard; 50 | end; 51 | 52 | procedure TWizardPage.SetWizardController(const Value: IWizard); 53 | begin 54 | fWizardController := Value; 55 | end; 56 | procedure TWizardPage.UpdateWizardState; 57 | begin 58 | Assert(Assigned(Wizard)); 59 | end; 60 | 61 | end. 62 | 63 | -------------------------------------------------------------------------------- /setup/setup.iss: -------------------------------------------------------------------------------- 1 | ; Script generated by the Inno Setup Script Wizard. 2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! 3 | 4 | #define MyAppName "DelphiPI" 5 | #define MyAppVerName "DelphiPI 0.73" 6 | #define MyAppPublisher "http://www.idursun.com" 7 | #define MyAppURL "http://bitbucket.org/idursun/delphipi" 8 | #define MyAppExeName "DelphiPI.exe" 9 | 10 | [Setup] 11 | AppName={#MyAppName} 12 | AppVerName={#MyAppVerName} 13 | AppPublisher={#MyAppPublisher} 14 | AppPublisherURL={#MyAppURL} 15 | AppSupportURL={#MyAppURL} 16 | AppUpdatesURL={#MyAppURL} 17 | DefaultDirName={pf}\{#MyAppName} 18 | DefaultGroupName={#MyAppName} 19 | AllowNoIcons=yes 20 | LicenseFile=LICENSE.txt 21 | OutputBaseFilename=delphipi.0.73.setup 22 | Compression=lzma/ultra 23 | SolidCompression=true 24 | 25 | [Languages] 26 | Name: eng; MessagesFile: compiler:Default.isl 27 | ;Name: tr; MessagesFile: compiler:Languages\Turkish.isl 28 | 29 | [Tasks] 30 | Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked 31 | 32 | [Files] 33 | Source: ..\DelphiPI.exe; DestDir: {app}; Flags: ignoreversion 34 | Source: LICENSE.txt; DestDir: {app}; Flags: ignoreversion 35 | Source: README.TXT; DestDir: {app}; Flags: ignoreversion 36 | ;Source: ..\locale\tr\LC_MESSAGES\default.mo; DestDir: {app}\locale\tr\LC_MESSAGES; DestName: default.mo; Flags: ignoreversion; Languages: tr 37 | 38 | [Icons] 39 | Name: {group}\{#MyAppName}; Filename: {app}\{#MyAppExeName} 40 | Name: {group}\{cm:UninstallProgram,{#MyAppName}}; Filename: {uninstallexe} 41 | Name: {userdesktop}\{#MyAppName}; Filename: {app}\{#MyAppExeName}; Tasks: desktopicon 42 | 43 | [Run] 44 | Filename: {app}\{#MyAppExeName}; Description: {cm:LaunchProgram,{#MyAppName}}; Flags: nowait postinstall skipifsilent 45 | -------------------------------------------------------------------------------- /DelphiPI.dpr: -------------------------------------------------------------------------------- 1 | program DelphiPI; 2 | 3 | uses 4 | Forms, 5 | PackageInfo in 'PackageInfo.pas', 6 | FormAbout in 'FormAbout.pas' {frmAbout}, 7 | PackageCompiler in 'PackageCompiler.pas', 8 | FormWizard in 'FormWizard.pas' {frmWizard}, 9 | PageBase in 'PageBase.pas' {WizardPage}, 10 | PageSelectFolders in 'PageSelectFolders.pas' {SelectFoldersPage}, 11 | PageProgress in 'PageProgress.pas' {ProgressPage}, 12 | WizardIntfs in 'WizardIntfs.pas', 13 | PageShowPackageList in 'PageShowPackageList.pas' {ShowPackageListPage}, 14 | PageInstallHelpFiles in 'PageInstallHelpFiles.pas' {InstallHelpFilesPage}, 15 | PageSummary in 'PageSummary.pas' {SummaryPage}, 16 | CompileThread in 'CompileThread.pas', 17 | CompilationData in 'CompilationData.pas', 18 | ScriptPersister in 'ScriptPersister.pas', 19 | gnugettext in 'libs\gnugettext.pas', 20 | Utils in 'Utils.pas', 21 | PackageInfoFactory in 'PackageInfoFactory.pas', 22 | PackageList in 'PackageList.pas', 23 | PackageDependencyVerifier in 'PackageDependencyVerifier.pas', 24 | ProgressMonitor in 'ProgressMonitor.pas', 25 | MonitoredPackageCompiler in 'MonitoredPackageCompiler.pas', 26 | PageCompilerOptions in 'PageCompilerOptions.pas' {SelectCompilerOptions}, 27 | InstalledPackageResolver in 'InstalledPackageResolver.pas', 28 | TreeModel in 'TreeModel.pas', 29 | ListViewModel in 'ListViewModel.pas', 30 | TreeViewModel in 'TreeViewModel.pas', 31 | TreeNodes in 'TreeNodes.pas', 32 | PackageLoadThread in 'PackageLoadThread.pas', 33 | DelphiVersionTreeViewModel in 'DelphiVersionTreeViewModel.pas', 34 | CustomTypes in 'CustomTypes.pas'; 35 | 36 | {$R *.res} 37 | 38 | begin 39 | 40 | Application.Initialize; 41 | Application.MainFormOnTaskbar := True; 42 | Application.Title := 'Delphi Package Installer'; 43 | Application.CreateForm(TfrmWizard, frmWizard); 44 | Application.Run; 45 | end. 46 | -------------------------------------------------------------------------------- /PackageList.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PackageList; 7 | 8 | interface 9 | uses SysUtils, Classes, PackageInfo, Generics.Collections; 10 | type 11 | 12 | TPackageList = class(TList) 13 | private 14 | public 15 | constructor Create; 16 | function IndexOf(const PackageName: String): Integer; overload; 17 | procedure SortList; 18 | end; 19 | implementation 20 | uses Generics.Defaults; 21 | type 22 | 23 | TPackageInfoComparer = class(TInterfacedObject, IComparer) 24 | function Compare(const Left, Right: TPackageInfo): Integer; 25 | end; 26 | 27 | { TPackageList } 28 | 29 | constructor TPackageList.Create; 30 | begin 31 | inherited Create(TPackageInfoComparer.Create); 32 | //OwnsObjects := true; 33 | end; 34 | 35 | function TPackageList.IndexOf(const PackageName: String): Integer; 36 | var 37 | I: Integer; 38 | begin 39 | Result := -1; 40 | for I := 0 to count - 1 do 41 | begin 42 | if UpperCase(Self[i].PackageName) = UpperCase(PackageName) then 43 | exit(i); 44 | end; 45 | end; 46 | 47 | procedure TPackageList.SortList; 48 | var 49 | tmp : TPackageInfo; 50 | i,j: Integer; 51 | packagename: string; 52 | changed : boolean; 53 | begin 54 | changed := true; 55 | while changed do 56 | begin 57 | changed := false; 58 | for i := 0 to Count - 1 do 59 | begin 60 | tmp := Self[i]; 61 | for packagename in tmp.RequiredPackageList do 62 | begin 63 | j := indexOf(packagename); 64 | if (j > i) then 65 | begin 66 | Self.Exchange(i,j); 67 | changed := true; 68 | end; 69 | end; 70 | end; 71 | end; 72 | end; 73 | 74 | { TPackageInfoComparer } 75 | 76 | function TPackageInfoComparer.Compare(const Left, Right: TPackageInfo): Integer; 77 | begin 78 | Result := CompareStr( UpperCase(Left.PackageName), UpperCase(Right.PackageName) ); 79 | end; 80 | 81 | end. 82 | -------------------------------------------------------------------------------- /PackageInfo.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PackageInfo; 7 | interface 8 | uses Classes, StrUtils, TreeModel; 9 | 10 | type 11 | TPackageStatus = (psNone, psCompiling, psInstalling, psSuccess, psError); 12 | TPackageInfo = class 13 | private 14 | fRequiredPackageList: TStringList; 15 | fContainedFileList : TStringList; 16 | FDescription : String; 17 | FSuffix : String; 18 | FRunOnly : Boolean; 19 | FPackageName : String; 20 | fFileName: String; 21 | fStatus: TPackageStatus; 22 | public 23 | constructor Create;overload; 24 | constructor Create(const packageName:string);overload; 25 | destructor Destroy; override; 26 | function DependsOn(const package: TPackageInfo): Boolean; overload; 27 | 28 | property Description: string read FDescription write FDescription; 29 | property PackageName: string read FPackageName write FPackageName; 30 | property RunOnly: Boolean read FRunOnly write FRunOnly; 31 | property Suffix: string read FSuffix write FSuffix; 32 | property RequiredPackageList: TStringList read fRequiredPackageList; 33 | property ContainedFileList: TStringList read fContainedFileList; 34 | property FileName: string read fFileName write fFileName; 35 | property Status: TPackageStatus read fStatus write fStatus; 36 | end; 37 | 38 | implementation 39 | uses SysUtils, contnrs, JclStrings; 40 | 41 | constructor TPackageInfo.Create; 42 | begin 43 | fRequiredPackageList := TStringList.Create; 44 | fContainedFileList := TStringList.Create; 45 | end; 46 | 47 | destructor TPackageInfo.Destroy; 48 | begin 49 | FreeAndNil(fRequiredPackageList); 50 | FreeAndNil(fContainedFileList); 51 | inherited; 52 | end; 53 | 54 | constructor TPackageInfo.Create(const packageName: string); 55 | begin 56 | Create; 57 | FPackageName := packageName; 58 | end; 59 | 60 | function TPackageInfo.DependsOn(const package: TPackageInfo): Boolean; 61 | begin 62 | assert(package <> nil); 63 | Result := RequiredPackageList.IndexOf(package.packageName) > -1; 64 | end; 65 | 66 | 67 | end. 68 | 69 | -------------------------------------------------------------------------------- /FormAbout.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit FormAbout; 7 | 8 | interface 9 | 10 | uses 11 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Vcl.Controls, Forms, 12 | Dialogs, StdCtrls, ExtCtrls; 13 | 14 | type 15 | TfrmAbout = class(TForm) 16 | grpInformation: TGroupBox; 17 | Label7: TLabel; 18 | Image2: TImage; 19 | lblVersion: TLabel; 20 | Label9: TLabel; 21 | Label10: TLabel; 22 | Label11: TLabel; 23 | lblAuthorsWebsite: TLabel; 24 | lblProjectWebsite: TLabel; 25 | Label2: TLabel; 26 | lblAuthor: TLabel; 27 | pnlBottom: TPanel; 28 | btnDonate: TButton; 29 | btnClose: TButton; 30 | Bevel1: TBevel; 31 | procedure btnCloseClick(Sender: TObject); 32 | procedure lblAuthorsWebsiteClick(Sender: TObject); 33 | procedure lblProjectWebsiteClick(Sender: TObject); 34 | procedure FormCreate(Sender: TObject); 35 | procedure btnDonateClick(Sender: TObject); 36 | private 37 | { Private declarations } 38 | public 39 | { Public declarations } 40 | end; 41 | 42 | var 43 | frmAbout: TfrmAbout; 44 | 45 | implementation 46 | uses ShellApi, gnugettext, Utils; 47 | const 48 | donationAddress = 49 | 'https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ibrahim'+ 50 | '%2edursun%40gmail%2ecom&item_name=delphipi&no_shipping=0&no_note=1'+ 51 | '&tax=0¤cy_code=USD&lc=TR&bn=PP%2dDonationsBF&charset=UTF%2d8'; 52 | {$R *.dfm} 53 | 54 | procedure TfrmAbout.btnDonateClick(Sender: TObject); 55 | begin 56 | ShellExecute(0,'open',PWideChar(donationAddress), NIL, NIL, SW_SHOWNORMAL); 57 | end; 58 | 59 | procedure TfrmAbout.btnCloseClick(Sender: TObject); 60 | begin 61 | Close; 62 | end; 63 | 64 | procedure TfrmAbout.FormCreate(Sender: TObject); 65 | begin 66 | TranslateComponent(self); 67 | lblVersion.Caption :=Format('%s ''%s''', [Utils.VERSION, Utils.CODE]); 68 | lblAuthor.Caption := Utils.AUTHOR; 69 | end; 70 | 71 | procedure TfrmAbout.lblAuthorsWebsiteClick(Sender: TObject); 72 | begin 73 | ShellExecute(0,'open',PWideChar(lblAuthorsWebsite.Caption), NIL, NIL, SW_SHOWNORMAL); 74 | end; 75 | 76 | procedure TfrmAbout.lblProjectWebsiteClick(Sender: TObject); 77 | begin 78 | ShellExecute(0,'open',PWideChar(lblProjectWebsite.Caption), NIL, NIL, SW_SHOWNORMAL); 79 | end; 80 | 81 | end. 82 | -------------------------------------------------------------------------------- /DelphiPIProject.groupproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | {23AE099F-B83D-4A21-A920-873D7D98B66A} 4 | 5 | 6 | 7 | 8 | 9 | 10 | DelphiPI.dproj 11 | 12 | 13 | 14 | 15 | 16 | 17 | Default.Personality.12 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /PackageDependencyVerifier.pas: -------------------------------------------------------------------------------- 1 | { ** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | ** } 6 | unit PackageDependencyVerifier; 7 | 8 | interface 9 | 10 | uses Classes, PackageList, PackageInfo, CompilationData, InstalledPackageResolver, Generics.Collections; 11 | 12 | type 13 | TPackageDependencyVerifier = class 14 | private 15 | fMissingPackages: TStringList; 16 | function GetMissingPackage(key: string): String; 17 | public 18 | constructor Create; 19 | destructor Destroy; override; 20 | procedure Verify(const selectedPackages: TList; const installedPackageResolver: TInstalledPackageResolver); virtual; 21 | property MissingPackages[key: string]: String read GetMissingPackage; 22 | end; 23 | 24 | implementation 25 | uses SysUtils, JclFileUtils, gnugettext; 26 | 27 | { TPackageDependencyVerifier } 28 | constructor TPackageDependencyVerifier.Create; 29 | begin 30 | fMissingPackages := TStringList.Create; 31 | end; 32 | 33 | destructor TPackageDependencyVerifier.Destroy; 34 | begin 35 | fMissingPackages.Free; 36 | inherited; 37 | end; 38 | 39 | function TPackageDependencyVerifier.GetMissingPackage(key: string): String; 40 | begin 41 | Result := fMissingPackages.Values[key]; 42 | end; 43 | 44 | procedure TPackageDependencyVerifier.Verify(const selectedPackages: TList; const installedPackageResolver: TInstalledPackageResolver); 45 | var 46 | requiredPackage: string; 47 | i: Integer; 48 | package: TPackageInfo; 49 | allPackages: TStringList; 50 | begin 51 | fMissingPackages.Clear; 52 | allPackages := TStringList.Create; 53 | try 54 | allPackages.AddStrings(installedPackageResolver.InstalledPackages); 55 | for I := 0 to selectedPackages.Count - 1 do 56 | allPackages.Add(UpperCase(selectedPackages[i].PackageName)); 57 | 58 | for i := 0 to selectedPackages.Count - 1 do 59 | begin 60 | package := selectedPackages[i]; 61 | fMissingPackages.Values[package.packageName] := ''; 62 | 63 | for requiredPackage in package.RequiredPackageList do 64 | begin 65 | if fMissingPackages.Values[requiredPackage] <> '' then 66 | fMissingPackages.Values[package.packageName] := Format(_('%s requires %s'), [requiredPackage, fMissingPackages.Values[requiredPackage]]); 67 | 68 | if allPackages.IndexOf(UpperCase(requiredPackage)) = -1 then 69 | fMissingPackages.Values[package.packageName] := requiredPackage; 70 | end; 71 | end; 72 | 73 | finally 74 | allPackages.Free; 75 | end; 76 | end; 77 | 78 | end. 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /PageProgress.dfm: -------------------------------------------------------------------------------- 1 | inherited ProgressPage: TProgressPage 2 | Left = 299 3 | Top = 280 4 | Caption = 'ProgressPage' 5 | ClientHeight = 232 6 | ClientWidth = 412 7 | OnClose = FormClose 8 | OnCreate = FormCreate 9 | ExplicitWidth = 412 10 | ExplicitHeight = 232 11 | PixelsPerInch = 96 12 | TextHeight = 13 13 | object GroupBox1: TGroupBox 14 | AlignWithMargins = True 15 | Left = 3 16 | Top = 3 17 | Width = 406 18 | Height = 68 19 | Align = alTop 20 | Caption = 'Overall Progress' 21 | TabOrder = 0 22 | DesignSize = ( 23 | 406 24 | 68) 25 | object Label1: TLabel 26 | Left = 12 27 | Top = 18 28 | Width = 44 29 | Height = 13 30 | Caption = 'Package:' 31 | end 32 | object lblPackage: TLabel 33 | Left = 62 34 | Top = 18 35 | Width = 61 36 | Height = 13 37 | Caption = 'lblPackage' 38 | Font.Charset = DEFAULT_CHARSET 39 | Font.Color = clWindowText 40 | Font.Height = -11 41 | Font.Name = 'Tahoma' 42 | Font.Style = [fsBold] 43 | ParentFont = False 44 | end 45 | object lblCurrentPackageNo: TLabel 46 | Left = 411 47 | Top = 18 48 | Width = 15 49 | Height = 13 50 | Alignment = taRightJustify 51 | Anchors = [akTop, akRight, akBottom] 52 | Caption = ' ' 53 | ExplicitLeft = 401 54 | end 55 | object ProgressBar: TProgressBar 56 | Left = 12 57 | Top = 37 58 | Width = 381 59 | Height = 20 60 | Anchors = [akLeft, akTop, akRight] 61 | TabOrder = 0 62 | end 63 | object btnCancel: TButton 64 | Left = 432 65 | Top = 37 66 | Width = 59 67 | Height = 20 68 | Anchors = [akTop, akRight] 69 | Caption = 'Cancel' 70 | TabOrder = 1 71 | OnClick = btnCancelClick 72 | end 73 | end 74 | object memo: TRichEdit 75 | AlignWithMargins = True 76 | Left = 3 77 | Top = 77 78 | Width = 406 79 | Height = 129 80 | Align = alClient 81 | Font.Charset = RUSSIAN_CHARSET 82 | Font.Color = clWindowText 83 | Font.Height = -11 84 | Font.Name = 'Courier New' 85 | Font.Style = [] 86 | ParentFont = False 87 | ScrollBars = ssBoth 88 | TabOrder = 1 89 | Zoom = 100 90 | end 91 | object chkShowFullLog: TCheckBox 92 | AlignWithMargins = True 93 | Left = 3 94 | Top = 212 95 | Width = 406 96 | Height = 17 97 | Align = alBottom 98 | Caption = 'Show Full Log' 99 | TabOrder = 2 100 | OnClick = chkShowFullLogClick 101 | end 102 | end 103 | -------------------------------------------------------------------------------- /PageInstallHelpFiles.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PageInstallHelpFiles; 7 | 8 | interface 9 | 10 | uses 11 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Vcl.Controls, Forms, 12 | Dialogs, PageBase, StdCtrls, ComCtrls, WizardIntfs; 13 | 14 | type 15 | TInstallHelpFilesPage = class(TWizardPage) 16 | Label1: TLabel; 17 | helpFileList: TListView; 18 | btnInstallHelpFiles: TButton; 19 | procedure FormCreate(Sender: TObject); 20 | procedure btnInstallHelpFilesClick(Sender: TObject); 21 | private 22 | public 23 | procedure UpdateWizardState; override; 24 | function CanShowPage: Boolean; override; 25 | end; 26 | 27 | var 28 | InstallHelpFilesPage: TInstallHelpFilesPage; 29 | 30 | implementation 31 | {$R *.dfm} 32 | 33 | uses JclFileUtils, JclIDEUtils, gnugettext; 34 | 35 | { TInstallHelpFilesPage } 36 | 37 | function TInstallHelpFilesPage.CanShowPage: Boolean; 38 | begin 39 | Result := fCompilationData.HelpFiles.Count > 0; 40 | end; 41 | 42 | procedure TInstallHelpFilesPage.FormCreate(Sender: TObject); 43 | var 44 | I: Integer; 45 | item: TListItem; 46 | begin 47 | inherited; 48 | if fCompilationData.HelpFiles.Count = 0 then begin 49 | label1.Caption := _('No help files are found.'); 50 | helpFileList.Enabled := false; 51 | btnInstallHelpFiles.Enabled := false; 52 | exit; 53 | end; 54 | 55 | if (fCompilationData.Installation.VersionNumber <= 7) then 56 | for I := 0 to fCompilationData.HelpFiles.Count - 1 do begin 57 | item :=helpFileList.Items.Add; 58 | item.Caption := fCompilationData.HelpFiles[i]; 59 | item.Checked := true; 60 | end; 61 | end; 62 | 63 | procedure TInstallHelpFilesPage.UpdateWizardState; 64 | begin 65 | inherited; 66 | wizard.SetHeader(_('Help Files')); 67 | wizard.SetDescription(_('Select the help files that you want to register, if there are any.')); 68 | with wizard.GetAction(wbtBack) do 69 | Visible := False; 70 | end; 71 | 72 | procedure TInstallHelpFilesPage.btnInstallHelpFilesClick(Sender: TObject); 73 | //var 74 | // openHelp : TJclBorlandOpenHelp; 75 | // helpFileName: string; 76 | // successCount: integer; 77 | begin 78 | inherited; 79 | // successCount := 0; 80 | // if fCompilationData.Installation is TJclBorRADToolInstallation then begin 81 | // openHelp := fCompilationData.Installation.OpenHelp; 82 | // for helpFileName in fCompilationData.HelpFiles do begin 83 | // if openHelp.AddHelpFile(helpFileName,PathExtractFileNameNoExt(helpFileName)) then 84 | // inc(successCount); 85 | // end; 86 | // end; 87 | // ShowMessage(Format(_('%d help file(s) are registered successfully'),[successCount])); 88 | end; 89 | 90 | end. 91 | -------------------------------------------------------------------------------- /PageCompilerOptions.dfm: -------------------------------------------------------------------------------- 1 | inherited SelectCompilerOptions: TSelectCompilerOptions 2 | Left = 290 3 | Top = 283 4 | Caption = 'SelectCompilerOptions' 5 | ClientHeight = 232 6 | ClientWidth = 412 7 | OnClose = FormClose 8 | OnCreate = FormCreate 9 | ExplicitWidth = 412 10 | ExplicitHeight = 232 11 | PixelsPerInch = 96 12 | TextHeight = 13 13 | object grpOutputFolders: TGroupBox 14 | AlignWithMargins = True 15 | Left = 3 16 | Top = 3 17 | Width = 406 18 | Height = 142 19 | Align = alTop 20 | Caption = 'Compiler Options' 21 | TabOrder = 0 22 | DesignSize = ( 23 | 406 24 | 142) 25 | object lblBPLOutputFolder: TLabel 26 | Left = 15 27 | Top = 27 28 | Width = 91 29 | Height = 13 30 | Caption = 'BPL Output Folder:' 31 | end 32 | object lblDCP: TLabel 33 | Left = 15 34 | Top = 56 35 | Width = 94 36 | Height = 13 37 | Caption = 'DCP Output Folder:' 38 | end 39 | object lblDCU: TLabel 40 | Left = 15 41 | Top = 83 42 | Width = 95 43 | Height = 13 44 | Caption = 'DCU Output Folder:' 45 | end 46 | object Label1: TLabel 47 | Left = 15 48 | Top = 110 49 | Width = 95 50 | Height = 13 51 | Caption = 'Compiler Directives:' 52 | end 53 | object edtBPL: TEdit 54 | Left = 116 55 | Top = 24 56 | Width = 277 57 | Height = 21 58 | Anchors = [akLeft, akTop, akRight] 59 | TabOrder = 0 60 | end 61 | object btnBPLBrowse: TButton 62 | Left = 446 63 | Top = 22 64 | Width = 28 65 | Height = 25 66 | Anchors = [akTop, akRight] 67 | Caption = '...' 68 | TabOrder = 1 69 | OnClick = btnBPLBrowseClick 70 | end 71 | object edtDCP: TEdit 72 | Left = 116 73 | Top = 53 74 | Width = 277 75 | Height = 21 76 | Anchors = [akLeft, akTop, akRight] 77 | TabOrder = 2 78 | end 79 | object btnDCPBrowse: TButton 80 | Left = 446 81 | Top = 51 82 | Width = 28 83 | Height = 25 84 | Anchors = [akTop, akRight] 85 | Caption = '...' 86 | TabOrder = 3 87 | OnClick = btnDCPBrowseClick 88 | end 89 | object edtDCU: TEdit 90 | Left = 116 91 | Top = 80 92 | Width = 277 93 | Height = 21 94 | Anchors = [akLeft, akTop, akRight] 95 | TabOrder = 4 96 | end 97 | object btnDCUBrowse: TButton 98 | Left = 446 99 | Top = 78 100 | Width = 28 101 | Height = 25 102 | Anchors = [akTop, akRight] 103 | Caption = '...' 104 | TabOrder = 5 105 | OnClick = btnDCUBrowseClick 106 | end 107 | object edtConditionals: TEdit 108 | Left = 116 109 | Top = 107 110 | Width = 277 111 | Height = 21 112 | Anchors = [akLeft, akTop, akRight] 113 | TabOrder = 6 114 | end 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /TreeNodes.pas: -------------------------------------------------------------------------------- 1 | { ** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | ** } 6 | unit TreeNodes; 7 | interface 8 | uses treemodel, packageinfo, Generics.Defaults; 9 | type 10 | TNodeType = (ntNode, ntFolder, ntPackage); 11 | TTreeNode = class(TInterfacedObject, INode) 12 | private 13 | fName: string; 14 | fPath: string; 15 | fSelected: boolean; 16 | fNodeType: TNodeType; 17 | public 18 | constructor Create(const name, path: string); 19 | function GetData: TObject; virtual; 20 | function GetDisplayName: string; virtual; 21 | function GetNodePath: string; virtual; 22 | property NodeType: TNodeType read fNodeType; 23 | property Selected: boolean read fSelected write fSelected; 24 | end; 25 | 26 | TPackageTreeNode = class(TTreeNode) 27 | private 28 | fInfo: TPackageInfo; 29 | fMissingPackageName: string; 30 | public 31 | constructor Create(const info: TPackageInfo); virtual; 32 | 33 | function GetData: TObject; override; 34 | function GetDisplayName: string; override; 35 | function GetNodePath: string; override; 36 | function ToString: string; override; 37 | property MissingPackageName: string read fMissingPackageName write fMissingPackageName; 38 | end; 39 | 40 | TTreeNodeComparer = class(TInterfacedObject, IComparer) 41 | function Compare(const Left, Right: TTreeNode): Integer; 42 | end; 43 | 44 | 45 | implementation 46 | uses JclStrings; 47 | constructor TTreeNode.Create(const name, path: string); 48 | begin 49 | fName := name; 50 | fPath := path; 51 | fNodeType := ntFolder; 52 | fSelected := true; 53 | end; 54 | 55 | function TTreeNode.GetData: TObject; 56 | begin 57 | Result := nil; 58 | end; 59 | 60 | function TTreeNode.GetDisplayName: string; 61 | begin 62 | Result := fName; 63 | end; 64 | 65 | function TTreeNode.GetNodePath: string; 66 | begin 67 | Result := fPath; 68 | end; 69 | 70 | constructor TPackageTreeNode.Create(const info: TPackageInfo); 71 | begin 72 | fInfo := info; 73 | fNodeType := ntPackage; 74 | fSelected := true; 75 | end; 76 | 77 | function TPackageTreeNode.GetData: TObject; 78 | begin 79 | Result := fInfo; 80 | end; 81 | 82 | function TPackageTreeNode.GetDisplayName: string; 83 | begin 84 | Result := fInfo.PackageName; 85 | end; 86 | 87 | function TPackageTreeNode.GetNodePath: string; 88 | var 89 | i: integer; 90 | begin 91 | Result := fInfo.FileName; 92 | i := Pos(':', Result); 93 | if i <> 0 then 94 | Result := StrRestOf(Result, i + 2); 95 | end; 96 | 97 | function TPackageTreeNode.ToString: string; 98 | begin 99 | Result := fInfo.FileName; 100 | end; 101 | 102 | { TTreeNodeComparer } 103 | 104 | function TTreeNodeComparer.Compare(const Left, Right: TTreeNode): Integer; 105 | begin 106 | Result := StrCompare(Left.GetNodePath, Right.GetNodePath, true); 107 | end; 108 | 109 | end. 110 | -------------------------------------------------------------------------------- /PageSelectFolders.dfm: -------------------------------------------------------------------------------- 1 | inherited SelectFoldersPage: TSelectFoldersPage 2 | Left = 346 3 | Top = 221 4 | ActiveControl = edtBaseFolder 5 | Caption = 'SelectFoldersPage' 6 | ClientHeight = 232 7 | ClientWidth = 412 8 | OnClose = FormClose 9 | OnCreate = FormCreate 10 | PixelsPerInch = 96 11 | TextHeight = 13 12 | object grpPackagePattern: TGroupBox 13 | AlignWithMargins = True 14 | Left = 3 15 | Top = 134 16 | Width = 406 17 | Height = 79 18 | Align = alTop 19 | Caption = 'Pattern to select package files ' 20 | TabOrder = 2 21 | DesignSize = ( 22 | 406 23 | 79) 24 | object Label3: TLabel 25 | Left = 12 26 | Top = 51 27 | Width = 98 28 | Height = 13 29 | Caption = 'Package File Pattern' 30 | end 31 | object Label2: TLabel 32 | Left = 12 33 | Top = 16 34 | Width = 381 35 | Height = 26 36 | Anchors = [akLeft, akTop, akRight] 37 | Caption = 38 | 'Specify a pattern that matches for the package files that are su' + 39 | 'itable for your delphi installation. ie: *d7.dpk for Delphi 7' 40 | WordWrap = True 41 | end 42 | object cbPattern: TComboBox 43 | Left = 116 44 | Top = 48 45 | Width = 277 46 | Height = 21 47 | Anchors = [akLeft, akTop, akRight] 48 | TabOrder = 0 49 | Text = '*.dpk' 50 | end 51 | end 52 | object grpBaseFolder: TGroupBox 53 | AlignWithMargins = True 54 | Left = 3 55 | Top = 3 56 | Width = 406 57 | Height = 65 58 | Align = alTop 59 | Caption = 'Select Base Folder contains both Package and Source files' 60 | TabOrder = 0 61 | DesignSize = ( 62 | 406 63 | 65) 64 | object Label1: TLabel 65 | Left = 12 66 | Top = 16 67 | Width = 56 68 | Height = 13 69 | Caption = 'Base Folder' 70 | end 71 | object btnSelectFolder: TButton 72 | Left = 560 73 | Top = 35 74 | Width = 32 75 | Height = 21 76 | Anchors = [akTop, akRight] 77 | Caption = '...' 78 | TabOrder = 0 79 | WordWrap = True 80 | OnClick = btnSelectFolderClick 81 | end 82 | object edtBaseFolder: TEdit 83 | Left = 12 84 | Top = 35 85 | Width = 381 86 | Height = 21 87 | Anchors = [akLeft, akTop, akRight] 88 | TabOrder = 1 89 | OnChange = edtBaseFolderChange 90 | end 91 | end 92 | object grpDelphiVersion: TGroupBox 93 | AlignWithMargins = True 94 | Left = 3 95 | Top = 74 96 | Width = 406 97 | Height = 54 98 | Align = alTop 99 | Caption = 'Installed Delphi Versions' 100 | TabOrder = 1 101 | DesignSize = ( 102 | 406 103 | 54) 104 | object cbDelphiVersions: TComboBox 105 | Left = 12 106 | Top = 20 107 | Width = 381 108 | Height = 21 109 | Style = csDropDownList 110 | Anchors = [akLeft, akTop, akRight] 111 | TabOrder = 0 112 | OnChange = cbDelphiVersionsChange 113 | end 114 | end 115 | end 116 | -------------------------------------------------------------------------------- /PackageLoadThread.pas: -------------------------------------------------------------------------------- 1 | { ** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | ** } 6 | unit PackageLoadThread; 7 | 8 | interface 9 | uses Classes, SysUtils, Generics.Collections, PackageInfo, TreeNodes, PackageInfoFactory; 10 | type 11 | TPackageLoadThread = class(TThread) 12 | private 13 | fPackageInfoFactory: TPackageInfoFactory; 14 | fActive: Boolean; 15 | fList: TList; 16 | fDirectory: string; 17 | fPattern: string; 18 | procedure LoadPackageInformations(const directory: string); 19 | protected 20 | procedure Execute; override; 21 | procedure Search(const folder: String); 22 | public 23 | constructor Create(directory: string; pattern: string; list: TList); 24 | destructor Destroy; override; 25 | property Active: Boolean read fActive write fActive; 26 | end; 27 | 28 | implementation 29 | uses Dialogs, JclFileUtils; 30 | { TPackageLoadThread } 31 | 32 | constructor TPackageLoadThread.Create(directory: string; pattern: string; list: TList); 33 | begin 34 | inherited Create(true); 35 | Assert(Assigned(list), 'List cannot be null'); 36 | 37 | fList := list; 38 | fPackageInfoFactory := TPackageInfoFactory.Create; 39 | fDirectory := directory; 40 | fPattern := pattern; 41 | end; 42 | 43 | destructor TPackageLoadThread.Destroy; 44 | begin 45 | fPackageInfoFactory.Free; 46 | inherited; 47 | end; 48 | 49 | procedure TPackageLoadThread.Execute; 50 | begin 51 | inherited; 52 | fActive := true; 53 | try 54 | try 55 | Search(fDirectory); 56 | except 57 | on e: Exception do 58 | ShowMessage(e.Message); 59 | end; 60 | finally 61 | fActive := false; 62 | end; 63 | end; 64 | 65 | procedure TPackageLoadThread.LoadPackageInformations(const directory: string); 66 | var 67 | sr: TSearchRec; 68 | packageNode: TPackageTreeNode; 69 | begin 70 | if FindFirst(PathAppend(directory, fPattern), faAnyFile, sr) = 0 then 71 | begin 72 | try 73 | repeat 74 | if UpperCase(ExtractFileExt(sr.Name)) = '.DPK' then 75 | begin 76 | packageNode := TPackageTreeNode.Create(fPackageInfoFactory.CreatePackageInfo(PathAppend(directory, sr.Name))); 77 | if not fList.Contains(packageNode) then 78 | fList.Add(packageNode); 79 | end; 80 | until (FindNext(sr) <> 0) and Active; 81 | finally 82 | FindClose(sr); 83 | end; 84 | end; 85 | end; 86 | 87 | procedure TPackageLoadThread.Search(const folder: String); 88 | var 89 | directoryList: TStringList; 90 | directory, dir: string; 91 | begin 92 | directoryList := TStringList.Create; 93 | try 94 | BuildFileList(PathAppend(folder, '*.*'), faAnyFile, directoryList); 95 | for directory in directoryList do 96 | begin 97 | if not Active then 98 | Break; 99 | dir := PathAppend(folder, directory); 100 | if IsDirectory(dir) then 101 | Search(dir); 102 | end; 103 | LoadPackageInformations(folder); 104 | finally 105 | directoryList.Free; 106 | end; 107 | end; 108 | 109 | 110 | end. 111 | -------------------------------------------------------------------------------- /Test/TestPackageList.pas: -------------------------------------------------------------------------------- 1 | unit TestPackageList; 2 | interface 3 | 4 | uses 5 | TestFramework, Classes, StrUtils, PackageInfo, PackageList; 6 | 7 | type 8 | TestTPackageList = class(TTestCase) 9 | strict private 10 | package1, package2, package3: TPackageInfo; 11 | FPackageList: TPackageList; 12 | procedure EstablishContext; 13 | public 14 | procedure SetUp; override; 15 | procedure TearDown; override; 16 | 17 | published 18 | procedure When_list_is_cleared; 19 | procedure When_a_package_is_added; 20 | procedure When_a_package_is_removed; 21 | procedure When_a_package_is_searched; 22 | end; 23 | 24 | implementation 25 | 26 | procedure TestTPackageList.SetUp; 27 | begin 28 | FPackageList := TPackageList.Create; 29 | EstablishContext; 30 | end; 31 | 32 | 33 | procedure TestTPackageList.EstablishContext; 34 | begin 35 | package1 := TPackageInfo.Create('package1'); 36 | package2 := TPackageInfo.Create('package2'); 37 | package3 := TPackageInfo.Create('package3'); 38 | 39 | FPackageList.Add(package1); 40 | FPackageList.Add(package2); 41 | FPackageList.Add(package3); 42 | end; 43 | 44 | procedure TestTPackageList.TearDown; 45 | begin 46 | FPackageList.Free; 47 | FPackageList := nil; 48 | end; 49 | 50 | procedure TestTPackageList.When_list_is_cleared; 51 | begin 52 | FPackageList.Clear; 53 | CheckEquals(0, FPackageList.Count, 'list count should be 0'); 54 | end; 55 | 56 | procedure TestTPackageList.When_a_package_is_added; 57 | var 58 | item: TPackageInfo; 59 | oldCount: Integer; 60 | begin 61 | item := TPackageInfo.Create; 62 | item.PackageName := 'added package'; 63 | oldCount := FPackageList.Count; 64 | 65 | FPackageList.Add(item); 66 | 67 | CheckNotEquals(-1, FPackageList.IndexOf('added package'), 'should find in the list'); 68 | CheckEquals(oldCount + 1, FPackageList.Count,'list count should increase by 1'); 69 | end; 70 | 71 | procedure TestTPackageList.When_a_package_is_removed; 72 | var 73 | item: TPackageInfo; 74 | oldCount: integer; 75 | begin 76 | item := package2; 77 | oldCount := FPackageList.Count; 78 | FPackageList.Remove(item); 79 | 80 | CheckEquals(oldCount-1, FPackageList.Count, 'list count should decrease by 1'); 81 | CheckEquals(-1, FPackageList.IndexOf(item.PackageName), 'it should not be in the list'); 82 | end; 83 | 84 | procedure TestTPackageList.When_a_package_is_searched; 85 | var 86 | ReturnValue: Integer; 87 | PackageName: string; 88 | begin 89 | PackageName := 'package2'; 90 | ReturnValue := FPackageList.IndexOf(PackageName); 91 | CheckEquals(1, ReturnValue,'should return index of searched package'); 92 | 93 | PackageName := 'PackAge2'; 94 | ReturnValue := FPackageList.IndexOf(PackageName); 95 | CheckEquals(1, ReturnValue,'should perform case insensitive search'); 96 | 97 | PackageName := 'missing package'; 98 | ReturnValue := FPackageList.IndexOf(PackageName); 99 | CheckEquals(-1, ReturnValue, 'should return -1 if package is not found'); 100 | end; 101 | 102 | initialization 103 | RegisterTest(TestTPackageList.Suite); 104 | end. 105 | 106 | -------------------------------------------------------------------------------- /ConsoleProgressMonitor.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit ConsoleProgressMonitor; 7 | 8 | interface 9 | uses PackageInfo, ProgressMonitor; 10 | type 11 | TConsoleOutputLevel = (colSilent, colBrief, colFull); 12 | TConsoleProgressMonitor = class(TInterfacedObject, IProgressMonitor) 13 | private 14 | fOutputLevel: TConsoleOutputLevel; 15 | fStartTime: TDateTime; 16 | published 17 | public 18 | procedure CompilerOutput(const line: string); 19 | procedure Finished; 20 | procedure Log(const text: string); 21 | procedure PackageProcessed(const packageInfo: TPackageInfo; 22 | status: TPackageStatus); 23 | procedure Started; 24 | property OutputLevel: TConsoleOutputLevel read fOutputLevel write fOutputLevel; 25 | 26 | end; 27 | 28 | implementation 29 | uses DateUtils, SysUtils, StrUtils, JclConsole; 30 | 31 | procedure WriteLine(color: TJclScreenFontColor; text: string); overload; 32 | begin 33 | TJclConsole.Default.ActiveScreen.Writeln(text, TJclScreenTextAttribute.Create(color,bclBlack, color <> fclWhite)); 34 | end; 35 | 36 | procedure WriteLine(text: string=''); overload; 37 | begin 38 | TJclConsole.Default.ActiveScreen.Writeln(text, TJclScreenTextAttribute.Create(fclWhite, bclBlack, false)); 39 | end; 40 | 41 | { TConsoleProgressMonitor } 42 | 43 | procedure TConsoleProgressMonitor.CompilerOutput(const line: string); 44 | begin 45 | if length(line) > 256 then exit; //throws system error 87 46 | 47 | if OutputLevel = colSilent then exit; 48 | if OutputLevel = TConsoleOutputLevel.colFull then 49 | WriteLn(line) 50 | else if (Pos('Fatal:', line) > 0) or (Pos('Error', line) > 0) then 51 | WriteLine(fclRed,line); 52 | end; 53 | 54 | procedure TConsoleProgressMonitor.Finished; 55 | begin 56 | if OutputLevel = TConsoleOutputLevel.colSilent then 57 | exit; 58 | 59 | WriteLine(fclWhite, 'Completed in ' + floattostr(MilliSecondsBetween(GetTime, fStartTime)) + ' ms'); 60 | end; 61 | 62 | procedure TConsoleProgressMonitor.Log(const text: string); 63 | begin 64 | 65 | if OutputLevel = TConsoleOutputLevel.colFull then 66 | begin 67 | if StartsStr('-=', text) then 68 | WriteLine(fclYellow, text) 69 | else 70 | WriteLine(text); 71 | end; 72 | end; 73 | 74 | procedure TConsoleProgressMonitor.PackageProcessed( 75 | const packageInfo: TPackageInfo; status: TPackageStatus); 76 | begin 77 | if OutputLevel = TConsoleOutputLevel.colSilent then 78 | exit; 79 | case status of 80 | psNone: ; 81 | psCompiling: 82 | WriteLine('[Compile] ' + packageInfo.PackageName); 83 | psInstalling: 84 | WriteLine('[Install] ' + packageInfo.PackageName); 85 | psSuccess: begin 86 | WriteLine(fclGreen, '[Success] ' + packageInfo.PackageName); 87 | WriteLine; 88 | end; 89 | psError: begin 90 | WriteLine(fclRed, '[Fail ] ' + packageInfo.PackageName); 91 | WriteLine; 92 | end; 93 | end; 94 | end; 95 | 96 | procedure TConsoleProgressMonitor.Started; 97 | begin 98 | if OutputLevel = TConsoleOutputLevel.colSilent then 99 | exit; 100 | WriteLine('Starting'); 101 | fStartTime := GetTime; 102 | end; 103 | 104 | 105 | end. 106 | -------------------------------------------------------------------------------- /MonitoredPackageCompiler.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit MonitoredPackageCompiler; 7 | 8 | interface 9 | uses progressmonitor, packagecompiler, packageinfo, CompilationData; 10 | 11 | type 12 | TPackageCompileEvent = procedure(const package: TPackageInfo; status: TPackageStatus) of object; 13 | TMonitoredPackageCompiler = class(TPackageCompiler) 14 | private 15 | fMonitor: IProgressMonitor; 16 | protected 17 | procedure RaiseEvent(const packageInfo: TPackageInfo; status: TPackageStatus);virtual; 18 | procedure PrepareExtraOptions; override; 19 | 20 | public 21 | constructor Create(const compilationData: TCompilationData; const aMonitor: IProgressMonitor); reintroduce; 22 | procedure ResolveSourcePaths; override; 23 | procedure CompilerOutputCallback(const line:string); virtual; 24 | function CompilePackage(const packageInfo: TPackageInfo): boolean; override; 25 | function InstallPackage(const packageInfo: TPackageInfo): boolean; override; 26 | procedure Compile; override; 27 | end; 28 | 29 | implementation 30 | uses Classes; 31 | constructor TMonitoredPackageCompiler.Create(const compilationData:TCompilationData; const aMonitor: IProgressMonitor); 32 | begin 33 | Assert(aMonitor <> nil,'monitor cannot be null'); { TODO -oidursun -c : a default null implementation can be set } 34 | inherited Create(compilationData); 35 | fMonitor := aMonitor; 36 | end; 37 | 38 | procedure TMonitoredPackageCompiler.Compile; 39 | begin 40 | Installation.DCC32.OutputCallback := CompilerOutputCallback; 41 | fMonitor.Started; 42 | fMonitor.Log('-=Started'); 43 | inherited; 44 | fMonitor.Finished; 45 | fMonitor.Log('-=Finished'); 46 | end; 47 | 48 | function TMonitoredPackageCompiler.CompilePackage( 49 | const packageInfo: TPackageInfo): boolean; 50 | begin 51 | fMonitor.Log('-=Compiling: ' + packageInfo.PackageName); 52 | fMonitor.Log('Required :'+packageInfo.RequiredPackageList.DelimitedText); 53 | fMonitor.Log('Contains :'+packageInfo.ContainedFileList.DelimitedText); 54 | 55 | RaiseEvent(packageInfo, psCompiling); 56 | Result := inherited CompilePackage(packageInfo); 57 | if not Result then 58 | RaiseEvent(packageInfo, psError) 59 | else 60 | RaiseEvent(packageInfo, psSuccess); 61 | fMonitor.Log('Finished'); 62 | end; 63 | 64 | procedure TMonitoredPackageCompiler.CompilerOutputCallback(const line: string); 65 | begin 66 | fMonitor.CompilerOutput(line); 67 | end; 68 | 69 | function TMonitoredPackageCompiler.InstallPackage( 70 | const packageInfo: TPackageInfo): boolean; 71 | begin 72 | Result := inherited InstallPackage(packageInfo); 73 | end; 74 | 75 | procedure TMonitoredPackageCompiler.PrepareExtraOptions; 76 | var 77 | line: string; 78 | begin 79 | inherited; 80 | fMonitor.Log('-=All Path:'); 81 | for line in AllPaths do 82 | fMonitor.Log(line); 83 | 84 | fMonitor.Log('-=Compiler Options:'); 85 | fMonitor.Log(fExtraOptions); 86 | end; 87 | 88 | procedure TMonitoredPackageCompiler.RaiseEvent(const packageInfo: TPackageInfo; 89 | status: TPackageStatus); 90 | begin 91 | fMonitor.PackageProcessed(packageInfo, status); 92 | if (status = psSuccess) or (status = psError) then 93 | packageInfo.Status := status; 94 | end; 95 | 96 | procedure TMonitoredPackageCompiler.ResolveSourcePaths; 97 | var 98 | path: string; 99 | begin 100 | inherited; 101 | fMonitor.Log('-=Source Paths:'); 102 | for path in SourceFilePaths do 103 | fMonitor.Log(path); 104 | end; 105 | 106 | end. 107 | -------------------------------------------------------------------------------- /CompileThread.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit CompileThread; 7 | interface 8 | uses ProgressMonitor, PackageInfo, MonitoredPackageCompiler, Classes, JclIDEUtils, CompilationData; 9 | 10 | type 11 | TCompileThread = class(TThread, IProgressMonitor) 12 | private 13 | FRefCount : integer; 14 | fMonitor : IProgressMonitor; 15 | fCompilationData: TCompilationData; 16 | fCancel: boolean; 17 | fCompiler: TMonitoredPackageCompiler; 18 | procedure SetMonitor(const Value: IProgressMonitor); 19 | procedure SetCancel(const Value: boolean); 20 | protected 21 | procedure Execute; override; 22 | public 23 | constructor Create(const compilationData: TCompilationData); 24 | function _AddRef: Integer; stdcall; 25 | function _Release: Integer; stdcall; 26 | function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall; 27 | procedure CompilerOutput(const line: string); 28 | procedure Finished; 29 | procedure Log(const text: string); 30 | procedure PackageProcessed(const packageInfo: TPackageInfo; 31 | status: TPackageStatus); 32 | procedure Started; 33 | 34 | property Monitor: IProgressMonitor read FMonitor write SetMonitor; 35 | property Cancel: boolean read fCancel write SetCancel; 36 | end; 37 | 38 | implementation 39 | 40 | constructor TCompileThread.Create(const compilationData: TCompilationData); 41 | begin 42 | inherited Create(true); 43 | Assert(compilationData <> nil); 44 | fCompilationData := compilationData; 45 | end; 46 | 47 | procedure TCompileThread.Execute; 48 | begin 49 | inherited; 50 | fCompiler := TMonitoredPackageCompiler.Create(fCompilationData, Self); 51 | try 52 | fCompiler.Compile; 53 | finally 54 | fCompiler.Free; 55 | end; 56 | end; 57 | 58 | procedure TCompileThread.Log(const text: string); 59 | begin 60 | Synchronize(procedure 61 | begin 62 | Monitor.Log(text); 63 | end); 64 | end; 65 | 66 | procedure TCompileThread.CompilerOutput(const line: string); 67 | begin 68 | Synchronize(procedure 69 | begin 70 | Monitor.CompilerOutput(line); 71 | end); 72 | end; 73 | 74 | procedure TCompileThread.Finished; 75 | begin 76 | Synchronize(procedure 77 | begin 78 | Monitor.Finished; 79 | end); 80 | end; 81 | 82 | procedure TCompileThread.PackageProcessed(const packageInfo: TPackageInfo; 83 | status: TPackageStatus); 84 | begin 85 | Synchronize(procedure 86 | begin 87 | Monitor.PackageProcessed(packageInfo, status); 88 | end); 89 | end; 90 | 91 | procedure TCompileThread.Started; 92 | begin 93 | Synchronize(procedure 94 | begin 95 | Monitor.Started; 96 | end); 97 | end; 98 | 99 | procedure TCompileThread.SetCancel(const Value: boolean); 100 | begin 101 | fCancel := Value; 102 | if fCompiler <> nil then 103 | fCompiler.Cancel := true; 104 | end; 105 | 106 | procedure TCompileThread.SetMonitor(const Value: IProgressMonitor); 107 | begin 108 | FMonitor := Value; 109 | end; 110 | 111 | function TCompileThread.QueryInterface(const IID: TGUID; out Obj): HRESULT; 112 | begin 113 | if GetInterface(IID, Obj) then 114 | Result := 0 115 | else 116 | Result := E_NOINTERFACE; 117 | end; 118 | 119 | function TCompileThread._AddRef: Integer; 120 | begin 121 | Inc(FRefCount); 122 | Result := FRefCount; 123 | end; 124 | 125 | function TCompileThread._Release: Integer; 126 | begin 127 | Dec(FRefCount); 128 | Result := FRefCount; 129 | if Result = 0 then 130 | Destroy; 131 | end; 132 | 133 | end. 134 | -------------------------------------------------------------------------------- /ConsoleRunner.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit ConsoleRunner; 7 | 8 | interface 9 | uses Classes, PackageInfo, CompilationData, ConsoleProgressMonitor; 10 | type 11 | 12 | TConsoleRunner = class 13 | private 14 | fCompilationData: TCompilationData; 15 | fMonitor: TConsoleProgressMonitor; 16 | fOutputLevel: TConsoleOutputLevel; 17 | fScriptFile: String; 18 | procedure DisplayHelp; 19 | protected 20 | procedure DisplayHeader; virtual; 21 | procedure ParseArguments;virtual; 22 | public 23 | procedure Run; 24 | property OutputLevel: TConsoleOutputLevel read fOutputLevel; 25 | end; 26 | 27 | implementation 28 | 29 | uses SysUtils, gnugettext, MonitoredPackageCompiler, ScriptPersister, PackageCompiler, 30 | Utils, JclConsole, StrUtils; 31 | 32 | procedure WriteLine(color: TJclScreenFontColor; text: string); 33 | begin 34 | TJclConsole.Default.ActiveScreen.Writeln(text, TJclScreenTextAttribute.Create(color)); 35 | end; 36 | 37 | { TConsoleRunner } 38 | 39 | //TODO Refactor this 40 | procedure TConsoleRunner.Run; 41 | var 42 | scripter : TScriptPersister; 43 | packageCompiler: TMonitoredPackageCompiler; 44 | begin 45 | DisplayHeader; 46 | try 47 | ParseArguments; 48 | except 49 | on ex : Exception do begin 50 | WriteLine(fclRed, ex.Message); 51 | DisplayHelp; 52 | exit; 53 | end; 54 | end; 55 | 56 | scripter := TScriptPersister.Create; 57 | try 58 | fCompilationData := scripter.Load(fScriptFile); 59 | fMonitor := TConsoleProgressMonitor.Create; 60 | fMonitor.OutputLevel := Self.OutputLevel; 61 | finally 62 | scripter.Free; 63 | end; 64 | 65 | packageCompiler := TMonitoredPackageCompiler.Create(fCompilationData, fMonitor); 66 | try 67 | packageCompiler.Compile; 68 | finally 69 | packageCompiler.Free; 70 | end; 71 | end; 72 | 73 | procedure TConsoleRunner.DisplayHeader; 74 | begin 75 | WriteLine(fclWhite, 'DelphiPI Console ' + Utils.VERSION); 76 | WriteLine(fclWhite, 'By ' + Utils.AUTHOR); 77 | end; 78 | 79 | procedure TConsoleRunner.DisplayHelp; 80 | begin 81 | WriteLine(fclWhite, 'Usage:'); 82 | WriteLine(fclWhite, 'DelphiPIConsole.exe [ScriptFile] [OutputLevel]'); 83 | WriteLine(fclWhite, 'ScriptFile : script file saved by the DelphiPI which contains necessary information about compilation'); 84 | WriteLine(fclWhite, 'OutputLevel: during compilation how much info should be displayed'); 85 | WriteLine(fclWhite, #9'0 means silent'); 86 | WriteLine(fclWhite, #9'1 means brief'); 87 | WriteLine(fclWhite, #9'2 means full'); 88 | end; 89 | 90 | 91 | procedure TConsoleRunner.ParseArguments; 92 | var 93 | i:integer; 94 | param: string; 95 | begin 96 | fOutputLevel := TConsoleOutputLevel.colBrief; 97 | 98 | if ParamCount = 0 then 99 | raise Exception.Create('Requires Script File.'); 100 | 101 | fScriptFile := ParamStr(1); 102 | 103 | if not FileExists(fScriptFile) then 104 | raise Exception.Create('File does not exist: ' + fScriptFile); 105 | 106 | i := 2; 107 | 108 | while i < ParamCount do 109 | begin 110 | param := UpperCase(ParamStr(i)); 111 | // Logging level 112 | // if param = '-L' then 113 | // begin 114 | // i := i+1; 115 | // param := UpperCase(ParamStr(i)); 116 | if (param = '0') or (param = 'SILENT') then 117 | fOutputLevel := TConsoleOutputLevel.colSilent 118 | else if (param='1') or (param = 'BRIEF') then 119 | fOutputLevel := TConsoleOutputLevel.colBrief 120 | else if (param='2') or (param = 'FULL') then 121 | fOutputLevel := TConsoleOutputLevel.colFull 122 | else 123 | raise Exception.Create(param + ' is not a valid value for OutputLogLevel'); 124 | end; 125 | // 126 | // end; 127 | end; 128 | 129 | end. 130 | -------------------------------------------------------------------------------- /Test/TestDelphiVersionTreeViewModel.pas: -------------------------------------------------------------------------------- 1 | unit TestDelphiVersionTreeViewModel; 2 | interface 3 | 4 | uses 5 | TestFramework, TreeModel, Utils, Generics.Collections, Classes, 6 | DelphiVersionTreeViewModel, SysUtils; 7 | 8 | type 9 | 10 | TBasicNode = class(TInterfacedObject, INode) 11 | private 12 | fPath: string; 13 | public 14 | constructor Create(const path: string); 15 | function GetDisplayName: string; 16 | function GetData: TObject; 17 | function GetNodePath: string; 18 | end; 19 | 20 | TestTDelphiVersionTreeViewModel = class(TTestCase) 21 | strict private 22 | fModel: TDelphiVersionTreeViewModel; 23 | fNodes: TObjectList; 24 | private 25 | public 26 | procedure SetUp; override; 27 | procedure TearDown; override; 28 | published 29 | procedure Should_return_only_recognized_delphi_version_count; 30 | procedure Should_return_nodes_under_specified_delphi_version; 31 | procedure Should_return_node_at_1_for_Delphi_7; 32 | procedure Should_return_node_at_1_for_Delphi_2009; 33 | end; 34 | 35 | implementation 36 | 37 | procedure TestTDelphiVersionTreeViewModel.SetUp; 38 | begin 39 | fNodes := TObjectList.Create; 40 | fModel := TDelphiVersionTreeViewModel.Create(fNodes); 41 | end; 42 | 43 | procedure TestTDelphiVersionTreeViewModel.TearDown; 44 | begin 45 | fModel.Free; 46 | fModel := nil; 47 | fNodes.Free; 48 | end; 49 | 50 | procedure TestTDelphiVersionTreeViewModel.Should_return_only_recognized_delphi_version_count; 51 | var 52 | actual : integer; 53 | begin 54 | fNodes.Add(TBasicNode.Create('p70')); 55 | fNodes.Add(TBasicNode.Create('D70')); 56 | fNodes.Add(TBasicNode.Create('G70')); 57 | fNodes.Add(TBasicNode.Create('p60')); 58 | actual := fModel.GetChildCount(nil); 59 | CheckEquals(2,actual, 'Delphi version count was wrong'); 60 | end; 61 | 62 | procedure TestTDelphiVersionTreeViewModel.Should_return_nodes_under_specified_delphi_version; 63 | var 64 | actual : integer; 65 | begin 66 | fNodes.Add(TBasicNode.Create('p70')); 67 | fNodes.Add(TBasicNode.Create('D70')); 68 | fNodes.Add(TBasicNode.Create('G70')); 69 | fNodes.Add(TBasicNode.Create('p60')); 70 | actual := fModel.GetChildCount(TBasicNode.Create('Delphi 7')); 71 | CheckEquals(3,actual, 'package count of Delphi 7 was wrong'); 72 | end; 73 | 74 | procedure TestTDelphiVersionTreeViewModel.Should_return_node_at_1_for_Delphi_7; 75 | var 76 | actual : TBasicNode; 77 | begin 78 | fNodes.Add(TBasicNode.Create('p70')); 79 | fNodes.Add(TBasicNode.Create('D70')); 80 | fNodes.Add(TBasicNode.Create('G70')); 81 | fNodes.Add(TBasicNode.Create('p60')); 82 | actual := fModel.GetChild(TBasicNode.Create('Delphi 7'), 1); 83 | CheckEquals('D70',actual.GetDisplayName, 'returned package was wrong'); 84 | end; 85 | 86 | procedure TestTDelphiVersionTreeViewModel.Should_return_node_at_1_for_Delphi_2009; 87 | var 88 | actual : TBasicNode; 89 | begin 90 | fNodes.Add(TBasicNode.Create('p70')); 91 | fNodes.Add(TBasicNode.Create('D70')); 92 | fNodes.Add(TBasicNode.Create('pd12')); 93 | fNodes.Add(TBasicNode.Create('p12')); 94 | fNodes.Add(TBasicNode.Create('p_12')); 95 | actual := fModel.GetChild(TBasicNode.Create('Delphi 2009'), 1); 96 | CheckEquals('p12',actual.GetDisplayName, 'returned package was wrong'); 97 | end; 98 | 99 | 100 | { TBasicNode } 101 | 102 | constructor TBasicNode.Create(const path: string); 103 | begin 104 | fPath := path; 105 | end; 106 | 107 | function TBasicNode.GetData: TObject; 108 | begin 109 | Result := nil; 110 | end; 111 | 112 | function TBasicNode.GetDisplayName: string; 113 | begin 114 | Result := fPath; 115 | end; 116 | 117 | function TBasicNode.GetNodePath: string; 118 | begin 119 | Result := fPath; 120 | end; 121 | 122 | initialization 123 | // Register any test cases with the test runner 124 | RegisterTest(TestTDelphiVersionTreeViewModel.Suite); 125 | end. 126 | 127 | -------------------------------------------------------------------------------- /PackageInfoFactory.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PackageInfoFactory; 7 | 8 | interface 9 | 10 | uses SysUtils, StrUtils, Classes, PackageInfo; 11 | type 12 | 13 | TPackageInfoFactory = class 14 | private 15 | procedure ReadInfo(const packageInfo: TPackageInfo; const lines: TStrings); 16 | function ClearStr(Str: string):string; 17 | public 18 | function CreatePackageInfo(const packageFileName: string): TPackageInfo; overload; 19 | function CreatePackageInfo(const packageFileContent: TStrings): TPackageInfo; overload; 20 | end; 21 | implementation 22 | uses JclFileUtils; 23 | resourcestring 24 | StrRUNONLY = '{$RUNONLY'; 25 | StrDESCRIPTION = '{$DESCRIPTION '; 26 | StrSUFFIX = '{$LIBSUFFIX '; 27 | StrPackage = 'package'; 28 | StrRequires = 'requires'; 29 | StrContains = 'contains'; 30 | 31 | { TPackageInfoFactory } 32 | 33 | function TPackageInfoFactory.ClearStr(Str: string): string; 34 | begin 35 | Result := Trim(Str); 36 | Result := ReplaceStr(Result, ',', ''); 37 | Result := ReplaceStr(Result, ';', ''); 38 | end; 39 | 40 | function TPackageInfoFactory.CreatePackageInfo( 41 | const packageFileName: string): TPackageInfo; 42 | var 43 | lines: TStrings; 44 | begin 45 | lines := TStringList.Create; 46 | try 47 | lines.LoadFromFile(packageFileName); 48 | result := CreatePackageInfo(lines); 49 | Result.FileName := packageFileName; 50 | Result.PackageName := PathExtractFileNameNoExt(packageFileName); 51 | finally 52 | lines.Free; 53 | end; 54 | end; 55 | 56 | function TPackageInfoFactory.CreatePackageInfo( 57 | const packageFileContent: TStrings): TPackageInfo; 58 | begin 59 | assert(packageFileContent <> nil); 60 | Result := TPackageInfo.Create(); 61 | ReadInfo(Result, packageFileContent); 62 | end; 63 | 64 | // ugly code, but implementing a full blown parser here is like nailing with a sledge hammer 65 | procedure TPackageInfoFactory.ReadInfo(const packageInfo: TPackageInfo; const lines: TStrings); 66 | var 67 | I: Integer; 68 | Str : String; 69 | RequiresBlock,ContainsBlock: Boolean; 70 | begin 71 | assert(lines <> nil); 72 | assert(packageInfo <> nil); 73 | 74 | RequiresBlock := False; 75 | ContainsBlock := False; 76 | packageInfo.RunOnly := False; 77 | for I := 0 to lines.Count - 1 do 78 | begin 79 | Str := TrimRight(lines[i]); 80 | if Pos(StrRUNONLY+'}',str) = 1 then 81 | packageInfo.RunOnly := True; 82 | 83 | if (Pos(StrRUNONLY,str) = 1) and (Pos('ON',Str)>0) then 84 | packageInfo.RunOnly := True; 85 | 86 | if Pos(StrDESCRIPTION,str) > 0 then 87 | packageInfo.Description := Copy(Str,Length(StrDescription)+2,Pos('}',str)-Length(StrDescription)-3); 88 | if Pos(StrSUFFIX,str) > 0 then 89 | packageInfo.Suffix := Copy(Str,Length(StrSUFFIX)+2,Pos('}',str)-Length(StrSUFFIX)-3); 90 | 91 | if Pos(StrPackage,str) = 1 then 92 | packageInfo.PackageName := Trim(Copy(Str,Length(strPackage)+2,Length(Str)- Length(strPackage) -2)); 93 | 94 | if Pos(StrRequires,str) = 1 then RequiresBlock := True; 95 | if RequiresBlock then 96 | begin 97 | if not StartsStr('{$', Str) then 98 | packageInfo.RequiredPackageList.Add(ClearStr(Str)); 99 | end; 100 | if (RequiresBlock) and (pos(';',str) > 0) then 101 | RequiresBlock := False; 102 | 103 | if Pos(StrContains,str) = 1 then ContainsBlock := True; 104 | 105 | if ContainsBlock then 106 | if Pos(' in ',Str) > 0 then 107 | packageInfo.ContainedFileList.Add(Copy(Str,Pos('''',Str)+1,Length(Str) - Pos('''',Str)-2)) 108 | else 109 | packageInfo.ContainedFileList.Add(ClearStr(str)+ '.pas'); 110 | 111 | if (ContainsBlock) and (pos(';',str) > 0) then 112 | ContainsBlock := False; 113 | end; 114 | 115 | if packageInfo.RequiredPackageList.Count > 0 then 116 | packageInfo.RequiredPackageList.Delete(0); 117 | if packageInfo.ContainedFileList.Count > 0 then 118 | packageInfo.ContainedFileList.Delete(0); 119 | end; 120 | 121 | end. 122 | -------------------------------------------------------------------------------- /TreeViewModel.pas: -------------------------------------------------------------------------------- 1 | { ** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | ** } 6 | unit TreeViewModel; 7 | 8 | interface 9 | 10 | uses Classes, Generics.Collections, TreeModel; 11 | type 12 | TTreeViewModel = class(TTreeModelBase) 13 | private 14 | fNodes : TList; 15 | function SplitString(const str:string):TDynStrArray; 16 | public 17 | constructor Create(const nodes: TList); 18 | function GetChild(const parent: T; index: Integer): T; override; 19 | function GetChildCount(const parent: T): integer; override; 20 | end; 21 | 22 | implementation 23 | uses JclStrings, StrUtils; 24 | 25 | { TTreeViewModel } 26 | constructor TTreeViewModel.Create(const nodes: TList); 27 | begin 28 | fNodes := nodes; 29 | end; 30 | 31 | function TTreeViewModel.GetChild(const parent: T; index: Integer): T; 32 | var 33 | prefix, nodePath: string; 34 | node: T; 35 | words: TDynStrArray; 36 | I, currentLevel, nextLevel : integer; 37 | immediateChild: boolean; 38 | list : TStringList; 39 | nodes: TList; 40 | begin 41 | Result := default(T); 42 | 43 | prefix := ''; 44 | currentLevel := 0; 45 | nextLevel := 0; 46 | if parent <> nil then 47 | begin 48 | prefix := parent.GetNodePath; 49 | currentLevel := StrCharCount(prefix, '\'); 50 | nextLevel := currentLevel + 1; 51 | end; 52 | 53 | i := 0; 54 | list := TStringList.Create; 55 | list.Sorted := true; 56 | list.Duplicates := dupIgnore; 57 | try 58 | for node in fNodes do 59 | begin 60 | nodePath := node.GetNodePath; 61 | if not StartsStr(prefix, nodePath) then 62 | Continue; 63 | 64 | words := SplitString(nodePath); 65 | if Length(words) = 0 then 66 | Continue; 67 | 68 | if Length(words) <= nextLevel then 69 | Continue; 70 | 71 | list.Add(words[nextLevel]); 72 | if (List.Count = index+1) then 73 | begin 74 | immediateChild := Length(words) = nextLevel + 1; 75 | if immediateChild then 76 | Result := node 77 | else begin 78 | if prefix <> '' then 79 | Result := DoCreateLogicalNode(words[nextLevel], prefix + '\' + words[nextLevel]) 80 | else 81 | Result := DoCreateLogicalNode(words[nextLevel], words[nextLevel]); 82 | end; 83 | Break; 84 | end; 85 | end; 86 | finally 87 | list.Free; 88 | end; 89 | end; 90 | 91 | function TTreeViewModel.GetChildCount(const parent: T): integer; 92 | var 93 | prefix: string; 94 | node: T; 95 | nodePath: string; 96 | words: TDynStrArray; 97 | I: Integer; 98 | list: TStringList; 99 | currentLevel, nextLevel : integer; 100 | begin 101 | Result := 0; 102 | prefix := ''; 103 | currentLevel := 0; 104 | nextLevel := 0; 105 | if parent <> nil then 106 | begin 107 | prefix := parent.GetNodePath; 108 | currentLevel := StrCharCount(prefix, '\'); 109 | nextLevel := currentLevel + 1; 110 | end; 111 | 112 | list := TStringList.Create; 113 | list.Sorted := true; 114 | list.Duplicates := TDuplicates.dupIgnore; 115 | try 116 | for node in fNodes do 117 | begin 118 | nodePath := node.GetNodePath; 119 | if not StartsStr(prefix, nodePath) then 120 | Continue; 121 | 122 | words := SplitString(nodePath); 123 | if Length(words) = 0 then 124 | Continue; 125 | if Length(words) <= nextLevel then 126 | Continue; 127 | 128 | list.Add(words[nextLevel]); 129 | end; 130 | finally 131 | Result := list.Count; 132 | list.Free; 133 | end; 134 | end; 135 | 136 | function TTreeViewModel.SplitString(const str:string):TDynStrArray; 137 | var 138 | I, lastIndex: Integer; 139 | words : TStringList; 140 | begin 141 | words := TStringList.Create; 142 | try 143 | ExtractStrings(['\'], [], PWideChar(str), words); 144 | SetLength(Result, words.Count); 145 | for I := 0 to words.Count - 1 do 146 | Result[i] := words[i]; 147 | finally 148 | words.Free; 149 | end; 150 | end; 151 | 152 | 153 | end. 154 | -------------------------------------------------------------------------------- /CompilationData.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit CompilationData; 7 | interface 8 | uses Classes, PackageInfo, PackageList, JclIDEUtils; 9 | 10 | type 11 | TCompilationData = class 12 | private 13 | fBaseFolder: String; 14 | fInstallation: TJclBorRADToolInstallation; 15 | fPackageList: TPackageList; 16 | fHelpFiles: TStringList; 17 | fPattern: String; 18 | fDCPOutputFolder: string; 19 | fBPLOutputFolder: string; 20 | fDCUOutputFolder: string; 21 | FScripting: Boolean; 22 | fConditionals: string; 23 | 24 | procedure SetPackageList(const aPackageList: TPackageList); 25 | procedure SetInstallation(const Value: TJclBorRADToolInstallation); 26 | protected 27 | public 28 | constructor Create; 29 | destructor Destroy; override; 30 | 31 | procedure GetIdePackages(const list: TStringList); virtual; 32 | function GetIdeVersionSuffix: string; virtual; 33 | function SetDelphiVersion(const version:string):boolean; virtual; 34 | 35 | property Pattern: String read fPattern write fPattern; 36 | property Installation: TJclBorRADToolInstallation read fInstallation write SetInstallation; 37 | property BaseFolder: String read fBaseFolder write fBaseFolder; 38 | property HelpFiles: TStringList read fHelpFiles; 39 | property PackageList: TPackageList read fPackageList write SetPackageList; 40 | property DCPOutputFolder: string read fDCPOutputFolder write fDCPOutputFolder; 41 | property BPLOutputFolder: string read fBPLOutputFolder write fBPLOutputFolder; 42 | property DCUOutputFolder: string read fDCUOutputFolder write fDCUOutputFolder; 43 | property Conditionals: string read fConditionals write fConditionals; 44 | 45 | property Scripting: Boolean read fScripting write fScripting; 46 | end; 47 | 48 | implementation 49 | 50 | uses JclFileUtils,SysUtils; 51 | var 52 | installations: TJclBorRADToolInstallations; 53 | 54 | constructor TCompilationData.Create; 55 | begin 56 | fPattern := '*.dpk'; 57 | fPackageList := TPackageList.Create; 58 | fHelpFiles := TStringList.Create; 59 | fScripting := False; 60 | end; 61 | 62 | destructor TCompilationData.Destroy; 63 | begin 64 | fPackageList.Free; 65 | fHelpFiles.Free; 66 | inherited; 67 | end; 68 | 69 | procedure TCompilationData.GetIdePackages(const list: TStringList); 70 | var 71 | i: integer; 72 | begin 73 | assert(Assigned(Installation),'installation cannot be null'); 74 | 75 | for i := 0 to Installation.IdePackages.Count - 1 do 76 | list.Add(Installation.IdePackages.PackageFileNames[i]); 77 | end; 78 | 79 | function TCompilationData.GetIdeVersionSuffix: string; 80 | begin 81 | Result := Installation.VersionNumberStr; 82 | if Result = 'd11' then //Delphi 2007 packages have version 10 extension 83 | Result := 'd10'; 84 | end; 85 | 86 | function TCompilationData.SetDelphiVersion(const version: string): boolean; 87 | var 88 | installation: TJclBorRADToolInstallation; 89 | i : integer; 90 | begin 91 | Result := false; 92 | for i := 0 to installations.Count - 1 do 93 | begin 94 | installation := installations.Installations[i]; 95 | if UpperCase(Trim(installation.VersionNumberStr)) = UpperCase(Trim(version)) then 96 | begin 97 | fInstallation := installation; 98 | Result := true; 99 | break; 100 | end; 101 | end; 102 | if fInstallation = nil then 103 | raise Exception.Create('cannot find delphi version:' + version); 104 | end; 105 | 106 | procedure TCompilationData.SetInstallation( 107 | const Value: TJclBorRADToolInstallation); 108 | begin 109 | if fInstallation = Value then 110 | exit; 111 | 112 | fInstallation := Value; 113 | 114 | BPLOutputFolder := fInstallation.BPLOutputPath[bpWin32]; 115 | DCPOutputFolder := fInstallation.DCPOutputPath[bpWin32]; 116 | end; 117 | 118 | procedure TCompilationData.SetPackageList(const aPackageList: TPackageList); 119 | begin 120 | fPackageList.Free; 121 | fPackageList := aPackageList; 122 | end; 123 | initialization 124 | installations := TJclBorRADToolInstallations.Create; 125 | finalization 126 | installations.Free; 127 | 128 | end. 129 | -------------------------------------------------------------------------------- /PageCompilerOptions.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PageCompilerOptions; 7 | 8 | interface 9 | 10 | uses 11 | Classes, CompilationData, Windows, Messages, SysUtils, Variants, Graphics, Vcl.Controls, Forms, 12 | Dialogs, PageBase, StdCtrls, ExtCtrls, WizardIntfs; 13 | 14 | type 15 | TSelectCompilerOptions = class(TWizardPage) 16 | grpOutputFolders: TGroupBox; 17 | lblBPLOutputFolder: TLabel; 18 | edtBPL: TEdit; 19 | btnBPLBrowse: TButton; 20 | lblDCP: TLabel; 21 | edtDCP: TEdit; 22 | btnDCPBrowse: TButton; 23 | lblDCU: TLabel; 24 | edtDCU: TEdit; 25 | btnDCUBrowse: TButton; 26 | Label1: TLabel; 27 | edtConditionals: TEdit; 28 | procedure FormCreate(Sender: TObject); 29 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 30 | procedure btnBPLBrowseClick(Sender: TObject); 31 | procedure btnDCPBrowseClick(Sender: TObject); 32 | procedure btnDCUBrowseClick(Sender: TObject); 33 | private 34 | procedure SaveInstallationOutputFolders; 35 | procedure ShowInstallationOutputFolders; 36 | procedure BrowseFolder(var folder: string); 37 | function SelectFolder(const editBox: TEdit): string; 38 | public 39 | constructor Create(Owner: TComponent; const compilationData: TCompilationData); override; 40 | procedure UpdateWizardState; override; 41 | function CanShowPage: Boolean; override; 42 | end; 43 | 44 | var 45 | SelectCompilerOptions: TSelectCompilerOptions; 46 | 47 | implementation 48 | uses gnugettext, FileCtrl; 49 | {$R *.dfm} 50 | 51 | { TSelectDelphiInstallationPage } 52 | 53 | constructor TSelectCompilerOptions.Create(Owner: TComponent; 54 | const compilationData: TCompilationData); 55 | begin 56 | inherited; 57 | TranslateComponent(self); 58 | FCompilationData := compilationData; 59 | end; 60 | 61 | procedure TSelectCompilerOptions.FormClose(Sender: TObject; 62 | var Action: TCloseAction); 63 | begin 64 | inherited; 65 | SaveInstallationOutputFolders; 66 | end; 67 | 68 | procedure TSelectCompilerOptions.FormCreate(Sender: TObject); 69 | begin 70 | inherited; 71 | TranslateComponent(self); 72 | ShowInstallationOutputFolders; 73 | end; 74 | 75 | procedure TSelectCompilerOptions.BrowseFolder(var folder:string); 76 | var 77 | directory: string; 78 | begin 79 | directory := ''; 80 | if SelectDirectory(_('Select output folder'),'',directory) then 81 | begin 82 | folder := directory; 83 | end; 84 | end; 85 | 86 | function TSelectCompilerOptions.SelectFolder(const editBox: TEdit):string; 87 | var 88 | path: string; 89 | begin 90 | inherited; 91 | Assert(Assigned(editBox)); 92 | path := editBox.Text; 93 | BrowseFolder(path); 94 | editBox.Text := path; 95 | end; 96 | 97 | procedure TSelectCompilerOptions.btnBPLBrowseClick(Sender: TObject); 98 | begin 99 | inherited; 100 | SelectFolder(edtBPL); 101 | end; 102 | 103 | procedure TSelectCompilerOptions.btnDCPBrowseClick(Sender: TObject); 104 | begin 105 | inherited; 106 | SelectFolder(edtDCP); 107 | end; 108 | 109 | procedure TSelectCompilerOptions.btnDCUBrowseClick(Sender: TObject); 110 | begin 111 | inherited; 112 | SelectFolder(edtDCU); 113 | end; 114 | 115 | function TSelectCompilerOptions.CanShowPage: Boolean; 116 | begin 117 | Result := True; 118 | //Result := FCompilationData.Scripting; 119 | end; 120 | 121 | procedure TSelectCompilerOptions.SaveInstallationOutputFolders; 122 | begin 123 | Assert(Assigned(fCompilationData), 'Compilation data is null'); 124 | fCompilationData.BPLOutputFolder := edtBPL.Text; 125 | fCompilationData.DCPOutputFolder := edtDCP.Text; 126 | fCompilationData.DCUOutputFolder := edtDCU.Text; 127 | fCompilationData.Conditionals := edtConditionals.Text; 128 | end; 129 | 130 | procedure TSelectCompilerOptions.ShowInstallationOutputFolders; 131 | begin 132 | Assert(Assigned(fCompilationData), 'Compilation data is null'); 133 | edtBPL.Text:= fCompilationData.BPLOutputFolder; 134 | edtDCP.Text:= fCompilationData.DCPOutputFolder; 135 | edtDCU.Text:= fCompilationData.DCUOutputFolder; 136 | edtConditionals.Text := fCompilationData.Conditionals; 137 | end; 138 | 139 | procedure TSelectCompilerOptions.UpdateWizardState; 140 | begin 141 | inherited; 142 | wizard.SetHeader(_('Select Output Folders and Compiler Conditionals')); 143 | wizard.SetDescription(_('Please select output folders and compiler conditionals that will affect the compilation')); 144 | end; 145 | 146 | end. 147 | -------------------------------------------------------------------------------- /InstalledPackageResolver.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit InstalledPackageResolver; 7 | 8 | interface 9 | uses Classes, CompilationData; 10 | type 11 | 12 | IInstalledPackageResolver = interface 13 | procedure AddDefaultPackageList; 14 | function GetInstalledPackages: TStringList; 15 | procedure AddIDEPackageList(const CompilationData: TCompilationData); 16 | procedure Clear; 17 | end; 18 | 19 | TInstalledPackageResolver = class(TInterfacedObject, IInstalledPackageResolver) 20 | private 21 | fVersionSuffix: string; 22 | fSearchFolders: TStringList; 23 | fInstalledPackages: TStringList; 24 | function RemoveVersionSuffix(const name, suffix: string): string; 25 | function GetInstalledPackages: TStringList; 26 | protected 27 | public 28 | constructor Create; overload; virtual; 29 | constructor Create(const CompilationData: TCompilationData); overload; virtual; 30 | destructor Destroy; override; 31 | procedure AddDefaultPackageList; virtual; 32 | procedure AddIDEPackageList(const CompilationData: TCompilationData); virtual; 33 | procedure Clear; 34 | property InstalledPackages: TStringList read GetInstalledPackages; 35 | end; 36 | implementation 37 | 38 | uses SysUtils, JclFileUtils, JclIDEUtils; 39 | constructor TInstalledPackageResolver.Create; 40 | begin 41 | inherited Create; 42 | fSearchFolders := TStringList.Create; 43 | fInstalledPackages := TStringList.Create; 44 | end; 45 | 46 | constructor TInstalledPackageResolver.Create(const CompilationData: TCompilationData); 47 | var 48 | systemPath, versionPattern: string; 49 | filePattern: string; 50 | begin 51 | Assert(CompilationData <> nil, 'Compilation Data cannot be null'); 52 | Assert(CompilationData.Installation <> nil, 'Installation cannot be null'); 53 | 54 | Create; 55 | 56 | fVersionSuffix := CompilationData.GetIdeVersionSuffix; 57 | versionPattern := Copy(fVersionSuffix, 2, Length(fVersionSuffix) - 1) + '0'; 58 | filePattern := '*' + versionPattern + '.bpl'; 59 | 60 | systemPath := GetEnvironmentVariable('WINDIR') + '\System32\'; 61 | fSearchFolders.Add(PathAppend(systemPath, filePattern)); 62 | fSearchFolders.Add(PathAppend(CompilationData.Installation.LibFolderName[bpWin32], '*.bpl')); 63 | fSearchFolders.Add(PathAppend(CompilationData.Installation.BinFolderName, '*.bpl')); 64 | end; 65 | 66 | procedure TInstalledPackageResolver.AddDefaultPackageList; 67 | var 68 | packageName: string; 69 | internalList: TStringList; 70 | path, entry: string; 71 | begin 72 | internalList := TStringList.Create; 73 | try 74 | for path in fSearchFolders do 75 | BuildFileList(path, faAnyFile, internalList); 76 | 77 | for entry in internalList do 78 | begin 79 | packageName := PathExtractFileNameNoExt(entry); 80 | packageName := UpperCase(packageName); 81 | packageName := RemoveVersionSuffix(packageName, fVersionSuffix); 82 | fInstalledPackages.Add(packageName); 83 | end; 84 | 85 | finally 86 | internalList.Free; 87 | end; 88 | fInstalledPackages.Add('DESIGNIDE'); 89 | end; 90 | 91 | procedure TInstalledPackageResolver.AddIDEPackageList(const CompilationData: TCompilationData); 92 | var 93 | i: integer; 94 | idePackageName: string; 95 | list: TStringList; 96 | begin 97 | list := TStringList.Create; 98 | try 99 | CompilationData.GetIdePackages(list); 100 | 101 | for i := 0 to CompilationData.Installation.IdePackages.Count - 1 do 102 | list.Add(CompilationData.Installation.IdePackages.PackageFileNames[i]); 103 | 104 | for i := 0 to list.Count - 1 do 105 | begin 106 | idePackageName := PathExtractFileNameNoExt(list[i]); 107 | fInstalledPackages.Add(UpperCase(idePackageName)); 108 | end; 109 | finally 110 | list.Free; 111 | end; 112 | end; 113 | 114 | procedure TInstalledPackageResolver.Clear; 115 | begin 116 | fInstalledPackages.Clear; 117 | end; 118 | 119 | destructor TInstalledPackageResolver.Destroy; 120 | begin 121 | FreeAndNil(fInstalledPackages); 122 | FreeAndNil(fSearchFolders); 123 | inherited; 124 | end; 125 | 126 | function TInstalledPackageResolver.GetInstalledPackages: TStringList; 127 | begin 128 | Result := fInstalledPackages; 129 | end; 130 | 131 | function TInstalledPackageResolver.RemoveVersionSuffix(const name, suffix: string): string; 132 | begin 133 | Result := name; 134 | Delete(Result, Length(Result) - Length(suffix) + 1, Length(suffix)) 135 | end; 136 | end. 137 | 138 | -------------------------------------------------------------------------------- /PageSummary.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PageSummary; 7 | 8 | interface 9 | 10 | uses 11 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Vcl.Controls, Forms, 12 | Dialogs, PageBase, StdCtrls; 13 | 14 | type 15 | TSummaryPage = class(TWizardPage) 16 | Label1: TLabel; 17 | btnSave: TButton; 18 | edtSummary: TMemo; 19 | Label2: TLabel; 20 | procedure btnSaveClick(Sender: TObject); 21 | procedure FormCreate(Sender: TObject); 22 | private 23 | function Indented(const line: string):string; 24 | procedure AddBaseFolder(const summary: TStringList); 25 | procedure AddDelphiVersion(const summary: TStringList); 26 | procedure AddPackageList(const summary: TStringList); 27 | procedure AddSourcePathList(const summary: TStringList); 28 | procedure AddHelpFileList(const summary: TStringList); 29 | public 30 | procedure UpdateWizardState; override; 31 | 32 | end; 33 | 34 | var 35 | SummaryPage: TSummaryPage; 36 | 37 | implementation 38 | uses ScriptPersister,WizardIntfs, PackageInfo, gnugettext; 39 | {$R *.dfm} 40 | 41 | { TFinishedPage } 42 | 43 | 44 | procedure TSummaryPage.AddBaseFolder(const summary: TStringList); 45 | begin 46 | summary.Add(_('Base Folder:')); 47 | summary.Add(Indented(fCompilationData.BaseFolder)); 48 | end; 49 | 50 | procedure TSummaryPage.AddDelphiVersion(const summary: TStringList); 51 | begin 52 | summary.Add(_('Delphi Version:')); 53 | summary.Add(Indented(fCompilationData.Installation.IDEVersionNumberStr)); 54 | end; 55 | 56 | procedure TSummaryPage.AddHelpFileList(const summary: TStringList); 57 | var 58 | helpfile: string; 59 | begin 60 | summary.Add(_('Help Files:')); 61 | for helpfile in fCompilationData.HelpFiles do 62 | summary.Add(Indented(helpfile)); 63 | end; 64 | 65 | procedure TSummaryPage.AddPackageList(const summary: TStringList); 66 | var 67 | I: Integer; 68 | erroredPackages: TStringList; 69 | packageName: String; 70 | begin 71 | summary.Add(_('Package List:')); 72 | erroredPackages := TStringList.Create; 73 | try 74 | for I := 0 to fCompilationData.PackageList.Count - 1 do 75 | with fCompilationData.PackageList[i] do 76 | begin 77 | summary.Add(Indented(FileName)); 78 | if Status = psError then 79 | erroredPackages.Add(FileName); 80 | end; 81 | 82 | if erroredPackages.Count > 0 then 83 | begin 84 | summary.Add(_('However, following packages had some errors:')); 85 | for packageName in erroredPackages do 86 | summary.Add(Indented(packageName)); 87 | end; 88 | finally 89 | erroredPackages.Free; 90 | end; 91 | end; 92 | 93 | procedure TSummaryPage.AddSourcePathList(const summary: TStringList); 94 | //var 95 | // path: string; 96 | begin 97 | // summary.Add(_('Source File Paths:')); 98 | // for path in fCompilationData.SourceFilePaths do 99 | // summary.Add(Indented(path)); 100 | end; 101 | 102 | procedure TSummaryPage.btnSaveClick(Sender: TObject); 103 | var 104 | dialog: TSaveDialog; 105 | scripter: TScriptPersister; 106 | begin 107 | dialog := TSaveDialog.Create(self); 108 | try 109 | if dialog.Execute then begin 110 | scripter := TScriptPersister.Create; 111 | try 112 | scripter.Save(fCompilationData, dialog.FileName); 113 | finally 114 | scripter.Free; 115 | end; 116 | end; 117 | finally 118 | dialog.Free; 119 | end; 120 | end; 121 | 122 | procedure TSummaryPage.FormCreate(Sender: TObject); 123 | var 124 | summary: TStringList; 125 | begin 126 | inherited; 127 | if fCompilationData = nil then exit; 128 | summary := TStringList.Create; 129 | try 130 | AddBaseFolder(summary); 131 | AddDelphiVersion(summary); 132 | AddPackageList(summary); 133 | AddSourcePathList(summary); 134 | AddHelpFileList(summary); 135 | finally 136 | edtSummary.Lines.Assign(summary); 137 | summary.Free; 138 | end; 139 | end; 140 | 141 | function TSummaryPage.Indented(const line: string): string; 142 | begin 143 | Result := ' ' + line; 144 | end; 145 | 146 | procedure TSummaryPage.UpdateWizardState; 147 | begin 148 | inherited; 149 | fWizardController.SetHeader(_('Finished')); 150 | fWizardController.SetDescription(_('Installation Summary')); 151 | with fWizardController.GetAction(wbtNext) do 152 | Caption := _('&Exit'); 153 | 154 | with fWizardController.GetAction(wbtBack) do 155 | Visible := false; 156 | end; 157 | 158 | end. 159 | -------------------------------------------------------------------------------- /Test/TestPackageDependencyVerifier.pas: -------------------------------------------------------------------------------- 1 | unit TestPackageDependencyVerifier; 2 | interface 3 | 4 | uses 5 | TestFramework, CompilationData, PackageList, Classes, 6 | PackageDependencyVerifier, PackageInfo; 7 | 8 | type 9 | // Test methods for class TPackageDependencyVerifier 10 | TestTPackageDependencyVerifier = class(TTestCase) 11 | strict private 12 | SUT: TPackageDependencyVerifier; 13 | function CreatePackage(name: string; requireds: string ): TPackageInfo; 14 | published 15 | procedure When_a_required_package_is_missing_then_packages_depending_on_it_should_be_set_as_missing; 16 | procedure When_a_package_cannot_be_compiled_then_packages_depending_on_it_should_be_marked_as_missing; 17 | procedure When_a_package_is_removed_then_next_verfication_should_only_check_custom_packages; 18 | end; 19 | 20 | implementation 21 | uses Generics.Collections, InstalledPackageResolver; 22 | type 23 | TStringArr = array of string; 24 | 25 | TFakeInstalledPackageResolver = class(TInstalledPackageResolver) 26 | public 27 | constructor Create; override; 28 | end; 29 | 30 | procedure TestTPackageDependencyVerifier.When_a_required_package_is_missing_then_packages_depending_on_it_should_be_set_as_missing; 31 | var 32 | list: TObjectList; 33 | begin 34 | list := TObjectList.Create; 35 | list.OwnsObjects := True; 36 | try 37 | list.Add(CreatePackage('package1','an ide package')); 38 | list.Add(CreatePackage('package2','package1')); 39 | list.Add(CreatePackage('package3','missing package')); 40 | 41 | Sut := TPackageDependencyVerifier.Create; 42 | try 43 | Sut.Verify(list, TFakeInstalledPackageResolver.Create); 44 | 45 | CheckEqualsString('',Sut.MissingPackages['package1']); 46 | CheckEqualsString('',Sut.MissingPackages['package2']); 47 | CheckEqualsString('missing package',Sut.MissingPackages['package3']); 48 | finally 49 | SUT.Free; 50 | end; 51 | finally 52 | list.Free; 53 | end; 54 | end; 55 | 56 | function TestTPackageDependencyVerifier.CreatePackage(name, requireds: string): TPackageInfo; 57 | var 58 | req: string; 59 | words: TStrings; 60 | begin 61 | Result := TPackageInfo.Create(name); 62 | words := TStringList.Create; 63 | ExtractStrings([','],[' '],PWideChar(requireds), words); 64 | for req in words do 65 | begin 66 | Result.RequiredPackageList.Add(req); 67 | end; 68 | words.Free; 69 | end; 70 | 71 | procedure TestTPackageDependencyVerifier.When_a_package_cannot_be_compiled_then_packages_depending_on_it_should_be_marked_as_missing; 72 | var 73 | list: TObjectList; 74 | begin 75 | list := TObjectList.Create; 76 | try 77 | list.Add(CreatePackage('package1','an ide package,missing ide package')); 78 | list.Add(CreatePackage('package2','package1')); 79 | 80 | Sut := TPackageDependencyVerifier.Create; 81 | try 82 | Sut.Verify(list, TFakeInstalledPackageResolver.Create); 83 | 84 | CheckEqualsString('missing ide package',Sut.MissingPackages['package1']); 85 | CheckEqualsString('package1 requires missing ide package',Sut.MissingPackages['package2']); 86 | finally 87 | Sut.Free; 88 | end; 89 | finally 90 | list.Free; 91 | end; 92 | end; 93 | 94 | procedure TestTPackageDependencyVerifier.When_a_package_is_removed_then_next_verfication_should_only_check_custom_packages; 95 | var 96 | list: TObjectList; 97 | begin 98 | list := TObjectList.Create; 99 | list.Add(CreatePackage('package1','an ide package')); 100 | list.Add(CreatePackage('package2','package1')); 101 | list.Add(CreatePackage('package3','package2')); 102 | try 103 | 104 | Sut := TPackageDependencyVerifier.Create; 105 | Sut.Verify(list, TFakeInstalledPackageResolver.Create); 106 | 107 | CheckEqualsString('',Sut.MissingPackages['package1']); 108 | CheckEqualsString('',Sut.MissingPackages['package2']); 109 | 110 | list.Delete(0); // remove package1 111 | 112 | Sut.Verify(list, TFakeInstalledPackageResolver.Create); 113 | 114 | CheckEqualsString('',Sut.MissingPackages['package1']); 115 | CheckNotEqualsString('',Sut.MissingPackages['package3']); 116 | 117 | Sut.Free; 118 | finally 119 | list.Free; 120 | end; 121 | end; 122 | 123 | { TFakeInstalledPackageResolver } 124 | 125 | constructor TFakeInstalledPackageResolver.Create; 126 | begin 127 | inherited; 128 | InstalledPackages.Add('an ide package'); 129 | end; 130 | 131 | initialization 132 | // Register any test cases with the test runner 133 | RegisterTest(TestTPackageDependencyVerifier.Suite); 134 | end. 135 | -------------------------------------------------------------------------------- /Test/TestTreeModel.pas: -------------------------------------------------------------------------------- 1 | unit TestTreeModel; 2 | 3 | interface 4 | 5 | uses 6 | TestFramework, TreeModel, Classes, Generics.Collections, TreeViewModel; 7 | 8 | type 9 | 10 | TDumbNode = class(TInterfacedObject, INode) 11 | private 12 | fName: string; 13 | public 14 | constructor Create(name: string); 15 | function GetData: TObject; 16 | function GetDisplayName: string; 17 | function GetNodePath: string; 18 | end; 19 | 20 | TestTTreeModel = class(TTestCase) 21 | strict private 22 | FItems: TObjectList; 23 | FTreeModel: TTreeViewModel; 24 | private 25 | function CreateLogicalNode(name, path:string):TDumbNode; 26 | public 27 | procedure SetUp; override; 28 | procedure TearDown; override; 29 | published 30 | procedure Should_return_root_nodes_if_parent_is_nil; 31 | procedure Should_return_child_nodes_of_specified_parent; 32 | procedure Should_return_child_node_at_index_0; 33 | procedure Should_return_child_node_at_index_1; 34 | procedure Should_return_count_of_logical_children; 35 | procedure Should_return_logical_node_if_there_are_not_immediate_children; 36 | procedure Should_return_count_of_logical_nodes_under_a_parent; 37 | procedure Should_return_child_at_index_1_under_a_parent; 38 | end; 39 | 40 | implementation 41 | { TBasicNode } 42 | 43 | constructor TDumbNode.Create(name: string); 44 | begin 45 | fName := name; 46 | end; 47 | 48 | function TDumbNode.GetData: TObject; 49 | begin 50 | Result := nil; 51 | end; 52 | 53 | function TDumbNode.getDisplayName: string; 54 | begin 55 | Result := fName; 56 | end; 57 | 58 | function TDumbNode.GetNodePath: string; 59 | begin 60 | Result := fName; 61 | end; 62 | 63 | function TestTTreeModel.CreateLogicalNode(name, path: string): TDumbNode; 64 | begin 65 | Result := TDumbNode.Create(path); 66 | end; 67 | 68 | procedure TestTTreeModel.SetUp; 69 | begin 70 | FItems := TObjectList.Create; 71 | FItems.Add(TDumbNode.Create('a')); 72 | FItems.Add(TDumbNode.Create('a\1')); 73 | FItems.Add(TDumbNode.Create('a\2')); 74 | FItems.Add(TDumbNode.Create('a\2\3')); 75 | FItems.Add(TDumbNode.Create('b')); 76 | FItems.Add(TDumbNode.Create('b\1\1')); 77 | FItems.Add(TDumbNode.Create('b\1\2')); 78 | FItems.Add(TDumbNode.Create('c\1\1')); 79 | FItems.Add(TDumbNode.Create('c\1\2')); 80 | FItems.Add(TDumbNode.Create('c\2\1')); 81 | FTreeModel := TTreeViewModel.Create(fItems); 82 | FTreeModel.OnCreateLogicalNode := CreateLogicalNode; 83 | end; 84 | 85 | procedure TestTTreeModel.TearDown; 86 | begin 87 | FTreeModel.Free; 88 | FTreeModel := nil; 89 | end; 90 | 91 | procedure TestTTreeModel.Should_return_root_nodes_if_parent_is_nil; 92 | var 93 | childCount:integer; 94 | begin 95 | childCount := FTreeModel.GetChildCount(nil); 96 | CheckEquals(3, childCount, 'node count at level 0 was wrong'); 97 | end; 98 | 99 | procedure TestTTreeModel.Should_return_child_nodes_of_specified_parent; 100 | var 101 | childCount:integer; 102 | begin 103 | childCount := FTreeModel.GetChildCount(TDumbNode.Create('a')); 104 | CheckEquals(2, childCount, 'child count of node a was wrong'); 105 | end; 106 | 107 | 108 | procedure TestTTreeModel.Should_return_child_node_at_index_0; 109 | var 110 | actual: TDumbNode; 111 | begin 112 | actual := FTreeModel.GetChild(TDumbNode.Create('a'), 0); 113 | CheckNotNull(actual, 'returned should not be null'); 114 | CheckEquals('a\1', actual.GetNodePath, 'returned node is wrong'); 115 | end; 116 | 117 | procedure TestTTreeModel.Should_return_child_node_at_index_1; 118 | var 119 | actual: TDumbNode; 120 | begin 121 | actual := FTreeModel.GetChild(TDumbNode.Create('a'), 1); 122 | CheckNotNull(actual, 'returned should not be null'); 123 | CheckEquals('a\2', actual.GetNodePath, 'returned node is wrong'); 124 | end; 125 | 126 | procedure TestTTreeModel.Should_return_count_of_logical_children; 127 | var 128 | count : integer; 129 | begin 130 | count := FTreeModel.GetChildCount(TDumbNode.Create('b')); 131 | CheckEquals(1,count, 'logical children count was wrong'); 132 | end; 133 | 134 | procedure TestTTreeModel.Should_return_logical_node_if_there_are_not_immediate_children; 135 | var 136 | node : TDumbNode; 137 | begin 138 | node := FTreeModel.GetChild(TDumbNode.Create('b'), 0); 139 | CheckNotNull(node, 'logical node should not be null'); 140 | CheckEquals('b\1',node.GetNodePath, 'logical node path was wrong'); 141 | end; 142 | 143 | procedure TestTTreeModel.Should_return_count_of_logical_nodes_under_a_parent; 144 | var 145 | count: integer; 146 | begin 147 | count := FTreeModel.GetChildCount(TDumbNode.Create('c')); 148 | CheckEquals(2, count, 'logical node count was wrong'); 149 | end; 150 | 151 | procedure TestTTreeModel.Should_return_child_at_index_1_under_a_parent; 152 | var 153 | node: TDumbNode; 154 | begin 155 | node := FTreeModel.GetChild(TDumbNode.Create('c'),1); 156 | CheckEquals('c\2', node.GetNodePath, 'logical child was wrong'); 157 | end; 158 | 159 | initialization 160 | 161 | // Register any test cases with the test runner 162 | RegisterTest(TestTTreeModel.Suite); 163 | 164 | end. 165 | -------------------------------------------------------------------------------- /DelphiVersionTreeViewModel.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit DelphiVersionTreeViewModel; 7 | 8 | interface 9 | uses Classes, SysUtils, TreeModel, Utils, Generics.Collections; 10 | type 11 | 12 | TDelphiVersionTreeViewModel = class(TTreeModelBase) 13 | private 14 | fNodes: TList; 15 | function FindDelphiVersionIndexByName(const delphiVersionName: string):Integer; 16 | protected 17 | function GetChildren(const parent: T): TList; 18 | public 19 | constructor Create(const nodes: TList); virtual; 20 | function GetChild(const parent: T; index: Integer): T; override; 21 | function GetChildCount(const parent: T): Integer; override; 22 | end; 23 | 24 | TCachedDelphiVersionTreeViewModel = class(TDelphiVersionTreeViewModel) 25 | private 26 | fLastNodeCount: Integer; 27 | fCache: array[DELPHI_VERSION_5..DELPHI_LAST_VERSION] of TList; 28 | procedure RefillCache; 29 | public 30 | function GetChild(const parent: T; index: Integer): T; override; 31 | function GetChildCount(const parent: T): Integer; override; 32 | end; 33 | 34 | implementation 35 | uses JclStrings, JclFileUtils, RegularExpressions; 36 | 37 | { TDelphiVersionTreeViewModel } 38 | constructor TDelphiVersionTreeViewModel.Create(const nodes: TList); 39 | begin 40 | fNodes := nodes; 41 | end; 42 | 43 | function TDelphiVersionTreeViewModel.FindDelphiVersionIndexByName( 44 | const delphiVersionName: string): Integer; 45 | var 46 | I: Integer; 47 | begin 48 | Result := DELPHI_VERSION_UNKNOWN; 49 | for I := DELPHI_VERSION_5 to DELPHI_LAST_VERSION do 50 | if StrCompare(VersionNames[i], delphiVersionName) = 0 then 51 | Result := i; 52 | end; 53 | 54 | function TDelphiVersionTreeViewModel.GetChild(const parent: T; 55 | index: Integer): T; 56 | var 57 | ret: TList; 58 | begin 59 | Result := default(T); 60 | ret := GetChildren(parent); 61 | if ret.Count > index then 62 | Result := ret[index]; 63 | ret.Free; 64 | end; 65 | 66 | function TDelphiVersionTreeViewModel.GetChildCount(const parent: T): Integer; 67 | var 68 | ret: TList; 69 | begin 70 | ret := GetChildren(Parent); 71 | Result := ret.Count; 72 | ret.Free; 73 | end; 74 | 75 | function TDelphiVersionTreeViewModel.GetChildren(const parent: T): TList; 76 | var 77 | I: Integer; 78 | path : string; 79 | matches: array[DELPHI_VERSION_5..DELPHI_LAST_VERSION] of integer; 80 | node: T; 81 | ver, delphiVersionIndex: integer; 82 | begin 83 | FillChar(matches, Length(matches)*sizeof(Integer), 0); 84 | Result := TList.Create; 85 | if parent = nil then 86 | begin 87 | for node in fNodes do begin 88 | path := node.GetNodePath; 89 | ver := Utils.GuessDelphiVersion(path); 90 | if ver <> -1 then 91 | Inc(matches[ver]); 92 | end; 93 | for I := DELPHI_VERSION_5 to DELPHI_LAST_VERSION do 94 | if matches[i] > 0 then 95 | Result.Add(DoCreateLogicalNode(VersionNames[i],VersionNames[i])); 96 | end else begin 97 | delphiVersionIndex := FindDelphiVersionIndexByName(parent.GetNodePath); 98 | for node in fNodes do begin 99 | path := node.GetNodePath; 100 | ver := Utils.GuessDelphiVersion(path); 101 | if ver = delphiVersionIndex then 102 | Result.Add(node); 103 | end; 104 | end; 105 | end; 106 | 107 | procedure TCachedDelphiVersionTreeViewModel.RefillCache; 108 | var 109 | I: Integer; 110 | versionIndex: Integer; 111 | parents, children: TList; 112 | parentNode: T; 113 | begin 114 | for I := DELPHI_VERSION_5 to DELPHI_LAST_VERSION do 115 | begin 116 | if Assigned(fCache[i]) then 117 | FreeAndNil(fCache[i]); 118 | fCache[i] := TList.Create; 119 | end; 120 | 121 | parents := inherited GetChildren(default(T)); 122 | try 123 | for parentNode in parents do 124 | begin 125 | children := inherited GetChildren(parentNode); 126 | try 127 | versionIndex := FindDelphiVersionIndexByName(parentNode.GetNodePath); 128 | fCache[versionIndex].AddRange(children); 129 | finally 130 | children.Free; 131 | end; 132 | end; 133 | finally 134 | parents.Free; 135 | end; 136 | 137 | fLastNodeCount := fNodes.Count; 138 | end; 139 | 140 | function TCachedDelphiVersionTreeViewModel.GetChild(const parent: T; 141 | index: Integer): T; 142 | var 143 | versionIndex: Integer; 144 | begin 145 | if fLastNodeCount <> fNodes.Count then 146 | RefillCache; 147 | 148 | Result := default(T); 149 | if parent = nil then begin 150 | Result := inherited GetChild(parent, index); 151 | end else begin 152 | versionIndex := FindDelphiVersionIndexByName(parent.GetNodePath); 153 | if versionIndex in [DELPHI_VERSION_5..DELPHI_LAST_VERSION] then 154 | if index < fCache[versionIndex].Count then 155 | Result := fCache[versionIndex][index]; 156 | end; 157 | end; 158 | 159 | function TCachedDelphiVersionTreeViewModel.GetChildCount( 160 | const parent: T): Integer; 161 | var 162 | versionIndex : Integer; 163 | begin 164 | if fLastNodeCount <> fNodes.Count then 165 | RefillCache; 166 | 167 | if parent <> nil then begin 168 | versionIndex := FindDelphiVersionIndexByName(parent.GetNodePath); 169 | if versionIndex <> -1 then 170 | Result := fCache[versionIndex].Count; 171 | end else begin 172 | Result := inherited GetChildCount(default(T)); 173 | end; 174 | end; 175 | 176 | end. 177 | -------------------------------------------------------------------------------- /PageSelectFolders.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PageSelectFolders; 7 | 8 | interface 9 | 10 | uses 11 | CompilationData, Windows, Messages, SysUtils, Variants, Classes, Graphics, Vcl.Controls, Forms, 12 | Dialogs, PageBase, StdCtrls, ExtCtrls, WizardIntfs, JclIDEUtils, ActnList; 13 | 14 | type 15 | TSelectFoldersPage = class(TWizardPage) 16 | grpPackagePattern: TGroupBox; 17 | Label3: TLabel; 18 | cbPattern: TComboBox; 19 | grpBaseFolder: TGroupBox; 20 | Label1: TLabel; 21 | btnSelectFolder: TButton; 22 | edtBaseFolder: TEdit; 23 | Label2: TLabel; 24 | grpDelphiVersion: TGroupBox; 25 | cbDelphiVersions: TComboBox; 26 | procedure btnSelectFolderClick(Sender: TObject); 27 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 28 | procedure FormCreate(Sender: TObject); 29 | procedure cbDelphiVersionsChange(Sender: TObject); 30 | procedure edtBaseFolderChange(Sender: TObject); 31 | private 32 | FPatternsFileName: string; 33 | fInstallations : TJclBorRADToolInstallations; 34 | procedure AddDelphiInstallation(const installation: TJclBorRADToolInstallation); 35 | function GetInstallations: TJclBorRADToolInstallations; 36 | protected 37 | property Installations: TJclBorRADToolInstallations read GetInstallations; 38 | public 39 | constructor Create(Owner: TComponent; const compilationData: TCompilationData); override; 40 | procedure UpdateWizardState; override; 41 | function CanShowPage: Boolean; override; 42 | 43 | end; 44 | 45 | var 46 | SelectFoldersPage: TSelectFoldersPage; 47 | 48 | implementation 49 | uses FileCtrl, gnugettext, FormWizard, JclSysInfo, JclFileUtils; 50 | {$R *.dfm} 51 | { TSelectFoldersPage } 52 | 53 | constructor TSelectFoldersPage.Create(Owner: TComponent; 54 | const compilationData: TCompilationData); 55 | begin 56 | inherited; 57 | fCompilationData := compilationData; 58 | end; 59 | 60 | procedure TSelectFoldersPage.edtBaseFolderChange(Sender: TObject); 61 | begin 62 | inherited; 63 | UpdateWizardState; 64 | end; 65 | 66 | procedure TSelectFoldersPage.FormCreate(Sender: TObject); 67 | var 68 | i: integer; 69 | dataFolder: string; 70 | begin 71 | inherited; 72 | TranslateComponent(self); 73 | 74 | dataFolder := PathAppend(GetAppdataFolder, 'DelphiPI'); 75 | if not DirectoryExists(dataFolder) then 76 | CreateDir(dataFolder); 77 | 78 | FPatternsFileName := PathAppend(dataFolder, 'patterns.txt'); 79 | 80 | edtBaseFolder.Text := FCompilationData.BaseFolder; 81 | cbPattern.Text := FCompilationData.Pattern; 82 | 83 | if (FileExists(FPatternsFileName)) then 84 | cbPattern.Items.LoadFromFile(FPatternsFileName); 85 | 86 | for i := 0 to Installations.Count - 1 do 87 | AddDelphiInstallation(Installations.Installations[i]); 88 | 89 | if cbDelphiVersions.Items.Count > 0 then 90 | cbDelphiVersionsChange(cbDelphiVersions) 91 | else begin 92 | cbDelphiVersions.AddItem('[No Delphi Version Installed]', nil); 93 | cbDelphiVersions.ItemIndex := 0; 94 | end; 95 | end; 96 | 97 | procedure TSelectFoldersPage.FormClose(Sender: TObject; 98 | var Action: TCloseAction); 99 | begin 100 | inherited; 101 | if cbPattern.Items.IndexOf(cbPattern.Text) = -1 then 102 | cbPattern.Items.Add(cbPattern.Text); 103 | 104 | FCompilationData.BaseFolder := edtBaseFolder.Text; 105 | FCompilationData.Pattern := cbPattern.Text; 106 | fCompilationData.PackageList.Clear; 107 | 108 | if FileExists(FPatternsFileName) then 109 | JclFileUtils.CreateEmptyFile(FPatternsFileName); 110 | 111 | cbPattern.Items.SaveToFile(FPatternsFileName); 112 | end; 113 | 114 | procedure TSelectFoldersPage.AddDelphiInstallation(const installation: TJclBorRADToolInstallation); 115 | var 116 | i: integer; 117 | begin 118 | i := cbDelphiVersions.Items.Add(installation.Description); 119 | cbDelphiVersions.Items.Objects[i] := installation; 120 | if not Assigned(fCompilationData.Installation) then 121 | exit; 122 | 123 | if installation.VersionNumberStr = fCompilationData.Installation.VersionNumberStr then 124 | cbDelphiVersions.ItemIndex := i; 125 | end; 126 | 127 | procedure TSelectFoldersPage.UpdateWizardState; 128 | var 129 | action: TAction; 130 | begin 131 | inherited; 132 | wizard.SetHeader(_('Select Folders')); 133 | wizard.SetDescription(_('Please select folders which contains the packages that you want to install')); 134 | 135 | action := wizard.GetAction(wbtNext); 136 | action.Enabled := (edtBaseFolder.Text <> '') and (Installations.Count > 0) ; 137 | end; 138 | 139 | procedure TSelectFoldersPage.btnSelectFolderClick(Sender: TObject); 140 | var 141 | directory: string; 142 | begin 143 | inherited; 144 | directory := edtBaseFolder.Text; 145 | if SelectDirectory(_('Select the folder where packages are'),'',directory) then 146 | begin 147 | edtBaseFolder.Text := directory; 148 | UpdateWizardState; 149 | end; 150 | end; 151 | 152 | function TSelectFoldersPage.CanShowPage: Boolean; 153 | begin 154 | Result := not(fCompilationData.Scripting); 155 | end; 156 | 157 | procedure TSelectFoldersPage.cbDelphiVersionsChange(Sender: TObject); 158 | begin 159 | inherited; 160 | if (cbDelphiVersions.ItemIndex = -1) then 161 | cbDelphiVersions.ItemIndex := 0; 162 | 163 | if cbDelphiVersions.Items.Count > 0 then 164 | fCompilationData.Installation := cbDelphiVersions.Items.Objects[cbDelphiVersions.ItemIndex] as TJclBorRADToolInstallation; 165 | end; 166 | 167 | function TSelectFoldersPage.GetInstallations: TJclBorRADToolInstallations; 168 | begin 169 | if fInstallations = nil then 170 | fInstallations := TJclBorRADToolInstallations.Create; 171 | Result := fInstallations; 172 | end; 173 | 174 | end. 175 | -------------------------------------------------------------------------------- /PageProgress.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PageProgress; 7 | 8 | interface 9 | 10 | uses 11 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Vcl.Controls, Forms, 12 | Dialogs, PageBase, StdCtrls, ComCtrls, WizardIntfs, CompileThread, ProgressMonitor, PackageInfo; 13 | 14 | type 15 | TProgressPage = class(TWizardPage, IProgressMonitor) 16 | GroupBox1: TGroupBox; 17 | ProgressBar: TProgressBar; 18 | Label1: TLabel; 19 | lblPackage: TLabel; 20 | lblCurrentPackageNo: TLabel; 21 | memo: TRichEdit; 22 | btnCancel: TButton; 23 | chkShowFullLog: TCheckBox; 24 | procedure FormCreate(Sender: TObject); 25 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 26 | procedure btnCancelClick(Sender: TObject); 27 | procedure chkShowFullLogClick(Sender: TObject); 28 | private 29 | compileThreadWorking: Boolean; 30 | compileThread: TCompileThread; 31 | fFullLog : TStringList; 32 | protected 33 | procedure WriteInfo(const color: TColor; const info: string); 34 | public 35 | procedure Compile; 36 | procedure UpdateWizardState; override; 37 | procedure Finished; 38 | procedure Started; 39 | procedure CompilerOutput(const line: string); 40 | procedure PackageProcessed(const packageInfo: TPackageInfo; 41 | status: TPackageStatus); 42 | procedure Log(const text: string); 43 | 44 | end; 45 | 46 | var 47 | ProgressPage: TProgressPage; 48 | 49 | implementation 50 | uses gnugettext, StrUtils, JclStrings; 51 | var 52 | savedRtf: string; 53 | {$R *.dfm} 54 | 55 | { TProgressPage } 56 | 57 | procedure TProgressPage.FormCreate(Sender: TObject); 58 | begin 59 | inherited; 60 | TranslateComponent(self); 61 | lblPackage.Caption := ''; 62 | compileThreadWorking := false; 63 | fFullLog := TStringList.Create; 64 | chkShowFullLog.Enabled := false; 65 | Compile; 66 | end; 67 | 68 | procedure TProgressPage.FormClose(Sender: TObject; var Action: TCloseAction); 69 | begin 70 | inherited; 71 | if compileThreadWorking then begin 72 | compileThread.Cancel := true; 73 | compileThread.WaitFor; 74 | compileThread.Terminate; 75 | end; 76 | fFullLog.Free; 77 | end; 78 | 79 | procedure TProgressPage.UpdateWizardState; 80 | begin 81 | inherited; 82 | wizard.SetHeader(_('Compile and Install Packages')); 83 | wizard.SetDescription(_('Compiling packages that you have selected. Design time packages are going to be installed.')); 84 | with wizard.GetAction(wbtNext) do 85 | Enabled := not compileThreadWorking; 86 | 87 | with wizard.GetAction(wbtBack) do 88 | Enabled := not compileThreadWorking; 89 | btnCancel.Enabled := compileThreadWorking; 90 | chkShowFullLog.Enabled := not compileThreadWorking; 91 | end; 92 | 93 | procedure TProgressPage.WriteInfo(const color: TColor; const info: string); 94 | var 95 | oldColor: TColor; 96 | begin 97 | oldColor := memo.SelAttributes.Color; 98 | memo.SelAttributes.Color := color; 99 | memo.Lines.Add(info); 100 | memo.SelAttributes.Color := oldColor; 101 | memo.SelStart := Length(memo.Text); 102 | end; 103 | 104 | 105 | procedure TProgressPage.btnCancelClick(Sender: TObject); 106 | begin 107 | inherited; 108 | CompileThread.Cancel := true; 109 | end; 110 | 111 | procedure TProgressPage.chkShowFullLogClick(Sender: TObject); 112 | var 113 | line: string; 114 | begin 115 | inherited; 116 | if chkShowFullLog.Checked then 117 | begin 118 | savedRtf := memo.Text; 119 | memo.Clear; 120 | for line in fFullLog do 121 | begin 122 | if StartsStr('-=',line) then 123 | begin 124 | memo.SelAttributes.Size := 12; 125 | memo.SelAttributes.Style := [fsBold]; 126 | memo.Lines.Add(Copy(line,3,length(line)-2)); 127 | end else begin 128 | memo.SelAttributes.Size := 8; 129 | memo.SelAttributes.Style := []; 130 | memo.Lines.Add(line); 131 | end; 132 | end; 133 | end else begin 134 | memo.Text := savedRtf; 135 | end; 136 | end; 137 | 138 | procedure TProgressPage.Compile; 139 | begin 140 | ProgressBar.Max := fCompilationData.PackageList.Count; 141 | compileThread := TCompileThread.Create(fCompilationData); 142 | compileThread.Monitor := Self as IProgressMonitor; 143 | with compileThread do begin 144 | FreeOnTerminate := true; 145 | compileThreadWorking := true; 146 | Resume; 147 | end; 148 | end; 149 | 150 | procedure TProgressPage.Log(const text: string); 151 | begin 152 | fFullLog.Add(text); 153 | end; 154 | 155 | procedure TProgressPage.PackageProcessed(const packageInfo: TPackageInfo; 156 | status: TPackageStatus); 157 | begin 158 | case status of 159 | psNone: ; 160 | psCompiling: begin 161 | WriteInfo(clBlack, _('Compiling:') + packageInfo.PackageName); 162 | ProgressBar.StepBy(1); 163 | lblCurrentPackageNo.Caption := Format('%d/%d',[ProgressBar.Position,ProgressBar.Max]); 164 | end; 165 | psInstalling: WriteInfo(clBlue, _('Installing')); 166 | psSuccess: WriteInfo(clGreen, _('Successful')); 167 | psError: WriteInfo(clRed,_('Failed')); 168 | end; 169 | end; 170 | 171 | procedure TProgressPage.Started; 172 | begin 173 | ProgressBar.Position := 0; 174 | ProgressBar.Max := fCompilationData.PackageList.Count; 175 | end; 176 | 177 | procedure TProgressPage.CompilerOutput(const line: string); 178 | var 179 | S : String; 180 | begin 181 | S := Trim(line); 182 | if (Pos('Fatal:', S) > 0) or (Pos('Error', S) > 0) then 183 | WriteInfo(clRed, line); 184 | end; 185 | 186 | procedure TProgressPage.Finished; 187 | begin 188 | lblPackage.Caption :=''; 189 | ProgressBar.Position := 0; 190 | compileThreadWorking := false; 191 | WriteInfo(clBlack, _('*** Completed')); 192 | Wizard.UpdateInterface; 193 | end; 194 | 195 | 196 | end. 197 | -------------------------------------------------------------------------------- /FormWizard.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit FormWizard; 7 | 8 | interface 9 | 10 | uses 11 | CompilationData, Windows, Messages, SysUtils, Variants, Classes, Graphics, Vcl.Controls, Forms, 12 | Dialogs, StdCtrls, ExtCtrls, WizardIntfs, ActnList, System.Actions; 13 | 14 | type 15 | TFrmWizard = class(TForm, IWizard) 16 | HeaderPanel: TPanel; 17 | LogoImage: TImage; 18 | lblHeader: TLabel; 19 | lblDescription: TLabel; 20 | DockPanel: TPanel; 21 | pBottom: TPanel; 22 | btnBack: TButton; 23 | btnNext: TButton; 24 | btnAbout: TButton; 25 | Bevel1: TBevel; 26 | actionList: TActionList; 27 | actNext: TAction; 28 | actBack: TAction; 29 | actAbout: TAction; 30 | 31 | procedure FormCreate(Sender: TObject); 32 | procedure actNextExecute(Sender: TObject); 33 | procedure actAboutExecute(Sender: TObject); 34 | procedure actBackExecute(Sender: TObject); 35 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 36 | private 37 | FCompilationData : TCompilationData; 38 | FBaseFolder: String; 39 | FStates : TStringList; 40 | procedure SetBaseFolder(const Value: String); 41 | protected 42 | procedure SelectPage(const pageNo: Integer); 43 | public 44 | class var Wizard: IWizard; 45 | procedure UpdateInterface; 46 | function GetAction(buttonType: TWizardButtonType): TAction; 47 | procedure SetDescription(const desc: string); 48 | procedure SetHeader(const header: string); 49 | function GetState(const key: string): TObject; 50 | procedure SetState(const key: string; const value:TObject); 51 | 52 | property BaseFolder: String read FBaseFolder write SetBaseFolder; 53 | end; 54 | var 55 | frmWizard: TfrmWizard; 56 | 57 | implementation 58 | uses FormAbout, PageBase, PageSelectFolders, PageCompilerOptions, 59 | PageProgress, PageShowPackageList, PageInstallHelpFiles, PageSummary, 60 | gnugettext; 61 | var 62 | Pages: array of TPageClass; 63 | CurPage: Byte; 64 | ActivePage : TWizardPage; 65 | 66 | {$R *.dfm} 67 | { TfrmWizard } 68 | 69 | 70 | procedure TfrmWizard.FormCreate(Sender: TObject); 71 | begin 72 | FCompilationData := TCompilationData.Create; 73 | FStates := TStringList.Create; 74 | 75 | TFrmWizard.Wizard := self as IWizard; 76 | self.Caption := Application.Title; 77 | if (ParamCount > 0) then 78 | FCompilationData.BaseFolder := ParamStr(1); 79 | SelectPage(0); 80 | TranslateComponent(self); 81 | end; 82 | 83 | procedure TFrmWizard.FormClose(Sender: TObject; var Action: TCloseAction); 84 | begin 85 | FCompilationData.Free; 86 | FStates.Free; 87 | end; 88 | 89 | procedure TFrmWizard.actAboutExecute(Sender: TObject); 90 | begin 91 | Application.CreateForm(TfrmAbout,frmAbout); 92 | frmAbout.ShowModal; 93 | frmAbout.Free; 94 | end; 95 | 96 | procedure TFrmWizard.actBackExecute(Sender: TObject); 97 | begin 98 | SelectPage(CurPage-1); 99 | end; 100 | 101 | procedure TFrmWizard.actNextExecute(Sender: TObject); 102 | begin 103 | if CurPage + 1 = Length(Pages) then 104 | Close 105 | else 106 | SelectPage(CurPage+1); 107 | end; 108 | 109 | function TFrmWizard.GetAction(buttonType: TWizardButtonType): TAction; 110 | begin 111 | Result := nil; 112 | case buttonType of 113 | wbtNext: Result := actNext; 114 | wbtBack: Result := actBack; 115 | end; 116 | end; 117 | 118 | function TFrmWizard.GetState(const key: string): TObject; 119 | var 120 | index: Integer; 121 | begin 122 | Result := nil; 123 | index := FStates.IndexOf(key); 124 | if index <> -1 then 125 | Result := FStates.Objects[index]; 126 | end; 127 | 128 | procedure TFrmWizard.SelectPage(const pageNo: Integer); 129 | begin 130 | if (pageNo < 0) then exit; 131 | if (pageNo > Length(Pages)) then 132 | Close; 133 | 134 | if(Assigned(ActivePage)) then begin 135 | ActivePage.Close; 136 | FreeAndNil(ActivePage); 137 | end; 138 | 139 | CurPage := pageNo; 140 | ActivePage := Pages[pageNo].Create(self,FCompilationData); 141 | if not ActivePage.CanShowPage then 142 | begin 143 | SelectPage(pageNo+1); 144 | exit; 145 | end; 146 | ActivePage.Wizard := self; 147 | UpdateInterface; 148 | 149 | ActivePage.ManualDock(DockPanel); 150 | ActivePage.Visible := true; 151 | ActivePage.SetFocus; 152 | end; 153 | 154 | procedure TFrmWizard.SetBaseFolder(const Value: String); 155 | begin 156 | FBaseFolder := Value; 157 | UpdateInterface; 158 | end; 159 | 160 | procedure TFrmWizard.SetDescription(const desc: string); 161 | begin 162 | lblDescription.Caption := desc; 163 | end; 164 | 165 | procedure TFrmWizard.SetHeader(const header: string); 166 | begin 167 | lblHeader.Caption := header; 168 | end; 169 | 170 | procedure TFrmWizard.SetState(const key: string; const value:TObject); 171 | var 172 | index: Integer; 173 | begin 174 | index := FStates.IndexOf(key); 175 | if index <> -1 then 176 | FStates.Objects[index] := value 177 | else 178 | FStates.AddObject(key, value); 179 | end; 180 | 181 | procedure TFrmWizard.UpdateInterface; 182 | begin 183 | if not assigned(ActivePage) then 184 | exit; 185 | actNext.Enabled := true; 186 | actNext.Visible := true; 187 | actNext.Caption := _('&Next >>'); 188 | actNext.OnUpdate := nil; 189 | 190 | actBack.Enabled := true; 191 | actBack.Visible := true; 192 | actBack.Caption := _('<< &Back'); 193 | actBack.OnUpdate := nil; 194 | 195 | ActivePage.UpdateWizardState; 196 | 197 | actBack.Enabled := actBack.Enabled and (CurPage > 0); 198 | // btnNext.Enabled := btnNext.Enabled; //and (CurPage < length(Pages)-1); 199 | end; 200 | 201 | initialization 202 | SetLength(Pages,5); 203 | Pages[0] := TSelectFoldersPage; 204 | Pages[1] := TSelectCompilerOptions; 205 | Pages[2] := TShowPackageListPage; 206 | Pages[3] := TProgressPage; 207 | // Pages[4] := TInstallHelpFilesPage; 208 | Pages[4] := TSummaryPage; 209 | end. 210 | -------------------------------------------------------------------------------- /PackageCompiler.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit PackageCompiler; 7 | 8 | interface 9 | uses JclIDEUtils, PackageInfo, PackageList, SysUtils, Classes, CompilationData, ProgressMonitor; 10 | 11 | type 12 | 13 | TPackageCompiler = class 14 | private 15 | fCompilationData: TCompilationData; 16 | fCancel: boolean; 17 | fSourceFilePaths: TStringList; 18 | 19 | function ConvertToShortPaths(const paths : TStringList): string; 20 | function GetInstallation: TJclBorRADToolInstallation; 21 | function GetPackageList: TPackageList; 22 | protected 23 | fExtraOptions: String; 24 | fAllPaths: TStringList; 25 | procedure PrepareExtraOptions; virtual; 26 | procedure ResolveHelpFiles(const compilationData: TCompilationData); 27 | procedure AddSourcePathsToIDE(const sourceFilePaths: TStrings; const installation: TJclBorRADToolInstallation); 28 | procedure ResolveSourcePaths; virtual; 29 | 30 | property Installation: TJclBorRADToolInstallation read GetInstallation; 31 | property PackageList: TPackageList read GetPackageList; 32 | public 33 | constructor Create(const compilationData: TCompilationData); virtual; 34 | destructor Destroy; override; 35 | 36 | procedure Compile; virtual; 37 | function CompilePackage(const packageInfo : TPackageInfo): Boolean; virtual; 38 | function InstallPackage(const packageInfo : TPackageInfo): Boolean; virtual; 39 | 40 | //Properties 41 | property Cancel: boolean read fCancel write fCancel; 42 | property SourceFilePaths: TStringList read fSourceFilePaths write fSourceFilePaths; 43 | property AllPaths: TStringList read fAllPaths; 44 | property ExtraOptions: string read fExtraOptions; 45 | end; 46 | 47 | implementation 48 | 49 | uses JclFileUtils, JclStrings; 50 | { TPackageCompiler } 51 | 52 | constructor TPackageCompiler.Create(const compilationData: TCompilationData); 53 | begin 54 | fCompilationData := compilationData; 55 | fSourceFilePaths := TStringList.Create; 56 | fAllPaths := TStringList.Create; 57 | fAllPaths.Delimiter := ';'; 58 | end; 59 | 60 | destructor TPackageCompiler.Destroy; 61 | begin 62 | fSourceFilePaths.Free; 63 | fAllPaths.Free; 64 | inherited; 65 | end; 66 | 67 | function TPackageCompiler.GetInstallation: TJclBorRADToolInstallation; 68 | begin 69 | Result := fCompilationData.Installation; 70 | end; 71 | 72 | function TPackageCompiler.GetPackageList: TPackageList; 73 | begin 74 | Result := fCompilationData.PackageList; 75 | end; 76 | 77 | procedure TPackageCompiler.Compile; 78 | var 79 | i: integer; 80 | info: TPackageInfo; 81 | compilationSuccessful: boolean; 82 | begin 83 | if SourceFilePaths.Count = 0 then 84 | ResolveSourcePaths; 85 | 86 | PrepareExtraOptions; 87 | 88 | AddSourcePathsToIDE(SourceFilePaths, fCompilationData.Installation); 89 | 90 | if fCompilationData.HelpFiles.Count = 0 then 91 | ResolveHelpFiles(fCompilationData); 92 | 93 | PackageList.SortList; 94 | for i := 0 to PackageList.Count - 1 do 95 | begin 96 | info := PackageList[i]; 97 | compilationSuccessful := CompilePackage(info); 98 | 99 | if compilationSuccessful and (not info.RunOnly) then 100 | InstallPackage(info); 101 | 102 | if fCancel then 103 | break; 104 | end; 105 | end; 106 | 107 | function TPackageCompiler.CompilePackage( 108 | const packageInfo: TPackageInfo): Boolean; 109 | begin 110 | Result := Installation.DCC32.MakePackage( 111 | packageInfo.filename, 112 | fCompilationData.BPLOutputFolder, 113 | fCompilationData.DCPOutputFolder, 114 | fExtraOptions); 115 | end; 116 | 117 | procedure TPackageCompiler.PrepareExtraOptions; 118 | var 119 | shortPaths: string; 120 | I: Integer; 121 | begin 122 | fAllPaths.Clear; 123 | ExtractStrings([';'],[' '],PWideChar(Installation.LibrarySearchPath[bpWin32]),fAllPaths); 124 | fAllPaths.Add(Installation.BPLOutputPath[bpWin32]); 125 | fAllPaths.AddStrings(SourceFilePaths); 126 | 127 | for I := 0 to fAllPaths.Count - 1 do 128 | fAllPaths[i] := Installation.SubstitutePath(StrTrimQuotes(fAllPaths[i])); 129 | fAllPaths.Add('c:\Program Files (x86)\Embarcadero\RAD Studio\9.0\source\rtl\common'); 130 | shortPaths := ConvertToShortPaths(fAllPaths); 131 | fExtraOptions := '-B -Q -CC'; 132 | fExtraOptions := fExtraOptions + ' -NSSystem;System.Win;WinAPI;Vcl;Vcl.Imaging;Data'; 133 | fExtraOptions := fExtraOptions + ' -I'+shortPaths; 134 | fExtraOptions := fExtraOptions + ' -U'+shortPaths; 135 | fExtraOptions := fExtraOptions + ' -O'+shortPaths; 136 | fExtraOptions := fExtraOptions + ' -R'+shortPaths; 137 | fExtraOptions := fExtraOptions + ' -N'+PathGetShortName(fCompilationData.DCUOutputFolder); 138 | if Length(fCompilationData.Conditionals) > 0 then 139 | fExtraOptions := fExtraOptions + ' -D'+fCompilationData.Conditionals; 140 | end; 141 | 142 | function TPackageCompiler.ConvertToShortPaths(const paths : TStringList):string; 143 | var 144 | path : string; 145 | begin 146 | Result := ''; 147 | for path in paths do 148 | Result := Result + StrDoubleQuote(PathGetShortName(path)) + ';'; 149 | end; 150 | 151 | function TPackageCompiler.InstallPackage( 152 | const packageInfo: TPackageInfo): Boolean; 153 | var 154 | BPLFileName : String; 155 | begin 156 | BPLFileName := PathAddSeparator(Installation.BPLOutputPath[bpWin32]) + PathExtractFileNameNoExt(packageInfo.FileName) + packageInfo.Suffix + '.bpl'; 157 | Result := Installation.RegisterPackage(BPLFileName, packageInfo.Description); 158 | end; 159 | 160 | procedure TPackageCompiler.ResolveSourcePaths; 161 | var 162 | i,j: integer; 163 | files, containedFiles: TStringList; 164 | fileExt: string; 165 | begin 166 | Assert(assigned(SourceFilePaths)); 167 | 168 | 169 | files := TStringList.Create; 170 | files.Sorted := true; 171 | files.Duplicates := dupIgnore; 172 | 173 | containedFiles := TStringList.Create; 174 | containedFiles.Sorted := true; 175 | containedFiles.Duplicates := dupIgnore; 176 | 177 | SourceFilePaths.Clear; 178 | SourceFilePaths.Sorted := true; 179 | SourceFilePaths.Duplicates := dupIgnore; 180 | 181 | for i := 0 to PackageList.Count - 1 do 182 | begin 183 | SourceFilePaths.Add(ExtractFileDir(PackageList[i].FileName)); 184 | for j := 0 to PackageList[i].ContainedFileList.Count - 1 do 185 | containedFiles.Add(ExtractFileName(PackageList[i].ContainedFileList[j])); 186 | end; 187 | 188 | AdvBuildFileList(PathAppend(fCompilationData.BaseFolder,'*.pas'), 189 | faAnyFile, 190 | files, 191 | amAny, 192 | [flFullnames, flRecursive], 193 | '', nil); 194 | 195 | AdvBuildFileList(PathAppend(fCompilationData.BaseFolder,'*.inc'), 196 | faAnyFile, 197 | files, 198 | amAny, 199 | [flFullnames, flRecursive], 200 | '', nil); 201 | 202 | for I := 0 to files.count - 1 do 203 | begin 204 | fileExt := UpperCase(ExtractFileExt(files[i])); 205 | if (containedFiles.IndexOf(ExtractFileName(files[i])) > 0) or (fileExt = '.INC') then 206 | begin 207 | SourceFilePaths.Add(ExtractFileDir(files[i])); 208 | end 209 | end; 210 | end; 211 | 212 | procedure TPackageCompiler.ResolveHelpFiles(const compilationData: TCompilationData); 213 | var 214 | files: TStringList; 215 | filename: string; 216 | begin 217 | assert(assigned(fCompilationData)); 218 | 219 | files := TStringList.Create; 220 | try 221 | AdvBuildFileList(compilationData.BaseFolder +'\*.hlp', 222 | faAnyFile, 223 | files, 224 | amAny, 225 | [flFullnames, flRecursive], 226 | '', nil); 227 | for filename in files do 228 | compilationData.HelpFiles.Add(filename); 229 | finally 230 | files.Free; 231 | end; 232 | end; 233 | 234 | procedure TPackageCompiler.AddSourcePathsToIDE(const sourceFilePaths: TStrings; const installation: TJclBorRADToolInstallation); 235 | var 236 | path : string; 237 | begin 238 | Assert(assigned(sourceFilePaths)); 239 | Assert(assigned(installation)); 240 | for path in sourceFilePaths do 241 | begin 242 | installation.AddToLibrarySearchPath(path, bpWin32); 243 | end; 244 | end; 245 | 246 | end. 247 | -------------------------------------------------------------------------------- /ScriptPersister.pas: -------------------------------------------------------------------------------- 1 | {** 2 | DelphiPI (Delphi Package Installer) 3 | Author : ibrahim dursun (ibrahimdursun gmail) 4 | License : GNU General Public License 2.0 5 | **} 6 | unit ScriptPersister; 7 | 8 | interface 9 | uses SysUtils, Classes, CompilationData, PackageInfoFactory; 10 | type 11 | //TODO: refactor: this class has more than one responsibility = scanner + script persister 12 | TScriptPersister = class 13 | private 14 | fLines: TStringList; 15 | fLine: String; 16 | fCurrentLine :integer; 17 | fPackageInfoFactory: TPackageInfoFactory; 18 | protected 19 | function IsSectionHeader(line: string):boolean; 20 | function GetSectionHeader(line: string):string; 21 | function ReadNextLine: string; 22 | procedure SetPackageList(compilationData: TCompilationData); 23 | procedure SetDelphiVersion(compilationData: TCompilationData); 24 | function HasNextLine: boolean; 25 | { Added: Ronald Siekman - 24 12 2008 } 26 | procedure SetLibrarySearchPath(compilationData: TCompilationData); 27 | public 28 | constructor Create(); 29 | destructor Destroy; override; 30 | 31 | function Load(const scriptFilePath: string):TCompilationData; 32 | procedure Save(const compilationData: TCompilationData; const scriptFilePath: string); 33 | private 34 | class var 35 | const Header_BaseFolder = 'base-folder'; 36 | const Header_DelphiVersion = 'delphi-version'; 37 | const Header_BPLOutputFolder = 'bpl-output-folder'; 38 | const Header_DCPOutputFolder = 'dcp-output-folder'; 39 | const Header_DCUOutputFolder = 'dcu-output-folder'; 40 | const Header_Packages = 'packages'; 41 | { Added: Ronald Siekman - 24 12 2008 } 42 | const Header_Library_Search_Paths = 'library-search-paths'; 43 | end; 44 | 45 | implementation 46 | uses JclStrings, JclFileUtils, JclIDEUtils, PackageInfo; 47 | type 48 | 49 | TScriptWriter = class(TStringList) 50 | procedure WriteHeader(header: string); 51 | procedure WriteDetail(line:string); 52 | end; 53 | 54 | { TScriptPersister } 55 | 56 | constructor TScriptPersister.Create(); 57 | begin 58 | fLines := TStringList.Create; 59 | 60 | { Changed: Ronald Siekman - 24 12 2008 } 61 | fPackageInfoFactory := TPackageInfoFactory.Create; 62 | end; 63 | 64 | destructor TScriptPersister.Destroy; 65 | begin 66 | fLines.Free; 67 | fPackageInfoFactory.Free; 68 | inherited; 69 | end; 70 | 71 | function TScriptPersister.GetSectionHeader(line: string): string; 72 | begin 73 | Result := StrLower(Copy(line, 1, Length(line)-1)); 74 | end; 75 | 76 | function TScriptPersister.HasNextLine: boolean; 77 | begin 78 | Result := fCurrentLine < fLines.Count; 79 | end; 80 | 81 | function TScriptPersister.IsSectionHeader(line: string): boolean; 82 | begin 83 | Result := (line[Length(line)] = ':') and (line[1] <> ' '); 84 | end; 85 | 86 | function TScriptPersister.Load( 87 | const scriptFilePath: string): TCompilationData; 88 | var 89 | header: String; 90 | begin 91 | Result := TCompilationData.Create; 92 | if not FileExists(scriptFilePath) then exit; 93 | fCurrentLine := 0; 94 | fLine := ''; 95 | { Changed: Ronald Siekman - 24 12 2008 } 96 | //fLines := TStringList.Create; 97 | fLines.LoadFromFile(scriptFilePath); 98 | try 99 | while HasNextLine do 100 | begin 101 | fLine := ReadNextLine; 102 | if IsSectionHeader(fLine) then 103 | begin 104 | Result.Scripting := True; 105 | header := GetSectionHeader(fLine); 106 | 107 | if header = Header_BaseFolder then 108 | Result.BaseFolder := ReadNextLine; 109 | if header = Header_DelphiVersion then 110 | SetDelphiVersion(Result); 111 | if header = Header_BPLOutputFolder then 112 | Result.BPLOutputFolder := ReadNextLine; 113 | if header = Header_DCPOutputFolder then 114 | Result.DCPOutputFolder := ReadNextLine; 115 | if header = Header_DCUOutputFolder then 116 | Result.DCUOutputFolder := ReadNextLine; 117 | if header = Header_Library_Search_Paths then 118 | SetLibrarySearchPath(Result); 119 | if header = Header_Packages then 120 | SetPackageList(Result); 121 | end; 122 | end; 123 | finally 124 | //FreeAndNil(fLines); 125 | end; 126 | end; 127 | function TScriptPersister.ReadNextLine: string; 128 | begin 129 | if not HasNextLine then begin 130 | Result := ''; 131 | exit; 132 | end; 133 | 134 | fLine := Trim(fLines[fCurrentLine]); 135 | inc(fCurrentLine); 136 | Result := fLine; 137 | end; 138 | 139 | procedure TScriptPersister.SetDelphiVersion(compilationData: TCompilationData); 140 | begin 141 | ReadNextLine; 142 | compilationData.SetDelphiVersion(fLine); 143 | end; 144 | 145 | procedure TScriptPersister.SetLibrarySearchPath( 146 | compilationData: TCompilationData); 147 | 148 | procedure SemiColonTextToStringList( const line: string; 149 | var List: TStringList ); 150 | var 151 | sValue: string; 152 | sLine: string; 153 | iPos: Integer; 154 | begin 155 | sValue := line; 156 | 157 | iPos := Pos(';', sValue); 158 | while not(iPos = 0) do 159 | begin 160 | sLine := Trim(Copy(sValue, 1, iPos-1)); 161 | List.Add(sLine); 162 | Delete(sValue, 1, iPos); 163 | iPos := Pos(';', sValue); 164 | end; 165 | 166 | sValue := Trim(sValue); 167 | if not(sValue = '') then 168 | begin 169 | List.Add(sValue); 170 | end; 171 | end; 172 | 173 | var 174 | line : string; 175 | slPaths: TStringList; 176 | begin 177 | { Added: Ronald Siekman - 24 12 2008 } 178 | if Assigned(compilationData.Installation) then 179 | begin 180 | slPaths := TStringList.Create; 181 | try 182 | SemiColonTextToStringList(compilationData.Installation.LibrarySearchPath[bpWin32], 183 | slPaths); 184 | 185 | while HasNextLine do 186 | begin 187 | line := ReadNextLine; 188 | if IsSectionHeader(line) then begin 189 | Dec(fCurrentLine); 190 | break; 191 | end; 192 | 193 | if (slPaths.IndexOf(line) = -1 ) then 194 | begin 195 | compilationData.Installation.AddToLibrarySearchPath(line, bpWin32); 196 | end; 197 | end; 198 | finally 199 | slPaths.Free; 200 | end; 201 | end; 202 | end; 203 | 204 | procedure TScriptPersister.SetPackageList(compilationData: TCompilationData); 205 | var 206 | line : string; 207 | folder : string; 208 | filePath : string; 209 | begin 210 | { Changed: Ronald Siekman - 24 12 2008 } 211 | folder := IncludeTrailingPathDelimiter(compilationData.BaseFolder); 212 | 213 | while HasNextLine do 214 | begin 215 | line := ReadNextLine; 216 | filePath := PathAppend(folder, line); 217 | if IsSectionHeader(line) then begin 218 | Dec(fCurrentLine); 219 | break; 220 | end; 221 | 222 | if FileExists( filePath ) then 223 | begin 224 | compilationData.PackageList.Add(fPackageInfoFactory.CreatePackageInfo(filePath)); 225 | end; 226 | end; 227 | end; 228 | 229 | procedure TScriptPersister.Save(const compilationData: TCompilationData; const scriptFilePath: string); 230 | var 231 | script: TScriptWriter; 232 | i: Integer; 233 | begin 234 | if compilationData = nil then exit; 235 | script := TScriptWriter.Create; 236 | try 237 | with compilationData, script do 238 | begin 239 | WriteHeader(Header_BaseFolder); 240 | WriteDetail(compilationData.BaseFolder); 241 | 242 | WriteHeader(Header_DelphiVersion); 243 | WriteDetail(compilationData.Installation.VersionNumberStr); 244 | 245 | WriteHeader(Header_BPLOutputFolder); 246 | WriteDetail(compilationData.BPLOutputFolder); 247 | 248 | WriteHeader(Header_DCPOutputFolder); 249 | WriteDetail(compilationData.DCPOutputFolder); 250 | 251 | WriteHeader(Header_DCUOutputFolder); 252 | WriteDetail(compilationData.DCUOutputFolder); 253 | 254 | WriteHeader(Header_Packages); 255 | for i := 0 to compilationData.PackageList.Count-1 do 256 | begin 257 | if PathIsChild(compilationData.PackageList[i].FileName, compilationData.BaseFolder) then 258 | begin 259 | WriteDetail(PathGetRelativePath(compilationData.BaseFolder,compilationData.PackageList[i].FileName)); 260 | end else 261 | begin 262 | WriteDetail(compilationData.PackageList[i].FileName); 263 | end; 264 | end; 265 | end; 266 | script.SaveToFile(scriptFilePath); 267 | finally 268 | script.Free; 269 | end; 270 | end; 271 | 272 | { TScriptWriter } 273 | 274 | procedure TScriptWriter.WriteDetail(line: string); 275 | begin 276 | self.Add(' ' + line); 277 | end; 278 | 279 | procedure TScriptWriter.WriteHeader(header: string); 280 | begin 281 | self.Add(header+':'); 282 | end; 283 | 284 | end. 285 | -------------------------------------------------------------------------------- /DelphiPIConsole.dproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | {D044B842-27AC-4C92-B20B-002C54D1D724} 4 | 16.0 5 | DelphiPIConsole.dpr 6 | Release 7 | DCC32 8 | None 9 | True 10 | Win32 11 | 3 12 | Console 13 | 14 | 15 | true 16 | 17 | 18 | true 19 | Base 20 | true 21 | 22 | 23 | true 24 | Base 25 | true 26 | 27 | 28 | true 29 | Base 30 | true 31 | 32 | 33 | true 34 | Cfg_1 35 | true 36 | true 37 | 38 | 39 | true 40 | Cfg_1 41 | true 42 | true 43 | 44 | 45 | true 46 | Base 47 | true 48 | 49 | 50 | None 51 | DelphiPIConsole 52 | 1055 53 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 54 | System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) 55 | DelphiPIConsole.exe 56 | 00400000 57 | x86 58 | false 59 | false 60 | false 61 | false 62 | false 63 | 64 | 65 | .\$(Platform)\$(Config) 66 | "c:\temp\alpha.delphipi" 1 67 | System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 68 | 1033 69 | 70 | 71 | x64.exe 72 | .\$(Platform)\$(Config) 73 | System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) 74 | 1033 75 | 76 | 77 | false 78 | RELEASE;$(DCC_Define) 79 | 0 80 | 0 81 | 82 | 83 | 62 84 | 0 85 | CompanyName=;FileDescription=;FileVersion=0.62.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 86 | 1033 87 | None 88 | 89 | 90 | 1033 91 | 92 | 93 | DEBUG;$(DCC_Define) 94 | 95 | 96 | 97 | MainSource 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | Cfg_2 115 | Base 116 | 117 | 118 | Base 119 | 120 | 121 | Cfg_1 122 | Base 123 | 124 | 125 | 126 | 127 | Delphi.Personality.12 128 | 129 | 130 | 131 | 132 | DelphiPIConsole.dpr 133 | 134 | 135 | False 136 | True 137 | False 138 | "c:\temp\alpha.delphipi" 1 139 | 140 | 141 | False 142 | False 143 | 1 144 | 0 145 | 0 146 | 0 147 | False 148 | False 149 | False 150 | False 151 | False 152 | 1055 153 | 1254 154 | 155 | 156 | 157 | 158 | 1.0.0.0 159 | 160 | 161 | 162 | 163 | 164 | 1.0.0.0 165 | 166 | 167 | 168 | File C:\Users\Public\Documents\Embarcadero\Studio\15.0\Bpl\MGAndroidVoice210.bpl not found 169 | File C:\Users\Public\Documents\Embarcadero\Studio\15.0\Bpl\dclMGAndroidVoice210.bpl not found 170 | Microsoft Office 2000 Sample Automation Server Wrapper Components 171 | Microsoft Office XP Sample Automation Server Wrapper Components 172 | 173 | 174 | False 175 | 176 | True 177 | True 178 | 179 | 180 | 12 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /Test/DelphiPITests.dproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | {7DAE4251-928A-4C37-B08E-D819D4925C2F} 4 | 16.0 5 | Release 6 | DCC32 7 | DelphiPITests.dpr 8 | VCL 9 | True 10 | Win32 11 | 3 12 | Application 13 | 14 | 15 | true 16 | 17 | 18 | true 19 | Base 20 | true 21 | 22 | 23 | true 24 | Base 25 | true 26 | 27 | 28 | true 29 | Base 30 | true 31 | 32 | 33 | true 34 | Cfg_1 35 | true 36 | true 37 | 38 | 39 | true 40 | Base 41 | true 42 | 43 | 44 | true 45 | Cfg_2 46 | true 47 | true 48 | 49 | 50 | DelphiPITests 51 | 1055 52 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 53 | Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) 54 | $(BDS)\Source\DUnit\src;$(DCC_UnitSearchPath) 55 | DelphiPITests.exe 56 | 00400000 57 | x86 58 | _CONSOLE_TESTRUNNER;$(DCC_Define) 59 | false 60 | false 61 | false 62 | . 63 | false 64 | false 65 | 66 | 67 | .\$(Platform)\$(Config) 68 | true 69 | DelphiPITests_Icon.ico 70 | System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 71 | 1033 72 | $(BDS)\bin\default_app.manifest 73 | 74 | 75 | true 76 | x64.exe 77 | .\$(Platform)\$(Config) 78 | 1033 79 | System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) 80 | DelphiPITests_Icon.ico 81 | $(BDS)\bin\default_app.manifest 82 | 83 | 84 | false 85 | RELEASE;$(DCC_Define) 86 | 0 87 | 0 88 | 89 | 90 | true 91 | 1033 92 | 93 | 94 | DEBUG;$(DCC_Define) 95 | 96 | 97 | true 98 | 1033 99 | 100 | 101 | 102 | MainSource 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | Cfg_2 122 | Base 123 | 124 | 125 | Base 126 | 127 | 128 | Cfg_1 129 | Base 130 | 131 | 132 | 133 | 134 | Delphi.Personality.12 135 | 136 | 137 | 138 | 139 | False 140 | True 141 | False 142 | 143 | 144 | False 145 | False 146 | 1 147 | 0 148 | 0 149 | 0 150 | False 151 | False 152 | False 153 | False 154 | False 155 | 1055 156 | 1254 157 | 158 | 159 | 160 | 161 | 1.0.0.0 162 | 163 | 164 | 165 | 166 | 167 | 1.0.0.0 168 | 169 | 170 | 171 | DelphiPITests.dpr 172 | 173 | 174 | Microsoft Office 2000 Sample Automation Server Wrapper Components 175 | Microsoft Office XP Sample Automation Server Wrapper Components 176 | 177 | 178 | 179 | DUnit / Delphi Win32 180 | GUI 181 | 182 | 183 | 184 | 185 | True 186 | True 187 | 188 | 189 | 12 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /po/default.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: PACKAGE VERSION\n" 9 | "POT-Creation-Date: 2008-09-12 21:51\n" 10 | "PO-Revision-Date: 2008-09-12 22:01+0200\n" 11 | "Last-Translator: ibrahim dursun\n" 12 | "MIME-Version: 1.0\n" 13 | "Content-Type: text/plain; charset=UTF-8\n" 14 | "Content-Transfer-Encoding: 8bit\n" 15 | "X-Generator: dxgettext 1.2.1\n" 16 | "Language-Team: \n" 17 | 18 | #. frmAbout..Caption 19 | #: FormAbout.dfm:5 20 | msgid "About DelphiPI" 21 | msgstr "" 22 | 23 | #. frmAbout..Font.Name 24 | #. frmAbout..GroupBox2..Label7..Font.Name 25 | #. frmAbout..GroupBox2..Label8..Font.Name 26 | #. frmAbout..GroupBox2..lblAuthorsWebsite..Font.Name 27 | #. frmAbout..GroupBox2..lblProjectWebsite..Font.Name 28 | #. frmWizard..Font.Name 29 | #. frmWizard..HeaderPanel..lblHeader..Font.Name 30 | #. WizardPage..Font.Name 31 | #. ProgressPage..GroupBox1..lblPackage..Font.Name 32 | #. ShowPackageListPage..fPackageTree..Header.Font.Name 33 | #: FormAbout.dfm:12 34 | #: FormAbout.dfm:52 35 | #: FormAbout.dfm:621 36 | #: FormAbout.dfm:656 37 | #: FormAbout.dfm:671 38 | #: FormWizard.dfm:13 39 | #: FormWizard.dfm:349 40 | #: PageBase.dfm:13 41 | #: PageProgress.dfm:34 42 | #: PageShowPackageList.dfm:17 43 | msgid "Tahoma" 44 | msgstr "" 45 | 46 | #. frmAbout..btnClose..Caption 47 | #: FormAbout.dfm:32 48 | msgid "Close" 49 | msgstr "" 50 | 51 | #. frmAbout..GroupBox2..Caption 52 | #: FormAbout.dfm:41 53 | msgid "Information" 54 | msgstr "" 55 | 56 | #. frmAbout..GroupBox2..Label7..Caption 57 | #: FormAbout.dfm:48 58 | msgid "Delphi Package Installer" 59 | msgstr "" 60 | 61 | #. frmAbout..GroupBox2..Label8..Caption 62 | #: FormAbout.dfm:617 63 | msgid "0.32 'Dainese'" 64 | msgstr "" 65 | 66 | #. frmAbout..GroupBox2..Label9..Caption 67 | #: FormAbout.dfm:630 68 | msgid "Version:" 69 | msgstr "" 70 | 71 | #. frmAbout..GroupBox2..Label10..Caption 72 | #: FormAbout.dfm:637 73 | msgid "Project Website:" 74 | msgstr "" 75 | 76 | #. frmAbout..GroupBox2..Label11..Caption 77 | #: FormAbout.dfm:644 78 | msgid "Author's name:" 79 | msgstr "" 80 | 81 | #. frmAbout..GroupBox2..lblAuthorsWebsite..Caption 82 | #: FormAbout.dfm:652 83 | msgid "http://www.thexpot.net" 84 | msgstr "" 85 | 86 | #. frmAbout..GroupBox2..lblProjectWebsite..Caption 87 | #: FormAbout.dfm:667 88 | msgid "http://delphipi.googlecode.com" 89 | msgstr "" 90 | 91 | #. frmAbout..GroupBox2..Label2..Caption 92 | #: FormAbout.dfm:681 93 | msgid "Author's website:" 94 | msgstr "" 95 | 96 | #. frmAbout..btnDonate..Caption 97 | #: FormAbout.dfm:696 98 | msgid "Donate to DelphiPI" 99 | msgstr "" 100 | 101 | #. frmWizard..Caption 102 | #: FormWizard.dfm:4 103 | msgid "Delphi PI" 104 | msgstr "" 105 | 106 | #. frmWizard..HeaderPanel..lblHeader..Caption 107 | #: FormWizard.dfm:345 108 | msgid "lblHeader" 109 | msgstr "" 110 | 111 | #. frmWizard..HeaderPanel..lblDescription..Caption 112 | #: FormWizard.dfm:358 113 | msgid "lblDescription" 114 | msgstr "" 115 | 116 | #. frmWizard..pBottom..btnBack..Caption 117 | #: FormWizard.dfm:385 118 | #: FormWizard.pas:150 119 | msgid "<< &Back" 120 | msgstr "" 121 | 122 | #. frmWizard..pBottom..btnNext..Caption 123 | #: FormWizard.dfm:396 124 | #: FormWizard.pas:146 125 | msgid "&Next >>" 126 | msgstr "" 127 | 128 | #. frmWizard..pBottom..btnAbout..Caption 129 | #: FormWizard.dfm:408 130 | msgid "About..." 131 | msgstr "" 132 | 133 | #. WizardPage..Caption 134 | #: PageBase.dfm:6 135 | msgid "WizardPage" 136 | msgstr "" 137 | 138 | #. InstallHelpFilesPage..Caption 139 | #: PageInstallHelpFiles.dfm:2 140 | msgid "InstallHelpFilesPage" 141 | msgstr "" 142 | 143 | #. InstallHelpFilesPage..Label1....Caption 144 | #: PageInstallHelpFiles.dfm:16 145 | msgid "DelphiPI has found some help files in the folder that you have selected. Would you like to install them as well?" 146 | msgstr "" 147 | 148 | #. InstallHelpFilesPage..helpFileList......Caption 149 | #: PageInstallHelpFiles.dfm:29 150 | msgid "Help File Name" 151 | msgstr "" 152 | 153 | #. InstallHelpFilesPage..btnInstallHelpFiles..Caption 154 | #: PageInstallHelpFiles.dfm:44 155 | msgid "Install Help Files" 156 | msgstr "" 157 | 158 | #. ProgressPage..Caption 159 | #: PageProgress.dfm:2 160 | msgid "ProgressPage" 161 | msgstr "" 162 | 163 | #. ProgressPage..GroupBox1..Caption 164 | #: PageProgress.dfm:13 165 | msgid "Overall Progress" 166 | msgstr "" 167 | 168 | #. ProgressPage..GroupBox1..Label1..Caption 169 | #: PageProgress.dfm:23 170 | msgid "Package:" 171 | msgstr "" 172 | 173 | #. ProgressPage..GroupBox1..lblPackage..Caption 174 | #: PageProgress.dfm:30 175 | msgid "lblPackage" 176 | msgstr "" 177 | 178 | #. ProgressPage..GroupBox1..lblCurrentPackageNo..Caption 179 | #: PageProgress.dfm:44 180 | msgid " " 181 | msgstr "" 182 | 183 | #. ProgressPage..GroupBox2..Caption 184 | #: PageProgress.dfm:61 185 | msgid "Compiler Output" 186 | msgstr "" 187 | 188 | #. ProgressPage..GroupBox2..Memo..Font.Name 189 | #: PageProgress.dfm:74 190 | msgid "Courier New" 191 | msgstr "" 192 | 193 | #. SelectDelphiInstallationPage..Caption 194 | #: PageSelectDelphiInstallation.dfm:3 195 | msgid "SelectDelphiInstallationPage" 196 | msgstr "" 197 | 198 | #. SelectDelphiInstallationPage..rgDelphiVersions..Caption 199 | #: PageSelectDelphiInstallation.dfm:14 200 | msgid "Installed Delphi Versions" 201 | msgstr "" 202 | 203 | #. SelectDelphiInstallationPage..grpOutputFolders..Caption 204 | #: PageSelectDelphiInstallation.dfm:25 205 | msgid "Output Folders" 206 | msgstr "" 207 | 208 | #. SelectDelphiInstallationPage..grpOutputFolders..lblBPLOutputFolder..Caption 209 | #: PageSelectDelphiInstallation.dfm:35 210 | msgid "BPL:" 211 | msgstr "" 212 | 213 | #. SelectDelphiInstallationPage..grpOutputFolders..lblDCP..Caption 214 | #: PageSelectDelphiInstallation.dfm:42 215 | msgid "DCP:" 216 | msgstr "" 217 | 218 | #. SelectDelphiInstallationPage..grpOutputFolders..btnBPLBrowse..Caption 219 | #. SelectDelphiInstallationPage..grpOutputFolders..btnDCPBrowse..Caption 220 | #. SelectFoldersPage..GroupBox2..btnSelectFolder..Caption 221 | #: PageSelectDelphiInstallation.dfm:58 222 | #: PageSelectDelphiInstallation.dfm:76 223 | #: PageSelectFolders.dfm:77 224 | msgid "..." 225 | msgstr "" 226 | 227 | #. SelectFoldersPage..Caption 228 | #: PageSelectFolders.dfm:2 229 | msgid "SelectFoldersPage" 230 | msgstr "" 231 | 232 | #. SelectFoldersPage..GroupBox1..Caption 233 | #: PageSelectFolders.dfm:13 234 | msgid "Pattern to select package files " 235 | msgstr "" 236 | 237 | #. SelectFoldersPage..GroupBox1..Label3..Caption 238 | #: PageSelectFolders.dfm:23 239 | msgid "Package File Pattern" 240 | msgstr "" 241 | 242 | #. SelectFoldersPage..GroupBox1..Label2....Caption 243 | #: PageSelectFolders.dfm:33 244 | msgid "Specify a pattern that matches for the package files that are suitable for your delphi installation. ie: *d7.dpk for Delphi 7" 245 | msgstr "" 246 | 247 | #. SelectFoldersPage..GroupBox1..cbPattern..Text 248 | #: PageSelectFolders.dfm:50 249 | msgid "*.dpk" 250 | msgstr "" 251 | 252 | #. SelectFoldersPage..GroupBox2..Caption 253 | #: PageSelectFolders.dfm:59 254 | msgid "Select Base Folder contains both Package and Source files" 255 | msgstr "" 256 | 257 | #. SelectFoldersPage..GroupBox2..Label1..Caption 258 | #: PageSelectFolders.dfm:69 259 | msgid "Base Folder" 260 | msgstr "" 261 | 262 | #. ShowPackageListPage..Caption 263 | #: PageShowPackageList.dfm:2 264 | msgid "ShowPackageListPage" 265 | msgstr "" 266 | 267 | #. ShowPackageListPage..fPackageTree......WideText 268 | #: PageShowPackageList.dfm:39 269 | msgid "Package" 270 | msgstr "" 271 | 272 | #. ShowPackageListPage..fPackageTree......WideText 273 | #: PageShowPackageList.dfm:44 274 | msgid "Description" 275 | msgstr "" 276 | 277 | #. ShowPackageListPage..fPackageTree......WideText 278 | #: PageShowPackageList.dfm:49 279 | msgid "Type" 280 | msgstr "" 281 | 282 | #. ShowPackageListPage..SelectPopupMenu..miSelectAll..Caption 283 | #: PageShowPackageList.dfm:56 284 | msgid "Select All" 285 | msgstr "" 286 | 287 | #. ShowPackageListPage..SelectPopupMenu..miUnselectAll..Caption 288 | #: PageShowPackageList.dfm:60 289 | msgid "Unselect All" 290 | msgstr "" 291 | 292 | #. ShowPackageListPage..SelectPopupMenu..N1..Caption 293 | #: PageShowPackageList.dfm:64 294 | msgid "-" 295 | msgstr "" 296 | 297 | #. ShowPackageListPage..SelectPopupMenu..miSelectMatching..Caption 298 | #: PageShowPackageList.dfm:67 299 | #: PageShowPackageList.pas:336 300 | msgid "Select Matching..." 301 | msgstr "" 302 | 303 | #. ShowPackageListPage..SelectPopupMenu..miUnselectMatching..Caption 304 | #: PageShowPackageList.dfm:71 305 | msgid "Unselect Matching..." 306 | msgstr "" 307 | 308 | #. SummaryPage..Caption 309 | #: PageSummary.dfm:2 310 | msgid "SummaryPage" 311 | msgstr "" 312 | 313 | #. SummaryPage..Label1....Caption 314 | #: PageSummary.dfm:17 315 | msgid "Would you like to save this installation as a script so that you can automate installation of these packages?" 316 | msgstr "" 317 | 318 | #. SummaryPage..Label2..Caption 319 | #: PageSummary.dfm:31 320 | msgid "Summary:" 321 | msgstr "" 322 | 323 | #. SummaryPage..btnSave..Caption 324 | #: PageSummary.dfm:39 325 | msgid "Save" 326 | msgstr "" 327 | 328 | #: ConsoleRunner.pas:51 329 | msgid "Compiling:" 330 | msgstr "" 331 | 332 | #: ConsoleRunner.pas:53 333 | msgid "Compiled :" 334 | msgstr "" 335 | 336 | #. Programmer's name for it: StrRUNONLY 337 | #: PackageInfo.pas:65 338 | msgid "{$RUNONLY" 339 | msgstr "" 340 | 341 | #. Programmer's name for it: StrDESCRIPTION 342 | #: PackageInfo.pas:66 343 | msgid "{$DESCRIPTION " 344 | msgstr "" 345 | 346 | #. Programmer's name for it: StrSUFFIX 347 | #: PackageInfo.pas:67 348 | msgid "{$LIBSUFFIX " 349 | msgstr "" 350 | 351 | #. Programmer's name for it: StrPackage 352 | #: PackageInfo.pas:68 353 | msgid "package" 354 | msgstr "" 355 | 356 | #. Programmer's name for it: StrRequires 357 | #: PackageInfo.pas:69 358 | msgid "requires" 359 | msgstr "" 360 | 361 | #. Programmer's name for it: StrContains 362 | #: PackageInfo.pas:70 363 | msgid "contains" 364 | msgstr "" 365 | 366 | #: PageInstallHelpFiles.pas:51 367 | msgid "No help files are found." 368 | msgstr "" 369 | 370 | #: PageInstallHelpFiles.pas:69 371 | msgid "Help Files" 372 | msgstr "" 373 | 374 | #: PageInstallHelpFiles.pas:70 375 | msgid "Select the help files that you want to register, if there are any." 376 | msgstr "" 377 | 378 | #: PageInstallHelpFiles.pas:90 379 | msgid "%d help file(s) are registered successfully" 380 | msgstr "" 381 | 382 | #: PageProgress.pas:90 383 | msgid "Compile and Install Packages" 384 | msgstr "" 385 | 386 | #: PageProgress.pas:91 387 | msgid "Compiling packages that you have selected. Design time packages are going to be installed." 388 | msgstr "" 389 | 390 | #. lblFileName.Caption := ''; 391 | #: PageProgress.pas:141 392 | msgid "*** Completed" 393 | msgstr "" 394 | 395 | #: PageSelectDelphiInstallation.pas:130 396 | msgid "Select output folder" 397 | msgstr "" 398 | 399 | #: PageSelectDelphiInstallation.pas:215 400 | msgid "Select Delphi Installation" 401 | msgstr "" 402 | 403 | #: PageSelectDelphiInstallation.pas:216 404 | msgid "Please select delphi installation that you want to compile with" 405 | msgstr "" 406 | 407 | #: PageSelectFolders.pas:49 408 | msgid "Select Folders" 409 | msgstr "" 410 | 411 | #: PageSelectFolders.pas:50 412 | msgid "Please select folders which contains the packages that you want to install" 413 | msgstr "" 414 | 415 | #: PageSelectFolders.pas:62 416 | msgid "Select the folder where packages are" 417 | msgstr "" 418 | 419 | #: PageShowPackageList.pas:209 420 | msgid "Select Packages" 421 | msgstr "" 422 | 423 | #: PageShowPackageList.pas:210 424 | msgid "Select packages that you want to compile." 425 | msgstr "" 426 | 427 | #: PageShowPackageList.pas:216 428 | msgid "Compile" 429 | msgstr "" 430 | 431 | #: PageShowPackageList.pas:246 432 | msgid "Designtime Package" 433 | msgstr "" 434 | 435 | #: PageShowPackageList.pas:248 436 | msgid "Runtime Package" 437 | msgstr "" 438 | 439 | #: PageShowPackageList.pas:249 440 | msgid "FullPath :" 441 | msgstr "" 442 | 443 | #: PageShowPackageList.pas:250 444 | msgid "Description:" 445 | msgstr "" 446 | 447 | #: PageShowPackageList.pas:251 448 | msgid "Type :" 449 | msgstr "" 450 | 451 | #: PageShowPackageList.pas:252 452 | msgid "Requires :" 453 | msgstr "" 454 | 455 | #: PageShowPackageList.pas:276 456 | msgid "runtime" 457 | msgstr "" 458 | 459 | #: PageShowPackageList.pas:278 460 | msgid "design" 461 | msgstr "" 462 | 463 | #: PageShowPackageList.pas:336 464 | #: PageShowPackageList.pas:355 465 | msgid "File Mask" 466 | msgstr "" 467 | 468 | #: PageShowPackageList.pas:355 469 | msgid "UnSelect Matching..." 470 | msgstr "" 471 | 472 | #: PageSummary.pas:46 473 | msgid "Base Folder:" 474 | msgstr "" 475 | 476 | #: PageSummary.pas:52 477 | msgid "Delphi Version:" 478 | msgstr "" 479 | 480 | #: PageSummary.pas:60 481 | msgid "Help Files:" 482 | msgstr "" 483 | 484 | #: PageSummary.pas:71 485 | msgid "Package List:" 486 | msgstr "" 487 | 488 | #: PageSummary.pas:84 489 | msgid "However, following packages had some errors:" 490 | msgstr "" 491 | 492 | #: PageSummary.pas:97 493 | msgid "Source File Paths:" 494 | msgstr "" 495 | 496 | #: PageSummary.pas:149 497 | msgid "Finished" 498 | msgstr "" 499 | 500 | #: PageSummary.pas:150 501 | msgid "Installation Summary" 502 | msgstr "" 503 | 504 | #: PageSummary.pas:152 505 | msgid "&Exit" 506 | msgstr "" 507 | 508 | -------------------------------------------------------------------------------- /setup/LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | --------------------------------------------------------------------------------