diff --git a/.gitattributes b/.gitattributes index 75b93aacdc..b050af7188 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3450,6 +3450,8 @@ components/onlinepackagemanager/onlinepackagemanager.lpk svneol=native#text/plai components/onlinepackagemanager/onlinepackagemanager.lps svneol=native#text/plain components/onlinepackagemanager/onlinepackagemanager.pas svneol=native#text/pascal components/onlinepackagemanager/onlinepackagemanagerintf.pas svneol=native#text/pascal +components/onlinepackagemanager/opkman_addrepositorypackagefrm.lfm svneol=native#text/plain +components/onlinepackagemanager/opkman_addrepositorypackagefrm.pas svneol=native#text/pascal components/onlinepackagemanager/opkman_categoriesfrm.lfm svneol=native#text/plain components/onlinepackagemanager/opkman_categoriesfrm.pas svneol=native#text/pascal components/onlinepackagemanager/opkman_common.pas svneol=native#text/pascal diff --git a/components/onlinepackagemanager/onlinepackagemanager.lpk b/components/onlinepackagemanager/onlinepackagemanager.lpk index 0afaac7eb7..7e7dc1cbc0 100644 --- a/components/onlinepackagemanager/onlinepackagemanager.lpk +++ b/components/onlinepackagemanager/onlinepackagemanager.lpk @@ -20,7 +20,7 @@ - + @@ -119,6 +119,10 @@ + + + + diff --git a/components/onlinepackagemanager/onlinepackagemanager.pas b/components/onlinepackagemanager/onlinepackagemanager.pas index fc73cce1f0..ea5a3e6080 100644 --- a/components/onlinepackagemanager/onlinepackagemanager.pas +++ b/components/onlinepackagemanager/onlinepackagemanager.pas @@ -15,7 +15,8 @@ uses opkman_createrepositorypackagefrm, opkman_categoriesfrm, opkman_packagedetailsfrm, opkman_updates, opkman_createjsonforupdatesfrm, opkman_uploader, opkman_repositories, opkman_createrepositoryfrm, - opkman_repositorydetailsfrm, LazarusPackageIntf; + opkman_repositorydetailsfrm, opkman_addrepositorypackagefrm, + LazarusPackageIntf; implementation diff --git a/components/onlinepackagemanager/opkman_addrepositorypackagefrm.lfm b/components/onlinepackagemanager/opkman_addrepositorypackagefrm.lfm new file mode 100644 index 0000000000..8998ff2072 --- /dev/null +++ b/components/onlinepackagemanager/opkman_addrepositorypackagefrm.lfm @@ -0,0 +1,111 @@ +object AddRepositoryPackageFrm: TAddRepositoryPackageFrm + Left = 561 + Height = 157 + Top = 287 + Width = 459 + BorderIcons = [biSystemMenu] + BorderStyle = bsSingle + Caption = 'AddRepositoryPackageFrm' + ClientHeight = 157 + ClientWidth = 459 + Icon.Data = { + 7E04000000000100010010100000010020006804000016000000280000001000 + 0000200000000100200000000000000400006400000064000000000000000000 + 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00BDD8E8005FA7 + D3FF56A2D0FFB5D3E500009600FF009600FF009600FFFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00D7E9F20078B7DBFF2D8EC8FF8FCD + EBFF6FB7E2FF408EC8FF009600FF00C000FF009600FFFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00ECF4F90093C9E3FF3F9CCEFF82C4E5FFCCF4FFFFC4EF + FFFF8BD2F1FF8ACEF0FF009600FF00C000FF009600FFD1E9E100FFFFFF00FFFF + FF00FAFDFE00AFD8EB0055ABD5FF7DC0E0FFC7EEFCFFCCF2FFFFA8E8FFFF0096 + 00FF009600FF009600FF009600FF00C000FF009600FF009600FF009600FF0096 + 00FF6FB8D80077BDDCFFBFE5F6FFDBF6FFFFC1EEFFFFA5E5FFFF9FE3FFFF0096 + 00FF00C000FF00C000FF00C000FF00C000FF00C000FF00C000FF00C000FF0096 + 00FF45A9D3FFE7FBFEFFDDF6FFFFC1EFFFFFB7EBFFFFABE8FFFFA4E4FFFF0096 + 00FF009600FF009600FF009600FF00C000FF009600FF009600FF009600FF0096 + 00FF4EAED6FFE2F6FCFFD4F3FFFFC9F0FFFFBEEDFFFFB3EAFFFFADE7FFFF7CD9 + FEFF48C7EFFF43C4EAFF009600FF00C000FF009600FF40A7E1FF83C5ECFF328D + C7FF51B1D6FFE2F6FCFFD7F4FFFFCEF2FFFFC8EFFFFFBAEBFFFF92DBFBFF56C1 + F1FF48C2F9FF3BBDF0FF009600FF00C000FF009600FF47B1E6FF88CAEEFF3490 + C8FF53B4D7FFE2F6FDFFDAF4FFFFD5F3FFFFBDEBFFFF89D5F7FF69C9F5FF4CB4 + E9FF8DDAFBFF8CDCFFFF009600FF009600FF009600FF4FBBE8FF8CD0F0FF3693 + C9FF55B6D8FFE2F8FDFFD4F3FFFFB0E4FAFF86CFF1FF7FD0F5FF78D0F5FF4CB1 + E4FFB0E4FAFFB6E9FFFF9BE1FFFF78D6FEFF40BDF5FF3DB5E9FF90D5F1FF3895 + CAFF4FB4D8FFE1F8FEFFCDEBF9FF92D2EDFF84CCEBFF6FBFE5FF56B1DBFF3B94 + C8FFCEECFAFFD9F5FFFFB9EAFFFF95DFFEFF77D5FFFFA5E4FFFF84DCFBFF3193 + C9FF89CADE004EB5D9FFA5D9EDFFD2EBF5FFBEDEEDFF95C9DEFF89C3DBFF70B8 + D6FF69B9DDFF90D7F5FF7FCFF5FF9DDBF8FFAAE3FAFF84CAECFF51A6D5FF74B3 + D500FFFFFF00C7E4EE0076C4DEFF7EC6E0FFD1EEF7FFF6FFFFFFF0FEFFFFCBED + FBFF50ADDAFF8BD7F7FFAAE1F9FF95D6F2FF62B2DBFF61AED4FFBAD9E800FFFF + FF00FFFFFF00FFFFFF00FCFEFE00AFD8E60063BDDBFF92CFE5FFE6F8FCFFE3F6 + FEFFAFDDF2FFB2E4F7FF72C0E1FF55ADD5FFA3CFE100F8FCFD00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F0F9FC0099CEE00055B6D9FF9CD5 + EAFF88CCE7FF4DAFD6FF8FC7DD00ECF6FB00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1F2F8007DC3 + DCFF76C0DCFFDCEFF700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000 + } + OnCreate = FormCreate + PopupMode = pmExplicit + PopupParent = CreateRepositoryFrm.Owner + Position = poOwnerFormCenter + LCLVersion = '1.9.0.0' + object rbCreateNew: TRadioButton + Left = 31 + Height = 19 + Top = 24 + Width = 135 + Caption = 'Create a new package' + Checked = True + TabOrder = 0 + TabStop = True + end + object rbAddExisting: TRadioButton + Left = 31 + Height = 19 + Top = 64 + Width = 180 + Caption = 'Add existing package from file' + TabOrder = 1 + end + object pnButtons: TPanel + Left = 0 + Height = 41 + Top = 116 + Width = 459 + Align = alBottom + BevelOuter = bvNone + BorderStyle = bsSingle + ClientHeight = 37 + ClientWidth = 455 + TabOrder = 2 + object bOk: TButton + Left = 266 + Height = 27 + Top = 4 + Width = 85 + Anchors = [akTop, akRight] + Caption = 'OK' + ModalResult = 1 + ParentShowHint = False + ShowHint = True + TabOrder = 0 + end + object bCancel: TButton + Left = 352 + Height = 27 + Top = 4 + Width = 85 + Anchors = [akTop, akRight] + BorderSpacing.Around = 1 + Caption = 'Cancel' + Constraints.MinWidth = 80 + ModalResult = 2 + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + end +end diff --git a/components/onlinepackagemanager/opkman_addrepositorypackagefrm.pas b/components/onlinepackagemanager/opkman_addrepositorypackagefrm.pas new file mode 100644 index 0000000000..04608c8643 --- /dev/null +++ b/components/onlinepackagemanager/opkman_addrepositorypackagefrm.pas @@ -0,0 +1,49 @@ +unit opkman_addrepositorypackagefrm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, + StdCtrls, Buttons, Menus; + +type + + { TAddRepositoryPackageFrm } + + TAddRepositoryPackageFrm = class(TForm) + bCancel: TButton; + bOk: TButton; + pnButtons: TPanel; + rbCreateNew: TRadioButton; + rbAddExisting: TRadioButton; + procedure FormCreate(Sender: TObject); + private + + public + + end; + +var + AddRepositoryPackageFrm: TAddRepositoryPackageFrm; + +implementation +uses opkman_const; +{$R *.lfm} + +{ TAddRepositoryPackageFrm } + +procedure TAddRepositoryPackageFrm.FormCreate(Sender: TObject); +begin + Caption := rsAddRepositoryPackageFrm_Caption; + rbCreateNew.Caption := rsAddRepositoryPackageFrm_rbCreateNew_Caption; + rbAddExisting.Caption := rsAddRepositoryPackageFrm_rbAddExisting_Caption; + bOk.Caption := rsAddRepositoryPackageFrm_bOk_Caption; + bOk.Hint := rsAddRepositoryPackageFrm_bOk_Hint; + bCancel.Caption := rsAddRepositoryPackageFrm_bCancel_Caption; + bCancel.Hint := rsAddRepositoryPackageFrm_bCancel_Hint; +end; + +end. + diff --git a/components/onlinepackagemanager/opkman_common.pas b/components/onlinepackagemanager/opkman_common.pas index d10bfe4ccb..ab3cc178b4 100644 --- a/components/onlinepackagemanager/opkman_common.pas +++ b/components/onlinepackagemanager/opkman_common.pas @@ -446,7 +446,7 @@ var SearchRes: Longint; begin Result := true; - SearchRes := FindFirst(IncludeTrailingPathDelimiter(ADirectory) + AllFilesMask, faAnyFile + faSymLink, SearchRec); + SearchRes := FindFirst(IncludeTrailingPathDelimiter(ADirectory) + AllFilesMask, faAnyFile, SearchRec); try while SearchRes = 0 do begin diff --git a/components/onlinepackagemanager/opkman_const.pas b/components/onlinepackagemanager/opkman_const.pas index 546a8e5af5..acb5443f5a 100644 --- a/components/onlinepackagemanager/opkman_const.pas +++ b/components/onlinepackagemanager/opkman_const.pas @@ -396,7 +396,7 @@ resourcestring rsRepositories_Info1 = 'The following repository: "%s" is already in the list.'; //create private repository - rsCreateRepositoryFrm_Caption = 'Create private repository'; + rsCreateRepositoryFrm_Caption = 'Create/Edit private repository'; rsCreateRepositoryFrm_bOpen_Caption = 'Open'; rsCreateRepositoryFrm_bOpen_Hint = 'Open private respository'; rsCreateRepositoryFrm_bCreate_Caption = 'Create'; @@ -432,27 +432,40 @@ resourcestring rsCreateRepositoryFrm_VSTText_PackageType1 = 'Designtime'; rsCreateRepositoryFrm_VSTText_PackageType2 = 'Runtime'; rsCreateRepositoryFrm_VSTText_PackageType3 = 'Runtime only, cannot be installed in IDE'; - rsCreateRepositoryFrm_Error1 = 'Cannot open private repository. Error message: ' + sLineBreak + '"%s"'; + rsCreateRepositoryFrm_Error1 = 'Cannot open private repository: "%s". Error message: ' + sLineBreak + '"%s"'; rsCreateRepositoryFrm_Error2 = 'File ' + cRemoteJSONFile + ' not found.'; - rsCreateRepositoryFrm_Error3 = 'Cannot save private repository. Error message: ' + sLineBreak + '"%s"'; + rsCreateRepositoryFrm_Error3 = 'Cannot save private repository: "%s". Error message: ' + sLineBreak + '"%s"'; + rsCreateRepositoryFrm_Error4 = 'Cannot add package to repository!'; rsCreateRepositoryFrm_Info1 = 'The following directory: "%s" is not empty.' + sLineBreak + 'It''s recommended to save the repository to an empty directory. Continue?'; rsCreateRepositoryFrm_Info2 = 'The following directory: "%s" is read only.'; + rsCreateRepositoryFrm_Info3 = 'The following repository package: "%s" is already in the current repository.' + sLineBreak + 'Each repository and lazarus package must be unique!'; + rsCreateRepositoryFrm_Info4 = 'The following file: "%s" already exists in the current repository.'; + rsCreateRepositoryFrm_Info5 = 'The following lazarus package: "%s" is already in the current repository.' + sLineBreak + 'Each repository and lazarus package must be unique!'; //repository details - rsRepositoryDetails_Caption = 'Repository details'; - rsRepositoryDetails_lbName_Caption = 'Name'; - rsRepositoryDetails_edName_Hint = 'Enter the repository name'; - rsRepositoryDetails_lbAddress_Caption = 'Address'; - rsRepositoryDetails_edAddress_Hint = 'Enter the repository address(Ex: "http://localhost/packages/")'; - rsRepositoryDetails_lbDescription_Caption = 'Description'; - rsRepositoryDetails_mDescription_Hint = 'Enter the repository description'; - rsRepositoryDetails_bOk_Caption = 'OK'; - rsRepositoryDetails_bOk_Hint = 'Save and close the dialog'; - rsRepositoryDetails_bCancel_Caption = 'Cancel'; - rsRepositoryDetails_bCancel_Hint = 'Close the dialog without saving'; - rsRepositoryDetails_Info1 = 'Please enter the repository name.'; - rsRepositoryDetails_Info2 = 'Please enter the repository address.'; - rsRepositoryDetails_Info3 = 'The following repository: "%s" is already in the repository list. Continue?'; + rsRepositoryDetailsFrm_Caption = 'Repository details'; + rsRepositoryDetailsFrm_lbName_Caption = 'Name'; + rsRepositoryDetailsFrm_edName_Hint = 'Enter the repository name'; + rsRepositoryDetailsFrm_lbAddress_Caption = 'Address'; + rsRepositoryDetailsFrm_edAddress_Hint = 'Enter the repository address(Ex: "http://localhost/packages/")'; + rsRepositoryDetailsFrm_lbDescription_Caption = 'Description'; + rsRepositoryDetailsFrm_mDescription_Hint = 'Enter the repository description'; + rsRepositoryDetailsFrm_bOk_Caption = 'OK'; + rsRepositoryDetailsFrm_bOk_Hint = 'Save and close the dialog'; + rsRepositoryDetailsFrm_bCancel_Caption = 'Cancel'; + rsRepositoryDetailsFrm_bCancel_Hint = 'Close the dialog without saving'; + rsRepositoryDetailsFrm_Info1 = 'Please enter the repository name.'; + rsRepositoryDetailsFrm_Info2 = 'Please enter the repository address.'; + rsRepositoryDetailsFrm_Info3 = 'The following repository: "%s" is already in the repository list. Continue?'; + + //add package to repository + rsAddRepositoryPackageFrm_Caption = 'Add repository package'; + rsAddRepositoryPackageFrm_rbCreateNew_Caption = 'Create a new repository package'; + rsAddRepositoryPackageFrm_rbAddExisting_Caption = 'Add existing repository package from file'; + rsAddRepositoryPackageFrm_bOk_Caption = 'OK'; + rsAddRepositoryPackageFrm_bOk_Hint = 'Close the dialog and create the package'; + rsAddRepositoryPackageFrm_bCancel_Caption = 'Cancel'; + rsAddRepositoryPackageFrm_bCancel_Hint = 'Close the dialog'; implementation diff --git a/components/onlinepackagemanager/opkman_createrepositoryfrm.lfm b/components/onlinepackagemanager/opkman_createrepositoryfrm.lfm index b8bb9b170d..358b77e0aa 100644 --- a/components/onlinepackagemanager/opkman_createrepositoryfrm.lfm +++ b/components/onlinepackagemanager/opkman_createrepositoryfrm.lfm @@ -11,6 +11,7 @@ object CreateRepositoryFrm: TCreateRepositoryFrm Constraints.MinWidth = 650 OnCreate = FormCreate OnDestroy = FormDestroy + OnShow = FormShow PopupMode = pmExplicit Position = poOwnerFormCenter LCLVersion = '1.9.0.0' @@ -27,7 +28,7 @@ object CreateRepositoryFrm: TCreateRepositoryFrm TabOrder = 2 OnResize = pnButtonsResize object bOpen: TButton - Left = 101 + Left = 102 Height = 27 Top = 4 Width = 85 @@ -60,7 +61,7 @@ object CreateRepositoryFrm: TCreateRepositoryFrm ModalResult = 2 ParentShowHint = False ShowHint = True - TabOrder = 2 + TabOrder = 4 end object bAdd: TBitBtn Left = 311 @@ -69,45 +70,79 @@ object CreateRepositoryFrm: TCreateRepositoryFrm Width = 85 Caption = 'Add' Glyph.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + 36080000424D3608000000000000360000002800000020000000100000000100 + 2000000000000008000064000000640000000000000000000000FFFFFF00FFFF FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00BDD8E8005FA7D3FF56A2D0FFB5D3 E500009600FF009600FF009600FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00D9D9D900ABABABFFA7A7A7FFD4D4 + D400585858FF585858FF585858FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF FF00FFFFFF00FFFFFF00D7E9F20078B7DBFF2D8EC8FF8FCDEBFF6FB7E2FF408E C8FF009600FF00C000FF009600FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00E9E9E900BABABAFF949494FFCECECEFFBBBBBBFF9696 + 96FF585858FF707070FF585858FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF FF00ECF4F90093C9E3FF3F9CCEFF82C4E5FFCCF4FFFFC4EFFFFF8BD2F1FF8ACE - F0FF009600FF00C000FF009600FFD1E9E100FFFFFF00FFFFFF00FAFDFE00AFD8 + F0FF009600FF00C000FF009600FFD1E9E100FFFFFF00FFFFFF00FFFFFF00FFFF + FF00F4F4F400CACACAFFA0A0A0FFC6C6C6FFF2F2F2FFEEEEEEFFD3D3D3FFD0D0 + D0FF585858FF707070FF585858FFE3E3E300FFFFFF00FFFFFF00FAFDFE00AFD8 EB0055ABD5FF7DC0E0FFC7EEFCFFCCF2FFFFA8E8FFFF009600FF009600FF0096 - 00FF009600FF00C000FF009600FF009600FF009600FF009600FF6FB8D80077BD + 00FF009600FF00C000FF009600FF009600FF009600FF009600FFFCFCFC00D9D9 + D900ADADADFFC1C1C1FFEDEDEDFFF1F1F1FFE7E7E7FF585858FF585858FF5858 + 58FF585858FF707070FF585858FF585858FF585858FF585858FF6FB8D80077BD DCFFBFE5F6FFDBF6FFFFC1EEFFFFA5E5FFFF9FE3FFFF009600FF00C000FF00C0 - 00FF00C000FF00C000FF00C000FF00C000FF00C000FF009600FF45A9D3FFE7FB + 00FF00C000FF00C000FF00C000FF00C000FF00C000FF009600FFB9B9B900BEBE + BEFFE5E5E5FFF5F5F5FFEDEDEDFFE5E5E5FFE3E3E3FF585858FF707070FF7070 + 70FF707070FF707070FF707070FF707070FF707070FF585858FF45A9D3FFE7FB FEFFDDF6FFFFC1EFFFFFB7EBFFFFABE8FFFFA4E4FFFF009600FF009600FF0096 - 00FF009600FF00C000FF009600FF009600FF009600FF009600FF4EAED6FFE2F6 + 00FF009600FF00C000FF009600FF009600FF009600FF009600FFAAAAAAFFF9F9 + F9FFF5F5F5FFEEEEEEFFEBEBEBFFE7E7E7FFE4E4E4FF585858FF585858FF5858 + 58FF585858FF707070FF585858FF585858FF585858FF585858FF4EAED6FFE2F6 FCFFD4F3FFFFC9F0FFFFBEEDFFFFB3EAFFFFADE7FFFF7CD9FEFF48C7EFFF43C4 - EAFF009600FF00C000FF009600FF40A7E1FF83C5ECFF328DC7FF51B1D6FFE2F6 + EAFF009600FF00C000FF009600FF40A7E1FF83C5ECFF328DC7FFAFAFAFFFF5F5 + F5FFF3F3F3FFF0F0F0FFEDEDEDFFEAEAEAFFE7E7E7FFD9D9D9FFC4C4C4FFC0C0 + C0FF585858FF707070FF585858FFACACACFFC9C9C9FF939393FF51B1D6FFE2F6 FCFFD7F4FFFFCEF2FFFFC8EFFFFFBAEBFFFF92DBFBFF56C1F1FF48C2F9FF3BBD - F0FF009600FF00C000FF009600FF47B1E6FF88CAEEFF3490C8FF53B4D7FFE2F6 + F0FF009600FF00C000FF009600FF47B1E6FF88CAEEFF3490C8FFB1B1B1FFF5F5 + F5FFF3F3F3FFF1F1F1FFEFEFEFFFEBEBEBFFDCDCDCFFC3C3C3FFC4C4C4FFBDBD + BDFF585858FF707070FF585858FFB4B4B4FFCDCDCDFF969696FF53B4D7FFE2F6 FDFFDAF4FFFFD5F3FFFFBDEBFFFF89D5F7FF69C9F5FF4CB4E9FF8DDAFBFF8CDC - FFFF009600FF009600FF009600FF4FBBE8FF8CD0F0FF3693C9FF55B6D8FFE2F8 + FFFF009600FF009600FF009600FF4FBBE8FF8CD0F0FF3693C9FFB3B3B3FFF5F5 + F5FFF4F4F4FFF3F3F3FFEBEBEBFFD6D6D6FFCBCBCBFFB7B7B7FFDBDBDBFFDDDD + DDFF585858FF585858FF585858FFBCBCBCFFD1D1D1FF989898FF55B6D8FFE2F8 FDFFD4F3FFFFB0E4FAFF86CFF1FF7FD0F5FF78D0F5FF4CB1E4FFB0E4FAFFB6E9 - FFFF9BE1FFFF78D6FEFF40BDF5FF3DB5E9FF90D5F1FF3895CAFF4FB4D8FFE1F8 + FFFF9BE1FFFF78D6FEFF40BDF5FF3DB5E9FF90D5F1FF3895CAFFB5B5B5FFF6F6 + F6FFF3F3F3FFE4E4E4FFD0D0D0FFD1D1D1FFD1D1D1FFB4B4B4FFE4E4E4FFE9E9 + E9FFE1E1E1FFD7D7D7FFBFBFBFFFB6B6B6FFD5D5D5FF9A9A9AFF4FB4D8FFE1F8 FEFFCDEBF9FF92D2EDFF84CCEBFF6FBFE5FF56B1DBFF3B94C8FFCEECFAFFD9F5 - FFFFB9EAFFFF95DFFEFF77D5FFFFA5E4FFFF84DCFBFF3193C9FF89CADE004EB5 + FFFFB9EAFFFF95DFFEFF77D5FFFFA5E4FFFF84DCFBFF3193C9FFB3B3B3FFF7F7 + F7FFEBEBEBFFD2D2D2FFCDCDCDFFC1C1C1FFB3B3B3FF999999FFECECECFFF4F4 + F4FFEAEAEAFFDFDFDFFFD6D6D6FFE4E4E4FFDBDBDBFF979797FF89CADE004EB5 D9FFA5D9EDFFD2EBF5FFBEDEEDFF95C9DEFF89C3DBFF70B8D6FF69B9DDFF90D7 - F5FF7FCFF5FF9DDBF8FFAAE3FAFF84CAECFF51A6D5FF74B3D500FFFFFF00C7E4 + F5FF7FCFF5FF9DDBF8FFAAE3FAFF84CAECFF51A6D5FF74B3D500C8C8C800B4B4 + B4FFD9D9D9FFEBEBEBFFDEDEDEFFC9C9C9FFC3C3C3FFB8B8B8FFBABABAFFD7D7 + D7FFD1D1D1FFDCDCDCFFE3E3E3FFCCCCCCFFAAAAAAFFB5B5B500FFFFFF00C7E4 EE0076C4DEFF7EC6E0FFD1EEF7FFF6FFFFFFF0FEFFFFCBEDFBFF50ADDAFF8BD7 - F7FFAAE1F9FF95D6F2FF62B2DBFF61AED4FFBAD9E800FFFFFF00FFFFFF00FFFF + F7FFAAE1F9FF95D6F2FF62B2DBFF61AED4FFBAD9E800FFFFFF00FFFFFF00E3E3 + E300C2C2C2FFC5C5C5FFEDEDEDFFFDFDFDFFFCFCFCFFEDEDEDFFAFAFAFFFD7D7 + D7FFE1E1E1FFD6D6D6FFB5B5B5FFB0B0B0FFD9D9D900FFFFFF00FFFFFF00FFFF FF00FCFEFE00AFD8E60063BDDBFF92CFE5FFE6F8FCFFE3F6FEFFAFDDF2FFB2E4 F7FF72C0E1FF55ADD5FFA3CFE100F8FCFD00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FDFDFD00D7D7D700BBBBBBFFCECECEFFF7F7F7FFF6F6F6FFDEDEDEFFE3E3 + E3FFC0C0C0FFAEAEAEFFCFCFCF00FBFBFB00FFFFFF00FFFFFF00FFFFFF00FFFF FF00FFFFFF00FFFFFF00F0F9FC0099CEE00055B6D9FF9CD5EAFF88CCE7FF4DAF D6FF8FC7DD00ECF6FB00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00F8F8F800CDCDCD00B5B5B5FFD4D4D4FFCCCCCCFFAFAF + AFFFC7C7C700F6F6F600FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1F2F8007DC3DCFF76C0DCFFDCEF - F700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + F700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F1F1F100C2C2C2FFBFBFBFFFEFEF + EF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 } GlyphShowMode = gsmAlways + NumGlyphs = 2 + OnClick = bAddClick ParentShowHint = False ShowHint = True - TabOrder = 3 + TabOrder = 2 end object bDelete: TBitBtn Left = 396 @@ -116,45 +151,78 @@ object CreateRepositoryFrm: TCreateRepositoryFrm Width = 85 Caption = 'Delete' Glyph.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + 36080000424D3608000000000000360000002800000020000000100000000100 + 2000000000000008000064000000640000000000000000000000FFFFFF00FFFF FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00BDD8E8005FA7D3FF56A2D0FFB5D3 E500009600FF009600FF009600FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00D9D9D900ABABABFFA7A7A7FFD4D4 + D400585858FF585858FF585858FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF FF00FFFFFF00FFFFFF00D7E9F20078B7DBFF2D8EC8FF8FCDEBFF6FB7E2FF408E C8FF009600FF00C000FF009600FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00E9E9E900BABABAFF949494FFCECECEFFBBBBBBFF9696 + 96FF585858FF707070FF585858FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF FF00ECF4F90093C9E3FF3F9CCEFF82C4E5FFCCF4FFFFC4EFFFFF8BD2F1FF8ACE - F0FF009600FF00C000FF009600FFD1E9E100FFFFFF00FFFFFF00FAFDFE00AFD8 + F0FF009600FF00C000FF009600FFD1E9E100FFFFFF00FFFFFF00FFFFFF00FFFF + FF00F4F4F400CACACAFFA0A0A0FFC6C6C6FFF2F2F2FFEEEEEEFFD3D3D3FFD0D0 + D0FF585858FF707070FF585858FFE3E3E300FFFFFF00FFFFFF00FAFDFE00AFD8 EB0055ABD5FF7DC0E0FFC7EEFCFFCCF2FFFFA8E8FFFF009600FF009600FF0096 - 00FF009600FF00C000FF009600FF009600FF009600FF009600FF6FB8D80077BD + 00FF009600FF00C000FF009600FF009600FF009600FF009600FFFCFCFC00D9D9 + D900ADADADFFC1C1C1FFEDEDEDFFF1F1F1FFE7E7E7FF585858FF585858FF5858 + 58FF585858FF707070FF585858FF585858FF585858FF585858FF6FB8D80077BD DCFFBFE5F6FFDBF6FFFFC1EEFFFFA5E5FFFF9FE3FFFF009600FF00C000FF00C0 - 00FF00C000FF00C000FF00C000FF00C000FF00C000FF009600FF45A9D3FFE7FB + 00FF00C000FF00C000FF00C000FF00C000FF00C000FF009600FFB9B9B900BEBE + BEFFE5E5E5FFF5F5F5FFEDEDEDFFE5E5E5FFE3E3E3FF585858FF707070FF7070 + 70FF707070FF707070FF707070FF707070FF707070FF585858FF45A9D3FFE7FB FEFFDDF6FFFFC1EFFFFFB7EBFFFFABE8FFFFA4E4FFFF009600FF009600FF0096 - 00FF009600FF00C000FF009600FF009600FF009600FF009600FF4EAED6FFE2F6 + 00FF009600FF00C000FF009600FF009600FF009600FF009600FFAAAAAAFFF9F9 + F9FFF5F5F5FFEEEEEEFFEBEBEBFFE7E7E7FFE4E4E4FF585858FF585858FF5858 + 58FF585858FF707070FF585858FF585858FF585858FF585858FF4EAED6FFE2F6 FCFFD4F3FFFFC9F0FFFFBEEDFFFFB3EAFFFFADE7FFFF7CD9FEFF48C7EFFF43C4 - EAFF009600FF00C000FF009600FF40A7E1FF83C5ECFF328DC7FF51B1D6FFE2F6 + EAFF009600FF00C000FF009600FF40A7E1FF83C5ECFF328DC7FFAFAFAFFFF5F5 + F5FFF3F3F3FFF0F0F0FFEDEDEDFFEAEAEAFFE7E7E7FFD9D9D9FFC4C4C4FFC0C0 + C0FF585858FF707070FF585858FFACACACFFC9C9C9FF939393FF51B1D6FFE2F6 FCFFD7F4FFFFCEF2FFFFC8EFFFFFBAEBFFFF92DBFBFF56C1F1FF48C2F9FF3BBD - F0FF009600FF00C000FF009600FF47B1E6FF88CAEEFF3490C8FF53B4D7FFE2F6 + F0FF009600FF00C000FF009600FF47B1E6FF88CAEEFF3490C8FFB1B1B1FFF5F5 + F5FFF3F3F3FFF1F1F1FFEFEFEFFFEBEBEBFFDCDCDCFFC3C3C3FFC4C4C4FFBDBD + BDFF585858FF707070FF585858FFB4B4B4FFCDCDCDFF969696FF53B4D7FFE2F6 FDFFDAF4FFFFD5F3FFFFBDEBFFFF89D5F7FF69C9F5FF4CB4E9FF8DDAFBFF8CDC - FFFF009600FF009600FF009600FF4FBBE8FF8CD0F0FF3693C9FF55B6D8FFE2F8 + FFFF009600FF009600FF009600FF4FBBE8FF8CD0F0FF3693C9FFB3B3B3FFF5F5 + F5FFF4F4F4FFF3F3F3FFEBEBEBFFD6D6D6FFCBCBCBFFB7B7B7FFDBDBDBFFDDDD + DDFF585858FF585858FF585858FFBCBCBCFFD1D1D1FF989898FF55B6D8FFE2F8 FDFFD4F3FFFFB0E4FAFF86CFF1FF7FD0F5FF78D0F5FF4CB1E4FFB0E4FAFFB6E9 - FFFF9BE1FFFF78D6FEFF40BDF5FF3DB5E9FF90D5F1FF3895CAFF4FB4D8FFE1F8 + FFFF9BE1FFFF78D6FEFF40BDF5FF3DB5E9FF90D5F1FF3895CAFFB5B5B5FFF6F6 + F6FFF3F3F3FFE4E4E4FFD0D0D0FFD1D1D1FFD1D1D1FFB4B4B4FFE4E4E4FFE9E9 + E9FFE1E1E1FFD7D7D7FFBFBFBFFFB6B6B6FFD5D5D5FF9A9A9AFF4FB4D8FFE1F8 FEFFCDEBF9FF92D2EDFF84CCEBFF6FBFE5FF56B1DBFF3B94C8FFCEECFAFFD9F5 - FFFFB9EAFFFF95DFFEFF77D5FFFFA5E4FFFF84DCFBFF3193C9FF89CADE004EB5 + FFFFB9EAFFFF95DFFEFF77D5FFFFA5E4FFFF84DCFBFF3193C9FFB3B3B3FFF7F7 + F7FFEBEBEBFFD2D2D2FFCDCDCDFFC1C1C1FFB3B3B3FF999999FFECECECFFF4F4 + F4FFEAEAEAFFDFDFDFFFD6D6D6FFE4E4E4FFDBDBDBFF979797FF89CADE004EB5 D9FFA5D9EDFFD2EBF5FFBEDEEDFF95C9DEFF89C3DBFF70B8D6FF69B9DDFF90D7 - F5FF7FCFF5FF9DDBF8FFAAE3FAFF84CAECFF51A6D5FF74B3D500FFFFFF00C7E4 + F5FF7FCFF5FF9DDBF8FFAAE3FAFF84CAECFF51A6D5FF74B3D500C8C8C800B4B4 + B4FFD9D9D9FFEBEBEBFFDEDEDEFFC9C9C9FFC3C3C3FFB8B8B8FFBABABAFFD7D7 + D7FFD1D1D1FFDCDCDCFFE3E3E3FFCCCCCCFFAAAAAAFFB5B5B500FFFFFF00C7E4 EE0076C4DEFF7EC6E0FFD1EEF7FFF6FFFFFFF0FEFFFFCBEDFBFF50ADDAFF8BD7 - F7FFAAE1F9FF95D6F2FF62B2DBFF61AED4FFBAD9E800FFFFFF00FFFFFF00FFFF + F7FFAAE1F9FF95D6F2FF62B2DBFF61AED4FFBAD9E800FFFFFF00FFFFFF00E3E3 + E300C2C2C2FFC5C5C5FFEDEDEDFFFDFDFDFFFCFCFCFFEDEDEDFFAFAFAFFFD7D7 + D7FFE1E1E1FFD6D6D6FFB5B5B5FFB0B0B0FFD9D9D900FFFFFF00FFFFFF00FFFF FF00FCFEFE00AFD8E60063BDDBFF92CFE5FFE6F8FCFFE3F6FEFFAFDDF2FFB2E4 F7FF72C0E1FF55ADD5FFA3CFE100F8FCFD00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FDFDFD00D7D7D700BBBBBBFFCECECEFFF7F7F7FFF6F6F6FFDEDEDEFFE3E3 + E3FFC0C0C0FFAEAEAEFFCFCFCF00FBFBFB00FFFFFF00FFFFFF00FFFFFF00FFFF FF00FFFFFF00FFFFFF00F0F9FC0099CEE00055B6D9FF9CD5EAFF88CCE7FF4DAF D6FF8FC7DD00ECF6FB00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00F8F8F800CDCDCD00B5B5B5FFD4D4D4FFCCCCCCFFAFAF + AFFFC7C7C700F6F6F600FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E1F2F8007DC3DCFF76C0DCFFDCEF - F700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + F700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F1F1F100C2C2C2FFBFBFBFFFEFEF + EF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 } GlyphShowMode = gsmAlways + NumGlyphs = 2 ParentShowHint = False ShowHint = True - TabOrder = 4 + TabOrder = 3 end end object pnPackages: TPanel @@ -1056,4 +1124,11 @@ object CreateRepositoryFrm: TCreateRepositoryFrm 0000AA690000AA690000FFFFFF00 } end + object tmWait: TTimer + Enabled = False + Interval = 100 + OnTimer = tmWaitTimer + left = 85 + top = 32 + end end diff --git a/components/onlinepackagemanager/opkman_createrepositoryfrm.pas b/components/onlinepackagemanager/opkman_createrepositoryfrm.pas index 67c0e48c44..7354ffc532 100644 --- a/components/onlinepackagemanager/opkman_createrepositoryfrm.pas +++ b/components/onlinepackagemanager/opkman_createrepositoryfrm.pas @@ -64,11 +64,15 @@ type pnDetails: TPanel; SD: TSaveDialog; spMain: TSplitter; + tmWait: TTimer; + procedure bAddClick(Sender: TObject); procedure bCreateClick(Sender: TObject); procedure bOpenClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); + procedure FormShow(Sender: TObject); procedure pnButtonsResize(Sender: TObject); + procedure tmWaitTimer(Sender: TObject); private FVSTPackages: TVirtualStringTree; FVSTDetails: TVirtualStringTree; @@ -79,7 +83,12 @@ type function LoadRepository(const AFileName: String): Boolean; function SaveRepository(const AFileName: String): Boolean; procedure PopulatePackageTree; + procedure AddNewPackage; + procedure AddExistingPackage; function GetDisplayString(const AStr: String): String; + function LoadJSONFromFile(const AFileName: String; out AJSON: TJSONStringType): Boolean; + function SaveJSONToFile(const AFileName: String; const AJSON: TJSONStringType): Boolean; + function IsDuplicatePackage(const AJSON: TJSONStringType; const APackageFile: String): Boolean; procedure VSTPackagesGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; {%H-}Column: TColumnIndex; {%H-}TextType: TVSTTextType; var CellText: String); procedure VSTPackagesGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; @@ -108,7 +117,8 @@ var implementation -uses opkman_common, opkman_const, opkman_options, opkman_repositorydetailsfrm; +uses opkman_common, opkman_const, opkman_options, opkman_repositorydetailsfrm, + opkman_addrepositorypackagefrm, opkman_createrepositorypackagefrm; {$R *.lfm} @@ -271,6 +281,135 @@ begin end; end; +function TCreateRepositoryFrm.IsDuplicatePackage(const AJSON: TJSONStringType; + const APackageFile: String): Boolean; +var + SP: TSerializablePackages; + MetaPackage: TMetaPackage; + LazarusPackage: TLazarusPackage; + TargetPackageFile: String; + I: Integer; +begin + Result := False; + SP := TSerializablePackages.Create; + try + if SP.JSONToPackages(AJSON) then + begin + MetaPackage := FSerializablePackages.FindMetaPackage(SP.Items[0].Name, fpbPackageName); + if MetaPackage <> nil then + begin + Result := True; + MessageDlgEx(Format(rsCreateRepositoryFrm_Info3, [MetaPackage.DisplayName]), mtInformation, [mbOk], Self); + end; + + if not Result then + begin + for I := 0 to MetaPackage.LazarusPackages.Count - 1 do + begin + LazarusPackage := FSerializablePackages.FindLazarusPackage(TLazarusPackage(MetaPackage.LazarusPackages.Items[I]).Name); + if LazarusPackage <> nil then + begin + Result := True; + MessageDlgEx(Format(rsCreateRepositoryFrm_Info5, [TLazarusPackage(MetaPackage.LazarusPackages.Items[I]).Name]), mtInformation, [mbOk], Self); + Break; + end; + end; + + if not Result then + begin + TargetPackageFile := AppendPathDelim(ExtractFilePath(FRepository.FPath)) + ExtractFileName(APackageFile); + if FileExists(TargetPackageFile) then + begin + Result := True; + MessageDlgEx(Format(rsCreateRepositoryFrm_Info4, [TargetPackageFile]), mtInformation, [mbOk], Self); + end; + + if (not Result) and (not CopyFile(APackageFile, TargetPackageFile, True)) then + Result := True; + end; + end; + end; + finally + SP.Free; + end; +end; + +procedure TCreateRepositoryFrm.AddNewPackage; +var + CreateRepositoryPackagesFrm: TCreateRepositoryPackagesFrm; + JSON: TJSONStringType; + CanGo: Boolean; +begin + CreateRepositoryPackagesFrm := TCreateRepositoryPackagesFrm.Create(Self); + try + with CreateRepositoryPackagesFrm do + begin + SetType(1); + DestDir := AppendPathDelim(AppendPathDelim(ExtractFilePath(FRepository.FPath)) + 'Temp'); + if not DirectoryExists(DestDir) then + CreateDir(DestDir); + ShowModal; + if ModalResult = mrOk then + begin + CanGo := False; + if FileExists(PackageFile) and FileExists(JSONFile) then + begin + if LoadJSONFromFile(JSONFile, JSON) then + begin + if not IsDuplicatePackage(JSON, PackageFile) then + begin + if FSerializablePackages.AddPackageFromJSON(JSON) then + begin + JSON := ''; + if FSerializablePackages.PackagesToJSON(JSON) then + begin + if SaveJSONToFile(ExtractFilePath(FRepository.FPath) + cRemoteJSONFile, JSON) then + begin + if LoadRepository(FRepository.FPath) then + begin + CanGo := True; + PopulatePackageTree; + ShowHideControls(2); + EnableDisableButtons(True); + end; + end; + end; + end; + end; + end; + //DeleteFile(JSONFile); + end; + if not CanGo then + MessageDlgEx(rsCreateRepositoryFrm_Error4, mtError, [mbOk], Self); + end; + end; + finally + CreateRepositoryPackagesFrm.Free; + end; +end; + +procedure TCreateRepositoryFrm.AddExistingPackage; +begin + +end; + +procedure TCreateRepositoryFrm.bAddClick(Sender: TObject); +begin + AddRepositoryPackageFrm := TAddRepositoryPackageFrm.Create(Self); + try + AddRepositoryPackageFrm.ShowModal; + if AddRepositoryPackageFrm.ModalResult = mrOk then + begin + if AddRepositoryPackageFrm.rbCreateNew.Checked then + AddNewPackage + else + AddExistingPackage; + end; + finally + AddRepositoryPackageFrm.Free; + end; +end; + procedure TCreateRepositoryFrm.bOpenClick(Sender: TObject); begin if OD.Execute then @@ -291,6 +430,27 @@ begin FSerializablePackages.Free end; +procedure TCreateRepositoryFrm.FormShow(Sender: TObject); +begin + tmWait.Enabled := True; +end; + +procedure TCreateRepositoryFrm.tmWaitTimer(Sender: TObject); +begin + tmWait.Enabled := False; + if (Options.LastPrivateRepository <> '') and + (FileExists(Options.LastPrivateRepository)) and + (FileExists(AppendPathDelim(ExtractFilePath(Options.LastPrivateRepository)) + cRemoteJSONFile)) then + begin + if LoadRepository(Options.LastPrivateRepository) then + begin + PopulatePackageTree; + ShowHideControls(2); + EnableDisableButtons(True); + end; + end; +end; + procedure TCreateRepositoryFrm.pnButtonsResize(Sender: TObject); begin bAdd.Left := (pnButtons.Width - (bAdd.Width + bDelete.Width)) div 2; @@ -342,30 +502,26 @@ end; function TCreateRepositoryFrm.LoadRepository(const AFileName: String): Boolean; var FS: TFileStream; - procedure ReadString(out AString: String); - var - Len: Integer; - begin - Len := 0; - FS.Read(Len, SizeOf(Integer)); - SetLength(AString, Len div SizeOf(Char)); - FS.Read(Pointer(AString)^, Len); - end; begin Result := False; FS := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite); try try - ReadString(FRepository.FName); - ReadString(FRepository.FAddress); - ReadString(FRepository.FDescription); + FRepository.FName := FS.ReadAnsiString; + FRepository.FAddress := FS.ReadAnsiString; + FRepository.FDescription := FS.ReadAnsiString; FRepository.FPath := AFileName; - Result := FileExists(AppendPathDelim(ExtractFilePath(AFileName)) + cRemoteJSONFile); - if not Result then - MessageDlgEx(Format(rsCreateRepositoryFrm_Error1, [rsCreateRepositoryFrm_Error2]), mtError, [mbOk], Self); + Caption := rsCreateRepositoryFrm_Caption + '(' + AFileName + ')'; + Options.LastPrivateRepository := AFileName; + Options.Changed := True; + Result := True; except on E: Exception do - MessageDlgEx(Format(rsCreateRepositoryFrm_Error1, [E.Message]), mtError, [mbOk], Self); + begin + MessageDlgEx(Format(rsCreateRepositoryFrm_Error1, [AFileName, E.Message]), mtError, [mbOk], Self); + Options.LastPrivateRepository := ''; + Options.Changed := True; + end; end; finally FS.Free; @@ -376,14 +532,6 @@ function TCreateRepositoryFrm.SaveRepository(const AFileName: String): Boolean; var FS: TFileStream; FHandle: THandle; - procedure WriteString(const AString: String); - var - Len: Integer; - begin - Len := Length(AString)*SizeOf(Char); - FS.Write(Len, SizeOf(Integer)); - FS.Write(Pointer(AString)^, Len); - end; begin Result := False; if not IsDirectoryEmpty(ExtractFilePath(AFileName)) then @@ -405,9 +553,9 @@ begin FS := TFileStream.Create(AFileName, fmCreate or fmOpenWrite or fmShareDenyWrite); try try - WriteString(FRepository.FName); - WriteString(FRepository.FAddress); - WriteString(FRepository.FDescription); + FS.WriteAnsiString(FRepository.FName); + FS.WriteAnsiString(FRepository.FAddress); + FS.WriteAnsiString(FRepository.FDescription); FHandle := FileCreate(ExtractFilePath(AFileName) + cRemoteJSONFile); if fHandle <> THandle(-1) then begin @@ -416,7 +564,7 @@ begin end; except on E: Exception do - MessageDlgEx(Format(rsCreateRepositoryFrm_Error3, [E.Message]), mtError, [mbOk], Self); + MessageDlgEx(Format(rsCreateRepositoryFrm_Error3, [AFileName, E.Message]), mtError, [mbOk], Self); end; finally FS.Free; @@ -428,7 +576,6 @@ var RootNode, Node, ChildNode: PVirtualNode; RootData, Data, ChildData: PData; JSON: TJSONStringType; - Ms: TMemoryStream; i, j: Integer; MetaPackage: TMetaPackage; LazarusPackage: TLazarusPackage; @@ -442,55 +589,43 @@ begin RootData^.FName := FRepository.FName; RootData^.FDataType := 0; - if FileExists(ExtractFilePath(FRepository.FPath) + cRemoteJSONFile) then + if LoadJSONFromFile(ExtractFilePath(FRepository.FPath) + cRemoteJSONFile, JSON) then begin - Ms := TMemoryStream.Create; - try - Ms.LoadFromFile(ExtractFilePath(FRepository.FPath) + cRemoteJSONFile); - if Ms.Size > 0 then + FSerializablePackages.JSONToPackages(JSON); + for I := 0 to FSerializablePackages.Count - 1 do + begin + MetaPackage := TMetaPackage(FSerializablePackages.Items[I]); + Node := FVSTPackages.AddChild(RootNode); + Data := FVSTPackages.GetNodeData(Node); + if Trim(MetaPackage.DisplayName) <> '' then + Data^.FName := MetaPackage.DisplayName + else + Data^.FName := MetaPackage.Name; + Data^.FCategory := MetaPackage.Category; + Data^.FRepositoryFileName := MetaPackage.RepositoryFileName; + Data^.FRepositoryFileSize := MetaPackage.RepositoryFileSize; + Data^.FRepositoryFileHash := MetaPackage.RepositoryFileHash; + Data^.FRepositoryDate := MetaPackage.RepositoryDate; + Data^.FHomePageURL := MetaPackage.HomePageURL; + Data^.FDownloadURL := MetaPackage.DownloadURL; + Data^.FDataType := 1; + for J := 0 to MetaPackage.LazarusPackages.Count - 1 do begin - Ms.Position := 0; - SetLength(JSON, MS.Size); - MS.Read(Pointer(JSON)^, Length(JSON)); - FSerializablePackages.JSONToPackages(JSON); - for I := 0 to FSerializablePackages.Count - 1 do - begin - MetaPackage := TMetaPackage(FSerializablePackages.Items[I]); - Node := FVSTPackages.AddChild(RootNode); - Data := FVSTPackages.GetNodeData(Node); - if Trim(MetaPackage.DisplayName) <> '' then - Data^.FName := MetaPackage.DisplayName - else - Data^.FName := MetaPackage.Name; - Data^.FCategory := MetaPackage.Category; - Data^.FRepositoryFileName := MetaPackage.RepositoryFileName; - Data^.FRepositoryFileSize := MetaPackage.RepositoryFileSize; - Data^.FRepositoryFileHash := MetaPackage.RepositoryFileHash; - Data^.FRepositoryDate := MetaPackage.RepositoryDate; - Data^.FHomePageURL := MetaPackage.HomePageURL; - Data^.FDownloadURL := MetaPackage.DownloadURL; - Data^.FDataType := 1; - for J := 0 to MetaPackage.LazarusPackages.Count - 1 do - begin - LazarusPackage := TLazarusPackage(MetaPackage.LazarusPackages.Items[J]); - ChildNode := FVSTPackages.AddChild(Node); - ChildData := FVSTPackages.GetNodeData(ChildNode); - ChildData^.FName := LazarusPackage.Name; - ChildData^.FVersionAsString := LazarusPackage.VersionAsString; - ChildData^.FDescription := LazarusPackage.Description; - ChildData^.FAuthor := LazarusPackage.Author; - ChildData^.FLazCompatibility := LazarusPackage.LazCompatibility; - ChildData^.FFPCCompatibility := LazarusPackage.FPCCompatibility; - ChildData^.FSupportedWidgetSet := LazarusPackage.SupportedWidgetSet; - ChildData^.FPackageType := LazarusPackage.PackageType; - ChildData^.FLicense := LazarusPackage.License; - ChildData^.FDependenciesAsString := LazarusPackage.DependenciesAsString; - ChildData^.FDataType := 2; - end; - end; + LazarusPackage := TLazarusPackage(MetaPackage.LazarusPackages.Items[J]); + ChildNode := FVSTPackages.AddChild(Node); + ChildData := FVSTPackages.GetNodeData(ChildNode); + ChildData^.FName := LazarusPackage.Name; + ChildData^.FVersionAsString := LazarusPackage.VersionAsString; + ChildData^.FDescription := LazarusPackage.Description; + ChildData^.FAuthor := LazarusPackage.Author; + ChildData^.FLazCompatibility := LazarusPackage.LazCompatibility; + ChildData^.FFPCCompatibility := LazarusPackage.FPCCompatibility; + ChildData^.FSupportedWidgetSet := LazarusPackage.SupportedWidgetSet; + ChildData^.FPackageType := LazarusPackage.PackageType; + ChildData^.FLicense := LazarusPackage.License; + ChildData^.FDependenciesAsString := LazarusPackage.DependenciesAsString; + ChildData^.FDataType := 2; end; - finally - Ms.Free; end; end; if RootNode <> nil then @@ -520,6 +655,46 @@ begin end; end; +function TCreateRepositoryFrm.LoadJSONFromFile(const AFileName: String; + out AJSON: TJSONStringType): Boolean; +var + MS: TMemoryStream; +begin + Result := False; + if not FileExists(AFileName) then + Exit; + MS := TMemoryStream.Create; + try + Ms.LoadFromFile(AFileName); + if Ms.Size > 0 then + begin + Ms.Position := 0; + SetLength(AJSON, MS.Size); + MS.Read(Pointer(AJSON)^, Length(AJSON)); + Result := True; + end; + finally + MS.Free; + end; +end; + +function TCreateRepositoryFrm.SaveJSONToFile(const AFileName: String; + const AJSON: TJSONStringType): Boolean; +var + MS: TMemoryStream; +begin + Result := False; + MS := TMemoryStream.Create; + try + Ms.Write(Pointer(AJSON)^, Length(AJSON)); + Ms.Position := 0; + Ms.SaveToFile(AFileName); + Result := True; + finally + MS.Free; + end; +end; + procedure TCreateRepositoryFrm.VSTPackagesGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: String); @@ -603,12 +778,12 @@ begin //address DetailNode := FVSTDetails.AddChild(nil); DetailData := FVSTDetails.GetNodeData(DetailNode); - DetailData^.FDataType := 0; + DetailData^.FDataType := 17; DetailData^.FRepository.FAddress := FRepository.FAddress; //description DetailNode := FVSTDetails.AddChild(nil); DetailData := FVSTDetails.GetNodeData(DetailNode); - DetailData^.FDataType := 1; + DetailData^.FDataType := 3; DetailData^.FRepository.FDescription := FRepository.FDescription; end; 1: begin @@ -728,11 +903,11 @@ begin 0: begin DetailData := FVSTDetails.GetNodeData(Node); case DetailData^.FDataType of - 0: if Column = 0 then + 17: if Column = 0 then CellText := rsCreateRepositoryFrm_RepositoryAddress else CellText := DetailData^.FRepository.FAddress; - 1: if Column = 0 then + 3: if Column = 0 then CellText := rsCreateRepositoryFrm_RepositoryDescription else CellText := DetailData^.FRepository.FDescription; diff --git a/components/onlinepackagemanager/opkman_createrepositorypackagefrm.lfm b/components/onlinepackagemanager/opkman_createrepositorypackagefrm.lfm index 2533406b6f..16681f10bd 100644 --- a/components/onlinepackagemanager/opkman_createrepositorypackagefrm.lfm +++ b/components/onlinepackagemanager/opkman_createrepositorypackagefrm.lfm @@ -12,7 +12,6 @@ object CreateRepositoryPackagesFrm: TCreateRepositoryPackagesFrm OnCreate = FormCreate OnDestroy = FormDestroy PopupMode = pmExplicit - PopupParent = MainFrm.Owner Position = poOwnerFormCenter LCLVersion = '1.9.0.0' object pnMessage: TPanel @@ -298,6 +297,7 @@ object CreateRepositoryPackagesFrm: TCreateRepositoryPackagesFrm Top = 48 Width = 350 Anchors = [akTop, akLeft, akRight] + OnKeyPress = edDisplayNameKeyPress TabOrder = 1 end object pnCategories: TPanel diff --git a/components/onlinepackagemanager/opkman_createrepositorypackagefrm.pas b/components/onlinepackagemanager/opkman_createrepositorypackagefrm.pas index 96d4ae23a0..68e16c411d 100644 --- a/components/onlinepackagemanager/opkman_createrepositorypackagefrm.pas +++ b/components/onlinepackagemanager/opkman_createrepositorypackagefrm.pas @@ -89,6 +89,7 @@ type procedure bHelpClick(Sender: TObject); procedure bOptionsClick(Sender: TObject); procedure bSubmitClick(Sender: TObject); + procedure edDisplayNameKeyPress(Sender: TObject; var Key: char); procedure edPackageDirAcceptDirectory(Sender: TObject; Var Value: String); procedure edPackageDirButtonClick(Sender: TObject); procedure FormCreate(Sender: TObject); @@ -101,8 +102,10 @@ type FPackageDir: String; FPackageName: String; FPackageFile: String; + FJSONFile: String; FDestDir: String; FPackageOperation: TPackageOperation; + FTyp: Integer; procedure VSTPackagesGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; {%H-}TextType: TVSTTextType; var CellText: String); procedure VSTPackagesGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; @@ -134,8 +137,12 @@ type procedure DoOnUploadProgress(Sender: TObject; AFileName: String); procedure DoOnUploadError(Sender: TObject; AErrMsg: String); procedure DoOnUploadCompleted(Sender: TObject); + procedure CreatePackage; public procedure SetType(const ATyp: Integer); + property DestDir: String read FDestDir write FDestDir; + property PackageFile: string read FPackageFile; + property JSONFile: String read FJSONFile; end; var @@ -582,39 +589,55 @@ begin Result := True; end; -procedure TCreateRepositoryPackagesFrm.bCreateClick(Sender: TObject); +procedure TCreateRepositoryPackagesFrm.CreatePackage; var RootNode: PVirtualNode; RootData: PData; +begin + FPackageOperation := poCreate; + Screen.Cursor := crHourGlass; + ShowHideControls(1); + FPackageZipper := TPackageZipper.Create; + FPackageZipper.OnZipError := @DoOnZippError; + FPackageZipper.OnZipCompleted := @DoOnZipCompleted; + RootNode := FVSTPackages.GetFirst; + RootData := FVSTPackages.GetNodeData(RootNode); + if RootData^.FDisplayName <> '' then + FPackageName := StringReplace(RootData^.FDisplayName, ' ', '', [rfReplaceAll]) + else + FPackageName := StringReplace(RootData^.FName, ' ', '', [rfReplaceAll]); + FPackageFile := FDestDir + FPackageName + '.zip'; + FJSONFile := FDestDir + FPackageName + '.json'; + pnMessage.Caption := rsCreateRepositoryPackageFrm_Message4; + fPackageZipper.StartZip(FPackageDir, FPackageFile); +end; + + +procedure TCreateRepositoryPackagesFrm.bCreateClick(Sender: TObject); begin if not CanCreate then Exit; - SDD.Title := rsCreateRepositoryPackageFrm_SDDTitleDst; - SDD.InitialDir := Options.LastPackagedirDst; - EnableDisableControls(False); - if SDD.Execute then + if FTyp = 0 then begin - FPackageOperation := poCreate; - Screen.Cursor := crHourGlass; - ShowHideControls(1); - FPackageZipper := TPackageZipper.Create; - FPackageZipper.OnZipError := @DoOnZippError; - FPackageZipper.OnZipCompleted := @DoOnZipCompleted; - FDestDir := AppendPathDelim(SDD.FileName); - Options.LastPackagedirDst := SDD.FileName; - Options.Changed := True; - RootNode := FVSTPackages.GetFirst; - RootData := FVSTPackages.GetNodeData(RootNode); - if RootData^.FDisplayName <> '' then - FPackageName := StringReplace(RootData^.FDisplayName, ' ', '', [rfReplaceAll]) + SDD.Title := rsCreateRepositoryPackageFrm_SDDTitleDst; + SDD.InitialDir := Options.LastPackagedirDst; + EnableDisableControls(False); + if SDD.Execute then + begin + FDestDir := AppendPathDelim(SDD.FileName); + Options.LastPackagedirDst := FDestDir; + Options.Changed := True; + CreatePackage; + end else - FPackageName := StringReplace(RootData^.FName, ' ', '', [rfReplaceAll]); - FPackageFile := FDestDir + FPackageName + '.zip'; - pnMessage.Caption := rsCreateRepositoryPackageFrm_Message4; - fPackageZipper.StartZip(FPackageDir, FPackageFile); + EnableDisableControls(True); end - else - EnableDisableControls(True); + else if FTyp = 1 then + begin + Options.LastPackagedirDst := FDestDir; + Options.Changed := True; + CreatePackage; + end; end; procedure TCreateRepositoryPackagesFrm.bSubmitClick(Sender: TObject); @@ -639,10 +662,18 @@ begin else FPackageName := StringReplace(RootData^.FName, ' ', '', [rfReplaceAll]); FPackageFile := FDestDir + FPackageName + '.zip'; + FJSONFile := FDestDir + FPackageName + '.json'; pnMessage.Caption := rsCreateRepositoryPackageFrm_Message4; fPackageZipper.StartZip(FPackageDir, FPackageFile); end; +procedure TCreateRepositoryPackagesFrm.edDisplayNameKeyPress(Sender: TObject; + var Key: char); +begin + if Key in ['\', '/', ':', '*', '?', '"', '<', '>', '|'] then + Key := #0; +end; + procedure TCreateRepositoryPackagesFrm.bHelpClick(Sender: TObject); begin OpenURL(cHelpPage_CreateRepositoryPackage); @@ -658,7 +689,6 @@ begin if Assigned(FPackageZipper) then FPackageZipper.Terminate; ModalResult := mrCancel; - Close; end; procedure TCreateRepositoryPackagesFrm.VSTPackagesGetText( @@ -1006,7 +1036,10 @@ begin MetaPkg.RepositoryFileHash := MD5Print(MD5File(FPackageFile)); MetaPkg.RepositoryDate := Trunc(now); MetaPkg.PackageBaseDir := RootData^.FPackageBaseDir; - MetaPkg.DisplayName := RootData^.FDisplayName; + if Trim(RootData^.FDisplayName) <> '' then + MetaPkg.DisplayName := RootData^.FDisplayName + else + MetaPkg.DisplayName := RootData^.FName; MetaPkg.HomePageURL := RootData^.FHomePageURL; MetaPkg.DownloadURL := RootData^.FDownloadURL; MetaPkg.SVNURL := RootData^.FSVNURL; @@ -1043,7 +1076,7 @@ begin try MS.Write(Pointer(JSON)^, Length(JSON)); MS.Position := 0; - MS.SaveToFile(FDestDir + FPackageName + '.json'); + MS.SaveToFile(FJSONFile); Result := True; finally MS.Free; @@ -1084,9 +1117,9 @@ begin Screen.Cursor := crDefault; ShowHideControls(2); EnableDisableControls(True); - MessageDlgEx(rsCreateRepositoryPackageFrm_Message7, mtInformation, [mbOk], Self); + if FTyp = 0 then + MessageDlgEx(rsCreateRepositoryPackageFrm_Message7, mtInformation, [mbOk], Self); ModalResult := mrOk; - Close; end; poSubmit: begin @@ -1098,8 +1131,7 @@ begin JsonUpd := FDestDir + 'update_' + FPackageName + '.json' else JsonUpd := ''; - Uploader.StartUpload(cSubmitURL_Zip, cSubmitURL_JSON, FPackageFile, - FDestDir + FPackageName + '.json', JsonUpd); + Uploader.StartUpload(cSubmitURL_Zip, cSubmitURL_JSON, FPackageFile, FJSONFile, JsonUpd); end; end; end; @@ -1129,26 +1161,26 @@ begin Uploader := nil; if FileExists(FPackageFile) then DeleteFile(FPackageFile); - if FileExists(FDestDir + FPackageName + '.json') then - DeleteFile(FDestDir + FPackageName + '.json'); + if FileExists(FJSONFile) then + DeleteFile(FJSONFile); if FileExists(FDestDir + 'update_' + FPackageName + '.json') then DeleteFile(FDestDir + 'update_' + FPackageName + '.json'); MessageDlgEx(rsCreateRepositoryPackageFrm_Message9, mtInformation, [mbOk], Self); - Self.ModalResult := mrOk; - Self.Close; + ModalResult := mrOk; end; procedure TCreateRepositoryPackagesFrm.SetType(const ATyp: Integer); begin - bSubmit.Visible := ATyp = 0; - cbJSONForUpdates.Visible := ATyp = 0; + FTyp := ATyp; + bSubmit.Visible := FTyp = 0; + cbJSONForUpdates.Visible := FTyp = 0; bCreate.Visible := True; - if ATyp = 1 then + if FTyp = 1 then begin bCreate.Caption := rsCreateRepositoryPackageFrm_bCreate_Caption1; bCreate.Hint := rsCreateRepositoryPackageFrm_bCreate_Hint1; + pnB.AutoSize := True; end; - end; end. diff --git a/components/onlinepackagemanager/opkman_options.pas b/components/onlinepackagemanager/opkman_options.pas index 4ad1e21dc8..cb22e789e4 100644 --- a/components/onlinepackagemanager/opkman_options.pas +++ b/components/onlinepackagemanager/opkman_options.pas @@ -67,6 +67,7 @@ type FLastDownloadDir: String; FLastPackageDirSrc: String; FLastPackageDirDst: String; + FLastPrivateRepository: String; // Default values for local repositories. FLocalPackagesDefault: String; FLocalArchiveDefault: String; @@ -101,6 +102,7 @@ type property LastDownloadDir: String read FLastDownloadDir write FLastDownloadDir; property LastPackagedirSrc: String read FLastPackageDirSrc write FLastPackageDirSrc; property LastPackagedirDst: String read FLastPackageDirDst write FLastPackageDirDst; + property LastPrivateRepository: String read FLastPrivateRepository write FLastPrivateRepository; property ProxyEnabled: Boolean read FProxySettings.FEnabled write FProxySettings.FEnabled; property ProxyServer: String read FProxySettings.FServer write FProxySettings.FServer; property ProxyPort: Word read FProxySettings.FPort write FProxySettings.FPort; @@ -176,6 +178,7 @@ begin FLastDownloadDir := FXML.GetValue('General/LastDownloadDir/Value', ''); FLastPackageDirSrc := FXML.GetValue('General/LastPackageDirSrc/Value', ''); FLastPackageDirDst := FXML.GetValue('General/LastPackageDirDst/Value', ''); + FLastPrivateRepository := FXML.GetValue('General/LastPrivateRepository/Value', ''); FCheckForUpdates := FXML.GetValue('General/CheckForUpdates/Value', 0); FLastUpdate := FXML.GetExtendedValue('General/LastUpdate/Value', 0.0); FDaysToShowNewPackages := FXML.GetValue('General/DaysToShowNewPackages/Value', 31); @@ -207,6 +210,7 @@ begin FXML.SetDeleteValue('General/LastDownloadDir/Value', FLastDownloadDir, ''); FXML.SetDeleteValue('General/LastPackageDirSrc/Value', FLastPackageDirSrc, ''); FXML.SetDeleteValue('General/LastPackageDirDst/Value', FLastPackageDirDst, ''); + FXML.SetDeleteValue('General/LastPrivateRepository/Value', FLastPrivateRepository, ''); FXML.SetDeleteValue('General/CheckForUpdates/Value', FCheckForUpdates, 0); FXML.SetDeleteExtendedValue('General/LastUpdate/Value', FLastUpdate, 0.0); FXML.SetDeleteValue('General/DaysToShowNewPackages/Value', FDaysToShowNewPackages, 31); diff --git a/components/onlinepackagemanager/opkman_repositorydetailsfrm.pas b/components/onlinepackagemanager/opkman_repositorydetailsfrm.pas index 2b9fb0ed77..ef7ca4524e 100644 --- a/components/onlinepackagemanager/opkman_repositorydetailsfrm.pas +++ b/components/onlinepackagemanager/opkman_repositorydetailsfrm.pas @@ -44,17 +44,17 @@ uses opkman_const, opkman_common, opkman_options; procedure TRepositoryDetailsFrm.FormCreate(Sender: TObject); begin - Caption := rsRepositoryDetails_Caption; - lbName.Caption := rsRepositoryDetails_lbName_Caption; - edName.Hint := rsRepositoryDetails_edName_Hint; - lbAddress.Caption := rsRepositoryDetails_lbAddress_Caption; - edAddress.Hint := rsRepositoryDetails_edAddress_Hint; - lbDescription.Caption := rsRepositoryDetails_lbDescription_Caption; - mDescription.Hint := rsRepositoryDetails_mDescription_Hint; - bOk.Caption := rsRepositoryDetails_bOk_Caption; - bOk.Hint := rsRepositoryDetails_bOk_Hint; - bCancel.Caption := rsRepositoryDetails_bCancel_Caption; - bCancel.Hint := rsRepositoryDetails_bCancel_Hint; + Caption := rsRepositoryDetailsFrm_Caption; + lbName.Caption := rsRepositoryDetailsFrm_lbName_Caption; + edName.Hint := rsRepositoryDetailsFrm_edName_Hint; + lbAddress.Caption := rsRepositoryDetailsFrm_lbAddress_Caption; + edAddress.Hint := rsRepositoryDetailsFrm_edAddress_Hint; + lbDescription.Caption := rsRepositoryDetailsFrm_lbDescription_Caption; + mDescription.Hint := rsRepositoryDetailsFrm_mDescription_Hint; + bOk.Caption := rsRepositoryDetailsFrm_bOk_Caption; + bOk.Hint := rsRepositoryDetailsFrm_bOk_Hint; + bCancel.Caption := rsRepositoryDetailsFrm_bCancel_Caption; + bCancel.Hint := rsRepositoryDetailsFrm_bCancel_Hint; FAddress := ''; end; @@ -77,7 +77,7 @@ procedure TRepositoryDetailsFrm.bOkClick(Sender: TObject); begin if Trim(edName.Text) = '' then begin - MessageDlgEx(rsRepositoryDetails_Info1, mtInformation, [mbOk], Self); + MessageDlgEx(rsRepositoryDetailsFrm_Info1, mtInformation, [mbOk], Self); edName.SetFocus; Exit; end; @@ -88,7 +88,7 @@ begin FAddress := FAddress + '/'; if IsDuplicateRepository(FAddress) then begin - if MessageDlgEx(Format(rsRepositoryDetails_Info3, [FAddress]), mtInformation, [mbYes, mbNo], Self) = mrNo then + if MessageDlgEx(Format(rsRepositoryDetailsFrm_Info3, [FAddress]), mtInformation, [mbYes, mbNo], Self) = mrNo then begin edAddress.SetFocus; Exit; diff --git a/components/onlinepackagemanager/opkman_serializablepackages.pas b/components/onlinepackagemanager/opkman_serializablepackages.pas index d378a44427..a39c4bb4fe 100644 --- a/components/onlinepackagemanager/opkman_serializablepackages.pas +++ b/components/onlinepackagemanager/opkman_serializablepackages.pas @@ -274,6 +274,7 @@ type procedure Clear; function AddMetaPackage(const AName: String): TMetaPackage; procedure DeletePackage(const AIndex: Integer); + function AddPackageFromJSON(JSON: TJSONStringType): Boolean; function FindMetaPackage(const AValue: String; const AFindPackageBy: TFindPackageBy): TMetaPackage; function FindPackageIndex(const AValue: String; const AFindPackageBy: TFindPackageBy): Integer; function FindLazarusPackage(const APackageName: String): TLazarusPackage; @@ -721,6 +722,49 @@ begin FMetaPackages.Delete(AIndex); end; +function TSerializablePackages.AddPackageFromJSON(JSON: TJSONStringType): Boolean; +var + Data: TJSONData; + Parser: TJSONParser; + I: Integer; + MetaPackage: TMetaPackage; +begin + if Trim(JSON) = '' then + Exit(False); + Result := True; + Parser := TJSONParser.Create(JSON); + try + Data := Parser.Parse; + try + MetaPackage := nil; + try + if Data.JSONType = jtObject then + begin + for I := 0 to Data.Count - 1 do + begin + if Data.Items[I].JSONType = jtObject then + begin + if not JSONToPackageData(Data.Items[I], MetaPackage) then + Result := False; + end + else if Data.Items[I].JSONType = jtArray then + begin + if not JSONToLazarusPackages(Data.Items[I], MetaPackage) then + Result := False; + end; + end; + end; + except + Result := False; + end; + finally + Data.Free; + end; + finally + Parser.Free; + end; +end; + function TSerializablePackages.FindMetaPackage(const AValue: String; const AFindPackageBy: TFindPackageBy): TMetaPackage; var