diff --git a/windows/src/Defines.mak b/windows/src/Defines.mak index f88d4b34f5..275d188b47 100644 --- a/windows/src/Defines.mak +++ b/windows/src/Defines.mak @@ -35,6 +35,7 @@ INSTALLPATH_KEYMANENGINE=%CommonProgramFiles(X86)%\Keyman\Keyman Engine 10.0 !IFDEF USE_PLUSMEMO MAKEFLAG_USE_PLUSMEMO=-DUSE_PLUSMEMO + DELPHI_MSBUILD_FLAG_USE_PLUSMEMO=/p:USE_PLUSMEMO=USE_PLUSMEMO !ENDIF !IFDEF DELPHI_STARTER @@ -116,6 +117,8 @@ DCC32DPK=@$(DEVTOOLS) -dcc $(DELPHIDPKPARAMS) $(MAKEFLAG_USE_PLUSMEMO) DCC64=dcc64.exe $(DELPHIDPRPARAMS64) -N0x64\ -Ex64\ +DELPHI_MSBUILD=$(ROOT)\src\buildtools\msbuild-wrapper.bat $(DELPHI_MSBUILD_FLAG_USE_PLUSMEMO) + # # Other program build commands # diff --git a/windows/src/Makefile b/windows/src/Makefile index 4c10fefa26..fcddbf72cc 100644 --- a/windows/src/Makefile +++ b/windows/src/Makefile @@ -29,7 +29,7 @@ default: TARGETS=ext global buildtools developer engine desktop support RELEASE_TARGETS=desktop -CLEANS=test cleanroot +CLEANS=test cleanroot unit-tests MANIFESTS=engine desktop developer EXCLUDEPATHDEFINES=1 @@ -83,6 +83,11 @@ test: $(MAKE) $(TARGET) cd $(ROOT)\src +unit-tests: + cd $(ROOT)\src\unit-tests + $(MAKE) $(TARGET) + cd $(ROOT)\src + # ---------------------------------------------------------------------- # release # ---------------------------------------------------------------------- @@ -161,7 +166,7 @@ update-version: build-tools mkver-app build-release-wrapper: clean-output update-version $(MAKE) dirs $(MAKE) build-tools - $(MAKE) build + $(MAKE) build unit-tests $(MAKE) build-release $(MAKE) signcode $(MAKE) -DTARGET=test test diff --git a/windows/src/buildtools/msbuild-wrapper.bat b/windows/src/buildtools/msbuild-wrapper.bat new file mode 100644 index 0000000000..57d4c5deaa --- /dev/null +++ b/windows/src/buildtools/msbuild-wrapper.bat @@ -0,0 +1,12 @@ +@echo off + +rem +rem This wrapper is for Delphi msbuild calls only. It sets up the msbuild environment +rem for Delphi, which is not compatible with the VS msbuild environment. +rem +rem Do not use this for VS builds. +rem + +call rsvars.bat +msbuild.exe %* +exit /b %errorlevel% diff --git a/windows/src/global/delphi/general/PackageInfo.pas b/windows/src/global/delphi/general/PackageInfo.pas index 70d1678024..d6619e0e53 100644 --- a/windows/src/global/delphi/general/PackageInfo.pas +++ b/windows/src/global/delphi/general/PackageInfo.pas @@ -41,7 +41,6 @@ uses System.Generics.Collections, System.IniFiles, System.Sysutils, - Vcl.Graphics, Winapi.Windows, Xml.XMLDoc, Xml.XMLIntf, @@ -81,13 +80,27 @@ type pfclInstallTemp, // Used only for installation, temporary pfclLocaleFolder); // For locale files + + TPackage = class; + + { Base Classes } + TPackageBaseObject = class + strict private + FPackage: TPackage; + protected + property Package: TPackage read FPackage; + public + constructor Create(APackage: TPackage); virtual; + end; + + TPackageBaseNotifyObject = class(TPackageBaseObject) private FNotifyObjects: TObjectList; FTag: Integer; function Notify(EventType: TPackageNotifyEventType): Boolean; public - constructor Create; + constructor Create(APackage: TPackage); override; destructor Destroy; override; procedure AddNotifyObject(FEventHandler: TPackageNotifyEvent); procedure RemoveNotifyObject(FEventHandler: TPackageNotifyEvent); @@ -95,7 +108,16 @@ type property Tag: Integer read FTag write FTag; end; - TPackage = class; + TPackageObjectList = class(TObjectList) + strict private + FPackage: TPackage; + protected + property Package: TPackage read FPackage; + public + constructor Create(APackage: TPackage); + end; + + TPackageContentFile = class; TPackageContentFileList = class; @@ -103,16 +125,15 @@ type TPackageRegistryKeyValueType = (rkvtString, rkvtDWord); - TPackageRegistryKey = class + TPackageRegistryKey = class(TPackageBaseObject) private - FPackage: TPackage; FKey: WideString; FValueType: TPackageRegistryKeyValueType; FValue: WideString; FRoot: HKEY; FName: WideString; public // I3311 - constructor Create(APackage: TPackage); + constructor Create(APackage: TPackage); override; destructor Destroy; override; procedure Assign(Source: TPackageRegistryKey); property Key: WideString read FKey write FKey; @@ -122,11 +143,8 @@ type property ValueType: TPackageRegistryKeyValueType read FValueType write FValueType; end; - TPackageRegistryKeyList = class(TObjectList) - private - FPackage: TPackage; + TPackageRegistryKeyList = class(TPackageObjectList) public - constructor Create(APackage: TPackage); procedure Assign(Source: TPackageRegistryKeyList); virtual; procedure LoadIni(AIni: TIniFile); virtual; procedure SaveIni(AIni: TIniFile); virtual; @@ -136,9 +154,8 @@ type { Package Options } - TPackageOptions = class + TPackageOptions = class(TPackageBaseObject) private - FPackage: TPackage; FFileVersion: WideString; FExecuteProgram: WideString; FReadmeFile: TPackageContentFile; @@ -153,12 +170,10 @@ type EventType: TPackageNotifyEventType; var FAllow: Boolean); procedure ReadmeRemoved(Sender: TObject; EventType: TPackageNotifyEventType; var FAllow: Boolean); - protected - property Package: TPackage read FPackage; public - procedure Assign(Source: TPackageOptions); virtual; - constructor Create(APackage: TPackage); virtual; + constructor Create(APackage: TPackage); override; destructor Destroy; override; + procedure Assign(Source: TPackageOptions); virtual; procedure LoadIni(AIni: TIniFile); virtual; procedure SaveIni(AIni: TIniFile); virtual; procedure LoadXML(ARoot: IXMLNode); virtual; @@ -174,9 +189,8 @@ type { Package Information } - TPackageInfoEntry = class + TPackageInfoEntry = class(TPackageBaseObject) private - FPackage: TPackage; FURL: WideString; FDescription: WideString; FName: WideString; @@ -185,7 +199,6 @@ type procedure SetName(Value: WideString); procedure SetURL(Value: WideString); public - constructor Create(APackage: TPackage); procedure Assign(Source: TPackageInfoEntry); virtual; property InfoType: TPackageInfoEntryType read FInfoType; property Name: WideString read FName write SetName; @@ -193,16 +206,13 @@ type property URL: WideString read FURL write SetURL; end; - TPackageInfoEntryList = class(TObjectList) - private - FPackage: TPackage; + TPackageInfoEntryList = class(TPackageObjectList) protected procedure SetDesc(Name, Desc: WideString); procedure SetURL(Name, URL: WideString); function DescIndexOf(Name: WideString): WideString; function UrlIndexOf(Name: WideString): WideString; public - constructor Create(APackage: TPackage); procedure Assign(Source: TPackageInfoEntryList); virtual; procedure LoadIni(AIni: TIniFile); virtual; procedure SaveIni(AIni: TIniFile); virtual; @@ -213,32 +223,24 @@ type property Desc[Name: WideString]: WideString read DescIndexOf write SetDesc; property URL[Name: WideString]: WideString read URLIndexOf write SetURL; - - function Add(Item: TPackageInfoEntry): Integer; end; { Package Start Menu Classes } TPackageStartMenuEntryLocation = (psmelStartMenu, psmelDesktop); //, psmelQuickLaunch); - TPackageStartMenuEntry = class - private - FPackage: TPackage; + TPackageStartMenuEntry = class(TPackageBaseObject) public Name: WideString; Prog: WideString; Params: WideString; Icon: WideString; Location: TPackageStartMenuEntryLocation; - constructor Create(APackage: TPackage); procedure Assign(Source: TPackageStartMenuEntry); virtual; end; - TPackageStartMenuEntryList = class(TObjectList) - private - FPackage: TPackage; + TPackageStartMenuEntryList = class(TPackageObjectList) public - constructor Create(APackage: TPackage); procedure Assign(Source: TPackageStartMenuEntryList); virtual; procedure LoadIni(AIni: TIniFile); virtual; procedure SaveIni(AIni: TIniFile); virtual; @@ -246,15 +248,13 @@ type procedure SaveXML(ARoot: IXMLNode); virtual; end; - TPackageStartMenu = class - private - FPackage: TPackage; + TPackageStartMenu = class(TPackageBaseObject) public Path: WideString; DoCreate: Boolean; AddUninstallEntry: Boolean; Entries: TPackageStartMenuEntryList; - constructor Create(APackage: TPackage); + constructor Create(APackage: TPackage); override; destructor Destroy; override; procedure Assign(Source: TPackageStartMenu); virtual; procedure LoadIni(AIni: TIniFile); virtual; @@ -265,9 +265,8 @@ type { Package contained files } - TPackageContentFile = class(TPackageBaseObject) + TPackageContentFile = class(TPackageBaseNotifyObject) private - FPackage: TPackage; FCopyLocation: TPackageFileCopyLocation; FDescription: WideString; FFileName: WideString; @@ -277,22 +276,16 @@ type procedure SetFileType(const Value: TKMFileType); procedure SetCopyLocation(const Value: TPackageFileCopyLocation); public - constructor Create(APackage: TPackage); procedure Assign(Source: TPackageContentFile); virtual; function RelativeFileName: WideString; property FileName: WideString read FFileName write SetFileName; // relative to .kps, or no path if inside .kmp or .exe property FileType: TKMFileType read FFileType write SetFileType; property Description: WideString read FDescription write SetDescription; property CopyLocation: TPackageFileCopyLocation read FCopyLocation write SetCopyLocation; - property Package: TPackage read FPackage; end; - TPackageContentFileList = class(TObjectList) - private - FPackage: TPackage; - + TPackageContentFileList = class(TPackageObjectList) public - constructor Create(APackage: TPackage); procedure Assign(Source: TPackageContentFileList); virtual; procedure LoadIni(AIni: TIniFile); virtual; procedure SaveIni(AIni: TIniFile); virtual; @@ -305,6 +298,57 @@ type procedure Delete(Index: Integer); end; + { TPackageKeyboard } + + TPackageKeyboard = class; + TPackageKeyboardList = class; + TPackageKeyboardLanguage = class; + TPackageKeyboardLanguageList = class; + + TPackageKeyboard = class(TPackageBaseObject) + private + FName: string; + FOSKFont: TPackageContentFile; + FID: string; + FDisplayFont: TPackageContentFile; + FLanguages: TPackageKeyboardLanguageList; + FVersion: string; + procedure SetDisplayFont(const Value: TPackageContentFile); + procedure SetOSKFont(const Value: TPackageContentFile); + procedure DisplayFontRemoved(Sender: TObject; + EventType: TPackageNotifyEventType; var FAllow: Boolean); + procedure OSKFontRemoved(Sender: TObject; + EventType: TPackageNotifyEventType; var FAllow: Boolean); + public + constructor Create(APackage: TPackage); override; + destructor Destroy; override; + procedure Assign(Source: TPackageKeyboard); virtual; + property Name: string read FName write FName; + property ID: string read FID write FID; + property Version: string read FVersion write FVersion; + property Languages: TPackageKeyboardLanguageList read FLanguages; + property OSKFont: TPackageContentFile read FOSKFont write SetOSKFont; + property DisplayFont: TPackageContentFile read FDisplayFont write SetDisplayFont; + end; + + TPackageKeyboardList = class(TPackageObjectList) + public + procedure Assign(Source: TPackageKeyboardList); virtual; + procedure LoadIni(AIni: TIniFile); virtual; + procedure SaveIni(AIni: TIniFile); virtual; + procedure LoadXML(ARoot: IXMLNode); virtual; + procedure SaveXML(ARoot: IXMLNode); virtual; + end; + + TPackageKeyboardLanguage = class(TPackageBaseObject) + ID: string; + Name: string; + end; + + TPackageKeyboardLanguageList = class(TPackageObjectList); + + { TPackage } + TPackage = class private FFileName: WideString; @@ -320,6 +364,7 @@ type StartMenu: TPackageStartMenu; Files: TPackageContentFileList; Info: TPackageInfoEntryList; + Keyboards: TPackageKeyboardList; property FileName: WideString read FFileName write FFileName; procedure Assign(Source: TPackage); virtual; @@ -358,6 +403,8 @@ const SReadmeNotOwnedCorrectly = 'The readme file ''%s'' referred to is not part of the package.'; SGraphicNotOwnedCorrectly = 'The graphic file ''%s'' referred to is not part of the package.'; SFileNotOwnedCorrectly = 'The file ''%s'' referred to is not part of the package.'; + SDisplayFontNotOwnedCorrectly = 'The display font file ''%s'' referred to is not part of the package.'; + SOSKFontNotOwnedCorrectly = 'The OSK font file ''%s'' referred to is not part of the package.'; {------------------------------------------------------------------------------- - TPackageOptions - @@ -368,21 +415,20 @@ begin FFileVersion := Source.FileVersion; FExecuteProgram := Source.ExecuteProgram; if Assigned(Source.ReadmeFile) - then ReadmeFile := FPackage.Files.FromFileName(Source.ReadmeFile.FileName) + then ReadmeFile := Package.Files.FromFileName(Source.ReadmeFile.FileName) else ReadmeFile := nil; if Assigned(Source.GraphicFile) - then GraphicFile := FPackage.Files.FromFileName(Source.GraphicFile.FileName) + then GraphicFile := Package.Files.FromFileName(Source.GraphicFile.FileName) else GraphicFile := nil; FRegistryKeys.Assign(Source.RegistryKeys); end; constructor TPackageOptions.Create(APackage: TPackage); begin - inherited Create; + inherited Create(APackage); FLoadLegacy := True; - FPackage := APackage; - FRegistryKeys := TPackageRegistryKeyList.Create(FPackage); - FFileVersion := SKeymanVersion; + FRegistryKeys := TPackageRegistryKeyList.Create(Package); + FFileVersion := SKeymanVersion70; end; destructor TPackageOptions.Destroy; @@ -407,8 +453,8 @@ procedure TPackageOptions.LoadXML(ARoot: IXMLNode); begin FileVersion := VarToWideStr(ARoot.ChildNodes['System'].ChildNodes['FileVersion'].NodeValue); ExecuteProgram := VarToWideStr(ARoot.ChildNodes['Options'].ChildNodes['ExecuteProgram'].NodeValue); - ReadmeFile := FPackage.Files.FromFileName(VarToWideStr(ARoot.ChildNodes['Options'].ChildNodes['ReadMeFile'].NodeValue)); - GraphicFile := FPackage.Files.FromFileName(VarToWideStr(ARoot.ChildNodes['Options'].ChildNodes['GraphicFile'].NodeValue)); + ReadmeFile := Package.Files.FromFileName(VarToWideStr(ARoot.ChildNodes['Options'].ChildNodes['ReadMeFile'].NodeValue)); + GraphicFile := Package.Files.FromFileName(VarToWideStr(ARoot.ChildNodes['Options'].ChildNodes['GraphicFile'].NodeValue)); if Assigned(ReadmeFile) then ReadmeFile.AddNotifyObject(ReadmeRemoved); if Assigned(GraphicFile) then GraphicFile.AddNotifyObject(GraphicRemoved); FRegistryKeys.LoadXML(ARoot); @@ -429,8 +475,8 @@ procedure TPackageOptions.LoadIni(AIni: TIniFile); begin FileVersion := AIni.ReadString('Package', 'Version', ''); ExecuteProgram := AIni.ReadString('Package', 'ExecuteProgram', ''); - ReadmeFile := FPackage.Files.FromFileName(AIni.ReadString('Package', 'ReadMeFile', '')); - GraphicFile := FPackage.Files.FromFileName(AIni.ReadString('Package', 'GraphicFile', '')); + ReadmeFile := Package.Files.FromFileName(AIni.ReadString('Package', 'ReadMeFile', '')); + GraphicFile := Package.Files.FromFileName(AIni.ReadString('Package', 'GraphicFile', '')); if Assigned(ReadmeFile) then ReadmeFile.AddNotifyObject(ReadmeRemoved); if Assigned(GraphicFile) then GraphicFile.AddNotifyObject(GraphicRemoved); FRegistryKeys.LoadIni(AIni); @@ -466,7 +512,7 @@ begin FGraphicFile := nil else begin - if Value.FPackage <> FPackage then raise EPackageInfo.CreateFmt(SGraphicNotOwnedCorrectly, [Value]); + if Value.Package <> Package then raise EPackageInfo.CreateFmt(SGraphicNotOwnedCorrectly, [Value]); FGraphicFile := Value; FGraphicFile.AddNotifyObject(GraphicRemoved); end; @@ -479,7 +525,7 @@ begin FReadmeFile := nil else begin - if Value.FPackage <> FPackage then raise EPackageInfo.CreateFmt(SReadmeNotOwnedCorrectly, [Value]); + if Value.Package <> Package then raise EPackageInfo.CreateFmt(SReadmeNotOwnedCorrectly, [Value]); FReadmeFile := Value; FReadmeFile.AddNotifyObject(ReadmeRemoved); end; @@ -497,12 +543,6 @@ begin FInfoType := Source.InfoType; end; -constructor TPackageInfoEntry.Create(APackage: TPackage); -begin - inherited Create; - FPackage := APackage; -end; - procedure TPackageInfoEntry.SetDescription(Value: WideString); begin FDescription := Value; @@ -540,7 +580,7 @@ begin for i := 0 to ARoot.ChildNodes.Count - 1 do begin ANode := ARoot.ChildNodes[i]; - inf := TPackageInfoEntry.Create(FPackage); + inf := TPackageInfoEntry.Create(Package); inf.Name := ANode.NodeName; inf.Description := VarToWideStr(ANode.NodeValue); inf.URL := VarToWideStr(ANode.Attributes['URL']); @@ -578,7 +618,7 @@ begin description := CommaToken(t); url := CommaToken(t); - inf := TPackageInfoEntry.Create(FPackage); + inf := TPackageInfoEntry.Create(Package); inf.Name := s[i]; inf.Description := description; inf.URL := url; @@ -623,7 +663,7 @@ begin i := IndexOf(Name); if i = -1 then begin - inf := TPackageInfoEntry.Create(FPackage); + inf := TPackageInfoEntry.Create(Package); inf.Name := Name; Add(inf); end @@ -640,7 +680,7 @@ begin i := IndexOf(Name); if i = -1 then begin - inf := TPackageInfoEntry.Create(FPackage); + inf := TPackageInfoEntry.Create(Package); inf.Name := Name; Add(inf); end @@ -658,12 +698,6 @@ begin if WideLowerCase(Items[i].Name) = WideLowerCase(Name) then Result := i; end; -constructor TPackageInfoEntryList.Create(APackage: TPackage); -begin - inherited Create; - FPackage := APackage; -end; - procedure TPackageInfoEntryList.Assign(Source: TPackageInfoEntryList); var i: Integer; @@ -672,7 +706,7 @@ begin Clear; for i := 0 to Source.Count - 1 do begin - pie := TPackageInfoEntry.Create(FPackage); + pie := TPackageInfoEntry.Create(Package); pie.Assign(Source[i]); Add(pie); end; @@ -691,12 +725,6 @@ begin Location := Source.Location; end; -constructor TPackageStartMenuEntry.Create(APackage: TPackage); -begin - inherited Create; - FPackage := APackage; -end; - {------------------------------------------------------------------------------- - TPackageStartMenuEntryList - ------------------------------------------------------------------------------} @@ -722,7 +750,7 @@ begin begin with ANode.ChildNodes[i] do begin - sme := TPackageStartMenuEntry.Create(FPackage); + sme := TPackageStartMenuEntry.Create(Package); sme.Name := VarToWideStr(ChildNodes['Name'].NodeValue); sme.Prog := VarToWideStr(ChildNodes['FileName'].NodeValue); sme.Params := VarToWideStr(ChildNodes['Arguments'].NodeValue); @@ -766,7 +794,7 @@ begin prog := CommaToken(t); params := CommaToken(t); - sme := TPackageStartMenuEntry.Create(FPackage); + sme := TPackageStartMenuEntry.Create(Package); sme.Name := s[i]; sme.Prog := prog; sme.Params := params; @@ -785,12 +813,6 @@ begin AIni.WriteString('StartMenuEntries', Items[i].Name, Format('"%s","%s"', [Items[i].Prog, Items[i].Params])); end; -constructor TPackageStartMenuEntryList.Create(APackage: TPackage); -begin - inherited Create; - FPackage := APackage; -end; - procedure TPackageStartMenuEntryList.Assign(Source: TPackageStartMenuEntryList); var i: Integer; @@ -799,7 +821,7 @@ begin Clear; for i := 0 to Source.Count - 1 do begin - psme := TPackageStartMenuEntry.Create(FPackage); + psme := TPackageStartMenuEntry.Create(Package); psme.Assign(Source[i]); Add(psme); end; @@ -819,9 +841,8 @@ end; constructor TPackageStartMenu.Create(APackage: TPackage); begin - inherited Create; - FPackage := APackage; - Entries := TPackageStartMenuEntryList.Create(FPackage); + inherited Create(APackage); + Entries := TPackageStartMenuEntryList.Create(Package); end; destructor TPackageStartMenu.Destroy; @@ -879,15 +900,9 @@ begin FFileType := Source.FileType; end; -constructor TPackageContentFile.Create(APackage: TPackage); -begin - inherited Create; - FPackage := APackage; -end; - function TPackageContentFile.RelativeFileName: WideString; begin - Result := ExtractRelativePath(FPackage.FileName, FFileName); + Result := ExtractRelativePath(Package.FileName, FFileName); end; procedure TPackageContentFile.SetCopyLocation(const Value: TPackageFileCopyLocation); @@ -946,7 +961,7 @@ begin begin with ANode.ChildNodes[i] do begin - subfile := TPackageContentFile.Create(FPackage); + subfile := TPackageContentFile.Create(Package); subfile.FileName := VarToWideStr(ChildNodes['Name'].NodeValue); subfile.Description := VarToWideStr(ChildNodes['Description'].NodeValue); subfile.FCopyLocation := TPackageFileCopyLocation(StrToIntDef(VarToWideStr(ChildNodes['Location'].NodeValue), 0)); @@ -991,7 +1006,7 @@ begin description := CommaToken(t); filename := CommaToken(t); copylocation := TPackageFileCopyLocation(StrToIntDef(CommaToken(t), 0));// CommaToken(t) = '1'; - subfile := TPackageContentFile.Create(FPackage); + subfile := TPackageContentFile.Create(Package); subfile.FileName := filename; subfile.Description := description; subfile.FCopyLocation := copylocation; @@ -1011,12 +1026,6 @@ begin Items[i].FileName, Ord(Items[i].CopyLocation)])); end; -constructor TPackageContentFileList.Create(APackage: TPackage); -begin - inherited Create; - FPackage := APackage; -end; - procedure TPackageContentFileList.Assign(Source: TPackageContentFileList); var i: Integer; @@ -1025,7 +1034,7 @@ begin Clear; for i := 0 to Source.Count - 1 do begin - psf := TPackageContentFile.Create(FPackage); + psf := TPackageContentFile.Create(Package); psf.Assign(Source[i]); Add(psf); end; @@ -1071,6 +1080,7 @@ begin Options.Assign(Source.Options); StartMenu.Assign(Source.StartMenu); Info.Assign(Source.Info); + Keyboards.Assign(Source.Keyboards); end; constructor TPackage.Create; @@ -1080,6 +1090,8 @@ begin if not Assigned(Options) then Options := TPackageOptions.Create(Self); if not Assigned(StartMenu) then StartMenu := TPackageStartMenu.Create(Self); if not Assigned(Info) then Info := TPackageInfoEntryList.Create(Self); + if not Assigned(Keyboards) then Keyboards := TPackageKeyboardList.Create(Self); + end; destructor TPackage.Destroy; @@ -1088,6 +1100,7 @@ begin Options.Free; StartMenu.Free; Info.Free; + Keyboards.Free; inherited Destroy; end; @@ -1111,6 +1124,7 @@ begin Files.LoadIni(ini); Options.LoadLegacy := FLoadLegacy; Options.LoadIni(ini); + Keyboards.LoadIni(ini); finally ini.Free; end; @@ -1208,6 +1222,7 @@ begin Info.LoadXML(ARoot); Files.LoadXML(ARoot); Options.LoadXML(ARoot); + Keyboards.LoadXML(ARoot); end; procedure TPackage.DoSaveXML(ARoot: IXMLNode); @@ -1217,6 +1232,7 @@ begin StartMenu.SaveXML(ARoot); Info.SaveXML(ARoot); Files.SaveXML(ARoot); + Keyboards.SaveXML(ARoot); end; procedure TPackage.SaveIni; @@ -1231,6 +1247,7 @@ begin StartMenu.SaveIni(ini); Info.SaveIni(ini); Files.SaveIni(ini); + Keyboards.SaveIni(ini); ini.UpdateFile; finally ini.Free; @@ -1284,20 +1301,20 @@ end; { TPackageBaseObject } -constructor TPackageBaseObject.Create; +constructor TPackageBaseNotifyObject.Create(APackage: TPackage); begin - inherited Create; + inherited Create(APackage); FNotifyObjects := TObjectList.Create; end; -destructor TPackageBaseObject.Destroy; +destructor TPackageBaseNotifyObject.Destroy; begin Notify(netDestroy); FNotifyObjects.Free; inherited Destroy; end; -function TPackageBaseObject.Notify(EventType: TPackageNotifyEventType): Boolean; +function TPackageBaseNotifyObject.Notify(EventType: TPackageNotifyEventType): Boolean; var i: Integer; fAllow: Boolean; @@ -1310,7 +1327,7 @@ begin Result := True; end; -procedure TPackageBaseObject.AddNotifyObject(FEventHandler: TPackageNotifyEvent); +procedure TPackageBaseNotifyObject.AddNotifyObject(FEventHandler: TPackageNotifyEvent); var ev: TPackageNotifyEventWrapper; begin @@ -1320,7 +1337,7 @@ begin FNotifyObjects.Add(ev); end; -procedure TPackageBaseObject.RemoveNotifyObject(FEventHandler: TPackageNotifyEvent); +procedure TPackageBaseNotifyObject.RemoveNotifyObject(FEventHandler: TPackageNotifyEvent); var i: Integer; begin @@ -1332,6 +1349,14 @@ begin end; end; +{ TPackageBaseObject } + +constructor TPackageBaseObject.Create(APackage: TPackage); +begin + inherited Create; + FPackage := APackage; +end; + { TPackageRegistryKeyList } procedure TPackageRegistryKeyList.Assign(Source: TPackageRegistryKeyList); @@ -1342,18 +1367,12 @@ begin Clear; for i := 0 to Source.Count - 1 do begin - prk := TPackageRegistryKey.Create(FPackage); + prk := TPackageRegistryKey.Create(Package); prk.Assign(Source[i]); Add(prk); end; end; -constructor TPackageRegistryKeyList.Create(APackage: TPackage); -begin - inherited Create; - FPackage := APackage; -end; - procedure TPackageRegistryKeyList.LoadIni(AIni: TIniFile); var i: Integer; @@ -1371,7 +1390,7 @@ begin AIni.ReadSectionValues('Registry', FValues); for i := 0 to FValues.Count - 1 do begin - pkr := TPackageRegistryKey.Create(FPackage); + pkr := TPackageRegistryKey.Create(Package); name := FValues.Names[i]; value := FValues.ValueFromIndex[i]; @@ -1436,7 +1455,7 @@ begin for i := 0 to ANode.ChildNodes.Count - 1 do begin AKeyNode := ANode.ChildNodes[i]; - pkr := TPackageRegistryKey.Create(FPackage); + pkr := TPackageRegistryKey.Create(Package); name := VarToWideStr(AKeyNode.Attributes['Name']); value := VarToWideStr(AKeyNode.Attributes['Value']); @@ -1501,8 +1520,7 @@ end; constructor TPackageRegistryKey.Create(APackage: TPackage); begin - inherited Create; - FPackage := APackage; + inherited Create(APackage); FRoot := HKEY_CURRENT_USER; FValueType := rkvtString; end; @@ -1512,5 +1530,240 @@ begin inherited Destroy; end; +{ TPackageObjectList } + +constructor TPackageObjectList.Create(APackage: TPackage); +begin + inherited Create; + FPackage := APackage; +end; + +{ TPackageKeyboard } + +procedure TPackageKeyboard.Assign(Source: TPackageKeyboard); +var + i: Integer; + FLanguage: TPackageKeyboardLanguage; +begin + FName := Source.Name; + FID := Source.ID; + FVersion := Source.Version; + if Assigned(Source.OSKFont) + then FOSKFont := Package.Files.FromFileNameEx(Source.OSKFont.FileName) + else FOSKFont := nil; + if Assigned(Source.DisplayFont) + then FDisplayFont := Package.Files.FromFileNameEx(Source.DisplayFont.FileName) + else FDisplayFont := nil; + FLanguages.Clear; + for i := 0 to Source.Languages.Count - 1 do + begin + FLanguage := TPackageKeyboardLanguage.Create(Package); + FLanguage.ID := Source.Languages[i].ID; + FLanguage.Name := Source.Languages[i].Name; + FLanguages.Add(FLanguage); + end; +end; + +procedure TPackageKeyboard.SetDisplayFont(const Value: TPackageContentFile); +begin + if Assigned(FDisplayFont) then FDisplayFont.RemoveNotifyObject(DisplayFontRemoved); + if not Assigned(Value) then + FDisplayFont := nil + else + begin + if Value.Package <> Package then raise EPackageInfo.CreateFmt(SDisplayFontNotOwnedCorrectly, [Value]); + FDisplayFont := Value; + FDisplayFont.AddNotifyObject(DisplayFontRemoved); + end; +end; + +constructor TPackageKeyboard.Create(APackage: TPackage); +begin + inherited Create(APackage); + FLanguages := TPackageKeyboardLanguageList.Create(APackage); +end; + +destructor TPackageKeyboard.Destroy; +begin + FreeAndNil(FLanguages); + inherited Destroy; +end; + +procedure TPackageKeyboard.DisplayFontRemoved(Sender: TObject; + EventType: TPackageNotifyEventType; var FAllow: Boolean); +begin + FDisplayFont := nil; +end; + +procedure TPackageKeyboard.SetOSKFont(const Value: TPackageContentFile); +begin + if Assigned(FOSKFont) then FOSKFont.RemoveNotifyObject(OSKFontRemoved); + if not Assigned(Value) then + FOSKFont := nil + else + begin + if Value.Package <> Package then raise EPackageInfo.CreateFmt(SOSKFontNotOwnedCorrectly, [Value]); + FOSKFont := Value; + FOSKFont.AddNotifyObject(OSKFontRemoved); + end; +end; + +procedure TPackageKeyboard.OSKFontRemoved(Sender: TObject; + EventType: TPackageNotifyEventType; var FAllow: Boolean); +begin + FOSKFont := nil; +end; + +{ TPackageKeyboardList } + +procedure TPackageKeyboardList.Assign(Source: TPackageKeyboardList); +var + i: Integer; + pk: TPackageKeyboard; +begin + Clear; + for i := 0 to Source.Count - 1 do + begin + pk := TPackageKeyboard.Create(Package); + pk.Assign(Source[i]); + Add(pk); + end; +end; + +const + SPackageKeyboard_Name = 'Name'; + SPackageKeyboard_ID = 'ID'; + SPackageKeyboard_Version = 'Version'; + SPackageKeyboard_OSKFont = 'OSKFont'; + SPackageKeyboard_DisplayFont = 'DisplayFont'; + SPackageKeyboard_Language = 'Language'; + +procedure TPackageKeyboardList.LoadIni(AIni: TIniFile); +var + s: TStringList; + ln: WideString; + i, j: Integer; + FSectionName: string; + keyboard: TPackageKeyboard; + FLanguage: TPackageKeyboardLanguage; +begin + Clear; + s := TStringList.Create; + try + AIni.ReadSections(s); + for i := 0 to MaxInt do + begin + FSectionName := 'Keyboard'+IntToStr(i); + if s.IndexOf(FSectionName) < 0 then + Break; + + keyboard := TPackageKeyboard.Create(Package); + keyboard.Name := AIni.ReadString(FSectionName, SPackageKeyboard_Name, ''); + keyboard.ID := AIni.ReadString(FSectionName, SPackageKeyboard_ID, ''); + keyboard.Version := AIni.ReadString(FSectionName, SPackageKeyboard_Version, '1.0'); + keyboard.OSKFont := Package.Files.FromFileNameEx(AIni.ReadString(FSectionName, SPackageKeyboard_OSKFont, '')); + keyboard.DisplayFont := Package.Files.FromFileNameEx(AIni.ReadString(FSectionName, SPackageKeyboard_DisplayFont, '')); + + for j := 0 to MaxInt do + begin + ln := AIni.ReadString(FSectionName, SPackageKeyboard_Language+IntToStr(j), ''); + if ln = '' then + Break; + FLanguage := TPackageKeyboardLanguage.Create(Package); + FLanguage.ID := CommaToken(ln); + FLanguage.Name := CommaToken(ln); + keyboard.Languages.Add(FLanguage); + end; + + Add(keyboard); + end; + finally + s.Free; + end; +end; + +procedure TPackageKeyboardList.LoadXML(ARoot: IXMLNode); +var + keyboard: TPackageKeyboard; + i, j: Integer; + ANode: IXMLNode; + FLanguage: TPackageKeyboardLanguage; + ln: WideString; + FSectionName: string; +begin + Clear; + for i := 0 to MaxInt do + begin + FSectionName := 'Keyboard'+IntToStr(i); + if ARoot.ChildNodes.IndexOf(FSectionName) < 0 then + Break; + ANode := ARoot.ChildNodes[FSectionName]; + + keyboard := TPackageKeyboard.Create(Package); + keyboard.Name := VarToStr(ANode.ChildValues[SPackageKeyboard_Name]); + keyboard.ID := VarToStr(ANode.ChildValues[SPackageKeyboard_ID]); + keyboard.Version := VarToStr(ANode.ChildValues[SPackageKeyboard_Version]); + keyboard.OSKFont := Package.Files.FromFileNameEx(VarToStr(ANode.ChildValues[SPackageKeyboard_OSKFont])); + keyboard.DisplayFont := Package.Files.FromFileNameEx(VarToStr(ANode.ChildValues[SPackageKeyboard_DisplayFont])); + + for j := 0 to MaxInt do + begin + ln := VarToStr(ANode.ChildValues[SPackageKeyboard_Language+IntToStr(j)]); + if ln = '' then + Break; + FLanguage := TPackageKeyboardLanguage.Create(Package); + FLanguage.ID := CommaToken(ln); + FLanguage.Name := CommaToken(ln); + keyboard.Languages.Add(FLanguage); + end; + + Add(keyboard); + end; +end; + +procedure TPackageKeyboardList.SaveIni(AIni: TIniFile); +var + i, j: Integer; + FSectionName: string; +begin + for i := 0 to Count-1 do + begin + FSectionName := 'Keyboard'+IntToStr(i); + AIni.WriteString(FSectionName, SPackageKeyboard_Name, Items[i].Name); + AIni.WriteString(FSectionName, SPackageKeyboard_ID, Items[i].ID); + AIni.WriteString(FSectionName, SPackageKeyboard_Version, Items[i].Version); + if Assigned(Items[i].OSKFont) then + AIni.WriteString(FSectionName, SPackageKeyboard_OSKFont, ExtractFileName(Items[i].OSKFont.FileName)); + if Assigned(Items[i].DisplayFont) then + AIni.WriteString(FSectionName, SPackageKeyboard_DisplayFont, ExtractFileName(Items[i].DisplayFont.FileName)); + + for j := 0 to Items[i].Languages.Count-1 do + begin + AIni.WriteString(FSectionName, SPackageKeyboard_Language+IntToStr(j), Items[i].Languages[j].ID+','+Items[i].Languages[j].Name); + end; + end; +end; + +procedure TPackageKeyboardList.SaveXML(ARoot: IXMLNode); +var + i, j: Integer; +begin + for i := 0 to Count - 1 do + begin + with ARoot.AddChild('Keyboard'+IntToStr(i)) do + begin + ChildNodes[SPackageKeyboard_Name].NodeValue := Items[i].Name; + ChildNodes[SPackageKeyboard_ID].NodeValue := Items[i].ID; + ChildNodes[SPackageKeyboard_Version].NodeValue := Items[i].Version; + if Assigned(Items[i].OSKFont) then + ChildNodes[SPackageKeyboard_OSKFont].NodeValue := ExtractFileName(Items[i].OSKFont.FileName); + if Assigned(Items[i].DisplayFont) then + ChildNodes[SPackageKeyboard_DisplayFont].NodeValue := ExtractFileName(Items[i].DisplayFont.FileName); + for j := 0 to Items[i].Languages.Count - 1 do + ChildNodes[SPackageKeyboard_Language+IntToStr(j)].NodeValue := Items[i].Languages[j].ID+','+Items[i].Languages[j].Name; + end; + end; +end; + end. diff --git a/windows/src/global/delphi/general/kmpinffile.pas b/windows/src/global/delphi/general/kmpinffile.pas index aadc20a13e..de506a42b4 100644 --- a/windows/src/global/delphi/general/kmpinffile.pas +++ b/windows/src/global/delphi/general/kmpinffile.pas @@ -162,6 +162,11 @@ begin //if LowerCase(AIni.ReadString('Install', 'StartMenuReadme', '')) = 'true' then -- already in [StartMenu] Options.ReadmeFile := Files.FromFileName(AIni.ReadString('Install', 'ReadmeFile', '')); Options.ExecuteProgram := AIni.ReadString('Install', 'ExecuteProgram', ''); + +// TODO +// Also remember to update version number if source files change +// Also do not permit different versions of same keyboard in compiled form! + finally str.Free; end; diff --git a/windows/src/unit-tests/Makefile b/windows/src/unit-tests/Makefile new file mode 100644 index 0000000000..3c1d6e4beb --- /dev/null +++ b/windows/src/unit-tests/Makefile @@ -0,0 +1,27 @@ +# +# Unit Tests Makefile. +# + +# ---------------------------------------------------------------------- + +TARGETS=package-info +CLEAN=package-info + +test: + $(MAKE) -DTARGET=test $(TARGETS) + +!include ..\Header.mak + +# ---------------------------------------------------------------------- + +package-info: + cd $(ROOT)\src\unit-tests\package-info + $(MAKE) $(TARGET) + +# ---------------------------------------------------------------------- + +!include ..\Target.mak + +# ---------------------------------------------------------------------- +# EOF +# ---------------------------------------------------------------------- diff --git a/windows/src/unit-tests/package-info/.gitignore b/windows/src/unit-tests/package-info/.gitignore new file mode 100644 index 0000000000..59f131f7a5 --- /dev/null +++ b/windows/src/unit-tests/package-info/.gitignore @@ -0,0 +1,2 @@ +test/*.out.* +Win32 diff --git a/windows/src/unit-tests/package-info/Makefile b/windows/src/unit-tests/package-info/Makefile new file mode 100644 index 0000000000..76edbf6b59 --- /dev/null +++ b/windows/src/unit-tests/package-info/Makefile @@ -0,0 +1,18 @@ +# +# Test the PackageInfo file format read and write - xml and inf +# + +!include ..\..\Defines.mak + +test: build + Win32\Debug\packageinfotestsuite.exe -b + +build: + $(DELPHI_MSBUILD) /p:CI=CI packageinfotestsuite.dproj + +clean: def-clean + -rd /s/q Win32 + -del dunitx-results.xml + -del test\*.out.* + +!include ..\..\Target.mak diff --git a/windows/src/unit-tests/package-info/PackageInfoTest.pas b/windows/src/unit-tests/package-info/PackageInfoTest.pas new file mode 100644 index 0000000000..8bba8ea026 --- /dev/null +++ b/windows/src/unit-tests/package-info/PackageInfoTest.pas @@ -0,0 +1,259 @@ +unit PackageInfoTest; + +interface + +uses + DUnitX.TestFramework, + + PackageInfo, + kpsfile; + +type + [TestFixture] + TPackageInfoTest = class(TObject) + private + DataPath: string; + procedure DoCompare(f1, f2: string); + procedure DoCompareKpsFiles(f1, f2: string; k1, k2: TKpsFile); + + public + [Setup] + procedure Setup; + + [TearDown] + procedure TearDown; + + [Test] + procedure TestXMLInOut; + + [Test] + procedure TestRoundTrip; + + [Test] + procedure TestRoundTripInf; + + [Test] + procedure TestInfInOut; + + [Test] + procedure TestAssign; + end; + +implementation + +uses + System.Classes, + System.SysUtils, + System.Win.ComObj, + Winapi.ActiveX, + Xml.XmlDoc, + Xml.XmlIntf; + + +procedure TPackageInfoTest.Setup; +begin + CoInitializeEx(nil, COINIT_APARTMENTTHREADED); + DataPath := ExtractFilePath(ParamStr(0)) + '..\..\test\'; +end; + +procedure TPackageInfoTest.TearDown; +begin + CoUninitialize; +end; + +procedure TPackageInfoTest.TestAssign; +var + p1, p2: TPackage; +begin + p1 := TKpsFile.Create; + p2 := TKpsFile.Create; + try + p1.FileName := DataPath + 'test1.xml'; + p1.LoadXML; + p2.Assign(p1); + p2.FileName := DataPath + 'testAssign.out.xml'; + p2.SaveXML; + finally + p1.Free; + p2.Free; + end; + + DoCompare(DataPath + 'test1.xml', DataPath + 'testAssign.out.xml'); +end; + +procedure TPackageInfoTest.TestInfInOut; +var + p1: TPackage; +begin + p1 := TKpsFile.Create; + try + p1.FileName := DataPath + 'test1.inf'; + p1.LoadIni; + p1.FileName := DataPath + 'test1.out.inf'; + p1.SaveIni; + finally + p1.Free; + end; + + DoCompare(DataPath + 'test1.inf', DataPath + 'test1.out.inf'); +end; + +procedure TPackageInfoTest.TestRoundTrip; +var + p1: TPackage; +begin + p1 := TKpsFile.Create; + try + p1.FileName := DataPath + 'test1.xml'; + p1.LoadXML; + p1.FileName := DataPath + 'test1.out.inf'; + p1.SaveIni; + finally + p1.Free; + end; + + p1 := TKpsFile.Create; + try + p1.FileName := DataPath + 'test1.out.inf'; + p1.LoadIni; + p1.FileName := DataPath + 'test1.out.xml'; + p1.SaveXML; + finally + p1.Free; + end; + + DoCompare(DataPath + 'test1.xml', DataPath + 'test1.out.xml'); +end; + +procedure TPackageInfoTest.TestRoundTripInf; +var + p1: TPackage; +begin + p1 := TKpsFile.Create; + try + p1.FileName := DataPath + 'test1.inf'; + p1.LoadIni; + p1.FileName := DataPath + 'test1.out.xml'; + p1.SaveXML; + finally + p1.Free; + end; + + p1 := TKpsFile.Create; + try + p1.FileName := DataPath + 'test1.out.xml'; + p1.LoadXML; + p1.FileName := DataPath + 'test1.out.inf'; + p1.SaveIni; + finally + p1.Free; + end; + + DoCompare(DataPath + 'test1.inf', DataPath + 'test1.out.inf'); +end; + +procedure TPackageInfoTest.TestXMLInOut; +var + p1: TPackage; +begin + p1 := TKpsFile.Create; + try + p1.FileName := DataPath + 'test1.xml'; + p1.LoadXML; + p1.FileName := DataPath + 'test1.out.xml'; + p1.SaveXML; + finally + p1.Free; + end; + + DoCompare(DataPath + 'test1.xml', DataPath + 'test1.out.xml'); +end; + +procedure TPackageInfoTest.DoCompare(f1, f2: string); +var + k1, k2: TKpsFile; +begin + k1 := TKpsFile.Create; + k2 := TKpsFile.Create; + try + k1.FileName := f1; + if SameText(ExtractFileExt(f1), '.xml') + then k1.LoadXml + else k1.LoadIni; + + k2.FileName := f2; + if SameText(ExtractFileExt(f2), '.xml') + then k2.LoadXml + else k2.LoadIni; + + DoCompareKpsFiles(f1, f2, k1, k2); + finally + k1.Free; + k2.Free; + end; +end; + +procedure TPackageInfoTest.DoCompareKpsFiles(f1, f2: string; k1, k2: TKpsFile); +var + i: Integer; + t: TPackageInfoEntryType; +begin + Assert.AreEqual(k1.Options.FileVersion, k2.Options.FileVersion); + Assert.AreEqual(k1.Options.ExecuteProgram, k2.Options.ExecuteProgram); + Assert.IsTrue( + ( + Assigned(k1.Options.ReadmeFile) and + Assigned(k2.Options.ReadmeFile) and + (k1.Options.ReadmeFile.FileName = k2.Options.ReadmeFile.FileName) + ) or ( + not Assigned(k1.Options.ReadmeFile) and + not Assigned(k2.Options.ReadmeFile) + ), + 'ReadmeFile does not match for '+f1+','+f2); + Assert.IsTrue( + ( + Assigned(k1.Options.GraphicFile) and + Assigned(k2.Options.GraphicFile) and + (k1.Options.GraphicFile.FileName = k2.Options.GraphicFile.FileName) + ) or ( + not Assigned(k1.Options.GraphicFile) and + not Assigned(k2.Options.GraphicFile) + ), + 'GraphicFile does not match for '+f1+','+f2); + + Assert.AreEqual(k1.Files.Count, k2.Files.Count); + for i := 0 to k1.Files.Count - 1 do + begin + Assert.AreEqual(k1.Files[i].FileName, k2.Files.FromFileNameEx(k1.Files[i].FileName).FileName); + Assert.AreEqual(k1.Files[i].Description, k2.Files.FromFileNameEx(k1.Files[i].FileName).Description); + end; + + for t := Low(TPackageInfoEntryType) to High(TPackageInfoEntryType) do + begin + Assert.AreEqual(k1.Info.Desc[PackageInfoEntryTypeNames[t]], k2.Info.Desc[PackageInfoEntryTypeNames[t]]); + Assert.AreEqual(k1.Info.URL[PackageInfoEntryTypeNames[t]], k2.Info.URL[PackageInfoEntryTypeNames[t]]); + end; + + Assert.AreEqual(k1.Keyboards.Count, k2.Keyboards.Count); + for i := 0 to k1.Keyboards.Count - 1 do + begin + Assert.AreEqual(k1.Keyboards[i].Name, k2.Keyboards[i].Name); + Assert.AreEqual(k1.Keyboards[i].ID, k2.Keyboards[i].ID); + Assert.AreEqual(k1.Keyboards[i].Version, k2.Keyboards[i].Version); + Assert.IsTrue( + ( + Assigned(k1.Keyboards[i].OSKFont) and + Assigned(k2.Keyboards[i].OSKFont) and + (k1.Keyboards[i].OSKFont.FileName = k2.Keyboards[i].OSKFont.FileName) + ) or ( + not Assigned(k1.Keyboards[i].OSKFont) and + not Assigned(k2.Keyboards[i].OSKFont) + ) + ); + end; +end; + + +initialization + TDUnitX.RegisterTestFixture(TPackageInfoTest); +end. diff --git a/windows/src/unit-tests/package-info/PackageInfoTestSuite.dpr b/windows/src/unit-tests/package-info/PackageInfoTestSuite.dpr new file mode 100644 index 0000000000..a02499a8e0 --- /dev/null +++ b/windows/src/unit-tests/package-info/PackageInfoTestSuite.dpr @@ -0,0 +1,75 @@ +program PackageInfoTestSuite; + +{$IFNDEF TESTINSIGHT} +{$APPTYPE CONSOLE} +{$ENDIF}{$STRONGLINKTYPES ON} +uses + System.SysUtils, + {$IFDEF TESTINSIGHT} + TestInsight.DUnitX, + {$ENDIF } + + PackageInfo in '..\..\global\delphi\general\PackageInfo.pas', + utilfiletypes in '..\..\global\delphi\general\utilfiletypes.pas', + utilstr in '..\..\global\delphi\general\utilstr.pas', + StockFileNames in '..\..\global\delphi\cust\StockFileNames.pas', + Unicode in '..\..\global\delphi\general\Unicode.pas', + KeymanVersion in '..\..\global\delphi\general\KeymanVersion.pas', + VersionInfo in '..\..\global\delphi\general\VersionInfo.pas', + utilsystem in '..\..\global\delphi\general\utilsystem.pas', + utilexecute in '..\..\global\delphi\general\utilexecute.pas', + utildir in '..\..\global\delphi\general\utildir.pas', + RegistryKeys in '..\..\global\delphi\general\RegistryKeys.pas', + GetOsVersion in '..\..\global\delphi\general\GetOsVersion.pas', + kpsfile in '..\..\global\delphi\general\kpsfile.pas', + PackageFileFormats in '..\..\global\delphi\general\PackageFileFormats.pas', + + DUnitX.Loggers.Console, + DUnitX.Loggers.Xml.NUnit, + DUnitX.TestFramework, + PackageInfoTest in 'PackageInfoTest.pas'; + +var + runner : ITestRunner; + results : IRunResults; + logger : ITestLogger; + nunitLogger : ITestLogger; +begin +{$IFDEF TESTINSIGHT} + TestInsight.DUnitX.RunRegisteredTests; + exit; +{$ENDIF} + try + //Check command line options, will exit if invalid + TDUnitX.CheckCommandLine; + //Create the test runner + runner := TDUnitX.CreateRunner; + //Tell the runner to use RTTI to find Fixtures + runner.UseRTTI := True; + //tell the runner how we will log things + //Log to the console window + logger := TDUnitXConsoleLogger.Create(true); + runner.AddLogger(logger); + //Generate an NUnit compatible XML File + nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile); + runner.AddLogger(nunitLogger); + runner.FailsOnNoAsserts := False; //When true, Assertions must be made during tests; + + //Run tests + results := runner.Execute; + if not results.AllPassed then + System.ExitCode := EXIT_ERRORS; + + {$IFNDEF CI} + //We don't want this happening when running under CI. + if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then + begin + System.Write('Done.. press key to quit.'); + System.Readln; + end; + {$ENDIF} + except + on E: Exception do + System.Writeln(E.ClassName, ': ', E.Message); + end; +end. diff --git a/windows/src/unit-tests/package-info/PackageInfoTestSuite.dproj b/windows/src/unit-tests/package-info/PackageInfoTestSuite.dproj new file mode 100644 index 0000000000..8cb444285f --- /dev/null +++ b/windows/src/unit-tests/package-info/PackageInfoTestSuite.dproj @@ -0,0 +1,527 @@ + + + {D450A640-6394-4474-BBBA-69C83A571086} + 18.2 + None + PackageInfoTestSuite.dpr + True + Debug + Win32 + 1 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + false + false + false + false + false + RESTComponents;FireDAC;FireDACSqliteDriver;soaprtl;FireDACIBDriver;soapmidas;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;$(DCC_UsePackage) + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + true + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + $(DUnitX);$(DCC_UnitSearchPath) + PackageInfoTestSuite + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + $(CI);$(USE_PLUSMEMO);$(DCC_Define) + + + DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;svnui;mbColorLibD10;dsnapcon;FireDACADSDriver;scFontCombo;DCPdelphi2009;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;JvCore;vcldb;bindcompfmx;svn;FireDACPgDriver;inetdb;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;EmbeddedWebBrowser_XE;VCLRESTComponents;dbxcds;VclSmp;JvDocking;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;keyman_components;FireDACCommonODBC;fmxase;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + DBXSqliteDriver;bindcompdbx;IndyIPCommon;DBXInterBaseDriver;vcl;IndyIPServer;vclactnband;vclFireDAC;IndySystem;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;vclimg;Jcl;vcltouch;vcldb;bindcompfmx;FireDACPgDriver;inetdb;DbxCommonDriver;fmx;fmxdae;xmlrtl;fmxobj;vclwinx;rtl;DbxClientDriver;CustomIPTransport;vcldsnap;dbexpress;IndyCore;vclx;bindcomp;appanalytics;dsnap;IndyIPClient;bindcompvcl;VCLRESTComponents;dbxcds;VclSmp;adortl;JclVcl;vclie;bindengine;DBXMySQLDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;IndyProtocols;FireDACCommonODBC;fmxase;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + 1033 + (None) + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Console + + + + PackageInfoTestSuite.dpr + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + PackageInfoTestSuite.exe + true + + + + + 1 + + + Contents\MacOS + 0 + + + + + classes + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + + + res\values + 1 + + + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + True + False + + + 12 + + + + + diff --git a/windows/src/unit-tests/package-info/PackageInfoTestSuite.res b/windows/src/unit-tests/package-info/PackageInfoTestSuite.res new file mode 100644 index 0000000000..6876088a66 Binary files /dev/null and b/windows/src/unit-tests/package-info/PackageInfoTestSuite.res differ diff --git a/windows/src/unit-tests/package-info/test/test1.inf b/windows/src/unit-tests/package-info/test/test1.inf new file mode 100644 index 0000000000..9bea7b7e3e --- /dev/null +++ b/windows/src/unit-tests/package-info/test/test1.inf @@ -0,0 +1,62 @@ +[Package] +Version=7.0 +ExecuteProgram= +ReadMeFile=readme.htm +GraphicFile=sideimage.bmp +[StartMenu] +Path=GFF Amharic Keyboard +Create=1 +AddUninstallEntry=1 +[StartMenuEntries] +Welcome="..\..\..\gff\gff_amh_7\source\welcome.htm","" +Amharic Keyboard Manual (Amharic)="AmharicTyping-Amharic.pdf","" +Amharic Keyboard Manual (English)="AmharicTyping-English.pdf","" +OFL (Abyssinica SIL Licence)="OFL.txt","" +GPL (WashRa + Free Serif Licence)="GNU-GPLv2.txt","" +[Info] +WebSite="http://keyboards.ethiopic.org","http://keyboards.ethiopic.org" +Version="8.0.0","" +Name="GFF Amharic Keyboard","" +Copyright="Creative Commons Attribution 3.0","" +Author="The Ge'ez Frontier Foundation","mailto:keyboards@ethiopic.org" +[Files] +0="File readme.htm","readme.htm",0 +1="File sideimage.bmp","sideimage.bmp",0 +2="File AmharicTyping-Amharic.pdf","..\..\..\gff\gff_amh_7\source\AmharicTyping-Amharic.pdf",0 +3="File AmharicTyping-English.pdf","..\..\..\gff\gff_amh_7\source\AmharicTyping-English.pdf",0 +4="File OFL.txt","..\..\..\shared\fonts\geez\OFL.txt",0 +5="File GNU-GPLv2.txt","..\..\..\shared\fonts\geez\GNU-GPLv2.txt",0 +6="File Welcome.htm","..\..\..\gff\gff_amh_7\source\welcome.htm",0 +7="Font Abyssinica SIL","..\..\..\shared\fonts\geez\AbyssinicaSIL-R.ttf",0 +8="Font Ethiopic Fantuwua","..\..\..\shared\fonts\geez\fantuwua.ttf",0 +9="Font Free Serif","..\..\..\shared\fonts\geez\FreeSerif.otf",0 +10="Font Ethiopic Yigezu Bisrat Goffer","..\..\..\shared\fonts\geez\goffer.ttf",0 +11="Font Ethiopic Hiwua","..\..\..\shared\fonts\geez\hiwua.ttf",0 +12="Font Ethiopia Jiret","..\..\..\shared\fonts\geez\jiret.ttf",0 +13="Font Ethiopia Jiret Slant","..\..\..\shared\fonts\geez\jiretsl.ttf",0 +14="Font Ethiopic Tint","..\..\..\shared\fonts\geez\tint.ttf",0 +15="Font Ethiopic WashRa Bold","..\..\..\shared\fonts\geez\washrab.ttf",0 +16="Font Ethiopic WashRa Bold Slant","..\..\..\shared\fonts\geez\washrabsl.ttf",0 +17="Font Ethiopic WashRa SemiBold","..\..\..\shared\fonts\geez\washrasb.ttf",0 +18="Font Ethiopic WashRa SemiBold Slant","..\..\..\shared\fonts\geez\washrasbsl.ttf",0 +19="Font Ethiopic Wookianos","..\..\..\shared\fonts\geez\wookianos.ttf",0 +20="Font Ethiopic Yebse","..\..\..\shared\fonts\geez\yebse.ttf",0 +21="File gff_amh_7.kvk","..\..\..\gff\gff_amh_7\build\gff_amh_7.kvk",0 +22="Keyboard Amharic","..\..\..\gff\gff_amh_7\build\gff_amh_7.kmx",0 +23="File gff_ethiopic_7.kvk","..\..\..\gff\gff_ethiopic_7\build\gff_ethiopic_7.kvk",0 +24="Keyboard Ethiopic - (Language Neutral)","..\..\..\gff\gff_ethiopic_7\build\gff_ethiopic_7.kmx",0 + +[Keyboard0] +Name=Amharic +ID=gff_amh_7 +Version=8.0 +OSKFont=wookianos.ttf +DisplayFont=fantuwua.ttf +Language0=amh,Amharic +Language1=gez,Ge'ez + +[Keyboard1] +Name=Ethiopic Language Neutral +ID=gff_ethiopic_7 +Version=8.0 +Language0=gez,Ge'ez diff --git a/windows/src/unit-tests/package-info/test/test1.xml b/windows/src/unit-tests/package-info/test/test1.xml new file mode 100644 index 0000000000..e209d7b15e --- /dev/null +++ b/windows/src/unit-tests/package-info/test/test1.xml @@ -0,0 +1,2 @@ + +9.0.500.07.0readme.htmsideimage.bmpGFF Amharic KeyboardWelcome..\..\..\gff\gff_amh_7\source\welcome.htmpsmelStartMenuAmharic Keyboard Manual (Amharic)AmharicTyping-Amharic.pdfpsmelStartMenuAmharic Keyboard Manual (English)AmharicTyping-English.pdfpsmelStartMenuOFL (Abyssinica SIL Licence)OFL.txtpsmelStartMenuGPL (WashRa + Free Serif Licence) GNU-GPLv2.txtpsmelStartMenuhttp://keyboards.ethiopic.org8.0.0GFF Amharic KeyboardCreative Commons Attribution 3.0The Ge'ez Frontier Foundationreadme.htmFile readme.htm0.htmsideimage.bmpFile sideimage.bmp0.bmp..\..\..\gff\gff_amh_7\source\AmharicTyping-Amharic.pdfFile AmharicTyping-Amharic.pdf0.pdf..\..\..\gff\gff_amh_7\source\AmharicTyping-English.pdfFile AmharicTyping-English.pdf0.pdf..\..\..\shared\fonts\geez\OFL.txtFile OFL.txt0.txt..\..\..\shared\fonts\geez\GNU-GPLv2.txtFile GNU-GPLv2.txt0.txt..\..\..\gff\gff_amh_7\source\welcome.htmFile Welcome.htm0.htm..\..\..\shared\fonts\geez\AbyssinicaSIL-R.ttfFont Abyssinica SIL0.ttf..\..\..\shared\fonts\geez\fantuwua.ttfFont Ethiopic Fantuwua0.ttf..\..\..\shared\fonts\geez\FreeSerif.otfFont Free Serif0.otf..\..\..\shared\fonts\geez\goffer.ttfFont Ethiopic Yigezu Bisrat Goffer0.ttf..\..\..\shared\fonts\geez\hiwua.ttfFont Ethiopic Hiwua0.ttf..\..\..\shared\fonts\geez\jiret.ttfFont Ethiopia Jiret0.ttf..\..\..\shared\fonts\geez\jiretsl.ttfFont Ethiopia Jiret Slant0.ttf..\..\..\shared\fonts\geez\tint.ttfFont Ethiopic Tint0.ttf..\..\..\shared\fonts\geez\washrab.ttfFont Ethiopic WashRa Bold0.ttf..\..\..\shared\fonts\geez\washrabsl.ttfFont Ethiopic WashRa Bold Slant0.ttf..\..\..\shared\fonts\geez\washrasb.ttfFont Ethiopic WashRa SemiBold0.ttf..\..\..\shared\fonts\geez\washrasbsl.ttfFont Ethiopic WashRa SemiBold Slant0.ttf..\..\..\shared\fonts\geez\wookianos.ttfFont Ethiopic Wookianos0.ttf..\..\..\shared\fonts\geez\yebse.ttfFont Ethiopic Yebse0.ttf..\..\..\gff\gff_amh_7\build\gff_amh_7.kvkFile gff_amh_7.kvk0.kvk..\..\..\gff\gff_amh_7\build\gff_amh_7.kmxKeyboard Amharic0.kmx..\..\..\gff\gff_ethiopic_7\build\gff_ethiopic_7.kvkFile gff_ethiopic_7.kvk0.kvk..\..\..\gff\gff_ethiopic_7\build\gff_ethiopic_7.kmxKeyboard Ethiopic - (Language Neutral)0.kmx