mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-06 11:18:10 +02:00
Opkman: Begin implementing support for multiple repositories.
git-svn-id: trunk@53956 -
This commit is contained in:
parent
96ce75a353
commit
91877feb80
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -3313,6 +3313,8 @@ components/onlinepackagemanager/opkman_packagelistfrm.lfm svneol=native#text/pla
|
||||
components/onlinepackagemanager/opkman_packagelistfrm.pas svneol=native#text/pascal
|
||||
components/onlinepackagemanager/opkman_progressfrm.lfm svneol=native#text/plain
|
||||
components/onlinepackagemanager/opkman_progressfrm.pas svneol=native#text/pascal
|
||||
components/onlinepackagemanager/opkman_repositories.lfm -text svneol=native#plain/text
|
||||
components/onlinepackagemanager/opkman_repositories.pas svneol=native#text/pascal
|
||||
components/onlinepackagemanager/opkman_serializablepackages.pas svneol=native#text/pascal
|
||||
components/onlinepackagemanager/opkman_timer.pas svneol=native#text/pascal
|
||||
components/onlinepackagemanager/opkman_updates.pas svneol=native#text/pascal
|
||||
|
@ -20,7 +20,7 @@
|
||||
<Description Value="Online package manger"/>
|
||||
<License Value="GPL"/>
|
||||
<Version Major="1"/>
|
||||
<Files Count="20">
|
||||
<Files Count="21">
|
||||
<Item1>
|
||||
<Filename Value="onlinepackagemanagerintf.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
@ -107,6 +107,10 @@
|
||||
<Filename Value="opkman_uploader.pas"/>
|
||||
<UnitName Value="opkman_uploader"/>
|
||||
</Item20>
|
||||
<Item21>
|
||||
<Filename Value="opkman_repositories.pas"/>
|
||||
<UnitName Value="opkman_repositories"/>
|
||||
</Item21>
|
||||
</Files>
|
||||
<i18n>
|
||||
<EnableI18N Value="True"/>
|
||||
|
@ -14,7 +14,7 @@ uses
|
||||
opkman_installer, opkman_packagelistfrm, opkman_options,
|
||||
opkman_createrepositorypackage, opkman_categoriesfrm,
|
||||
opkman_packagedetailsfrm, opkman_updates, opkman_createjsonforupdates,
|
||||
opkman_uploader, LazarusPackageIntf;
|
||||
opkman_uploader, opkman_repositories, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -33,6 +33,7 @@ uses
|
||||
|
||||
const
|
||||
cRemoteRepository = 'http://packages.lazarus-ide.org/';
|
||||
cRemoteRepositoryTitle = 'Lazarus Central Repository';
|
||||
cRemoteJSONFile = 'packagelist.json';
|
||||
cLocalRepository = 'onlinepackagemanager';
|
||||
cLocalRepositoryPackages = 'packages';
|
||||
@ -55,6 +56,7 @@ const
|
||||
cExtractDir = 'ExtractDir';
|
||||
cSubmitURL_Zip = 'aHR0cDovL2xhemFydXNvcG0uMDAwd2ViaG9zdGFwcC5jb20vemlwLnBocA==';
|
||||
cSubmitURL_JSON = 'aHR0cDovL2xhemFydXNvcG0uMDAwd2ViaG9zdGFwcC5jb20vanNvbi5waHA=';
|
||||
cSep = '#@$%^';
|
||||
|
||||
resourcestring
|
||||
//package manager
|
||||
@ -348,13 +350,25 @@ resourcestring
|
||||
rsCreateJSONForUpdatesFrm_Message4 = 'JSON for updates successfully created.';
|
||||
rsCreateJSONForUpdatesFrm_Error1 = 'Cannot create JSON for updates! Error message:';
|
||||
|
||||
|
||||
//categories form
|
||||
rsCategoriesFrm_Caption = 'List with categories';
|
||||
rsCategoriesFrm_lbMessage_Caption = 'Please select (check) one or more categories';
|
||||
rsCategoriesFrm_bYes_Caption = 'OK';
|
||||
rsCategoriesFrm_bCancel_Caption = 'Cancel';
|
||||
|
||||
//repositories
|
||||
rsRepositories_Caption = 'Repositories';
|
||||
rsRepositories_VST_HeaderColumn = 'Repository Address';
|
||||
rsRepositories_bAdd_Caption = 'Add';
|
||||
rsRepositories_bEdit_Caption = 'Edit';
|
||||
rsRepositories_bDelete_Caption = 'Delete';
|
||||
rsRepositories_bOk_Caption = 'OK';
|
||||
rsRepositories_bCancel_Caption = 'Cancel';
|
||||
rsRepositories_cbDefault_Caption = 'Set selected item as default repository';
|
||||
rsRepositories_Confirmation0 = 'Delete selected repository "%s" ?';
|
||||
rsRepositories_InputBox_Caption0 = 'Add repository';
|
||||
rsRepositories_InputBox_Caption1 = 'Edit repository';
|
||||
rsRepositories_InputBox_Text = 'Type the repository name:';
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -345,7 +345,7 @@ begin
|
||||
if SerializablePackages.Items[I].IsDownloadable then
|
||||
begin
|
||||
Inc(FCnt);
|
||||
FFrom := Options.RemoteRepository + SerializablePackages.Items[I].RepositoryFileName;
|
||||
FFrom := Options.RemoteRepository[Options.ActiveRepositoryIndex] + SerializablePackages.Items[I].RepositoryFileName;
|
||||
FTo := FDownloadTo + SerializablePackages.Items[I].RepositoryFileName;
|
||||
FCurSize := SerializablePackages.Items[I].RepositoryFileSize;
|
||||
DS := TDownloadStream.Create(TFileStream.Create(FTo, fmCreate));
|
||||
@ -499,7 +499,7 @@ end;
|
||||
|
||||
procedure TThreadDownload.DownloadJSON(const ATimeOut: Integer = -1);
|
||||
begin
|
||||
FRemoteJSONFile := Options.RemoteRepository + cRemoteJSONFile;
|
||||
FRemoteJSONFile := Options.RemoteRepository[Options.ActiveRepositoryIndex] + cRemoteJSONFile;
|
||||
FDownloadType := dtJSON;
|
||||
FTimer := TThreadTimer.Create;
|
||||
FTimer.Interval := ATimeOut;
|
||||
|
@ -151,7 +151,7 @@ begin
|
||||
VisualTree.OnChecked := @DoOnChecked;
|
||||
SerializablePackages := TSerializablePackages.Create;
|
||||
SerializablePackages.OnProcessJSON := @DoOnProcessJSON;
|
||||
PackageDownloader := TPackageDownloader.Create(Options.RemoteRepository);
|
||||
PackageDownloader := TPackageDownloader.Create(Options.RemoteRepository[Options.ActiveRepositoryIndex]);
|
||||
PackageDownloader.OnJSONProgress := @DoOnJSONProgress;
|
||||
PackageDownloader.OnJSONDownloadCompleted := @DoOnJSONDownloadCompleted;
|
||||
Updates := TUpdates.Create(LocalRepositoryUpdatesFile);
|
||||
@ -363,7 +363,7 @@ begin
|
||||
OptionsFrm.SetupControls(AActivePageIndex);
|
||||
if OptionsFrm.ShowModal = mrOk then
|
||||
begin
|
||||
tbRefresh.Enabled := Options.RemoteRepository <> '';
|
||||
tbRefresh.Enabled := Trim(Options.RemoteRepository[Options.ActiveRepositoryIndex]) <> '';
|
||||
GetPackageList;
|
||||
end;
|
||||
finally
|
||||
@ -384,7 +384,7 @@ begin
|
||||
VisualTree.VST.Enabled := (AEnable) and (SerializablePackages.Count > 0);
|
||||
if edFilter.CanFocus then
|
||||
edFilter.SetFocus;
|
||||
tbRefresh.Enabled := (AEnable) and (Trim(Options.RemoteRepository) <> '');
|
||||
tbRefresh.Enabled := (AEnable) and (Trim(Options.RemoteRepository[Options.ActiveRepositoryIndex]) <> '');
|
||||
tbDownload.Enabled := (AEnable) and (SerializablePackages.Count > 0) and (VisualTree.VST.CheckedCount > 0);
|
||||
tbInstall.Enabled := (AEnable) and (SerializablePackages.Count > 0) and (VisualTree.VST.CheckedCount > 0);
|
||||
tbUpdate.Enabled := (AEnable) and (SerializablePackages.Count > 0) and (VisualTree.VST.CheckedCount > 0);
|
||||
|
@ -47,7 +47,9 @@ type
|
||||
FProxySettings: TProxySettings;
|
||||
FXML: TXMLConfig;
|
||||
FVersion: Integer;
|
||||
FRemoteRepository: String;
|
||||
FRemoteRepository: TStringList;
|
||||
FRemoteRepositoryTmp: TStringList;
|
||||
FActiveRepositoryIndex: Integer;
|
||||
FForceDownloadAndExtract: Boolean;
|
||||
FDeleteZipAfterInstall: Boolean;
|
||||
FCheckForUpdates: Integer;
|
||||
@ -67,7 +69,6 @@ type
|
||||
FUserProfile: Integer;
|
||||
FExcludedFiles: String;
|
||||
FExcludedFolders: String;
|
||||
procedure SetRemoteRepository(const ARemoteRepository: String);
|
||||
public
|
||||
constructor Create(const AFileName: String);
|
||||
destructor Destroy; override;
|
||||
@ -77,7 +78,9 @@ type
|
||||
procedure CreateMissingPaths;
|
||||
published
|
||||
property Changed: Boolean read FChanged write FChanged;
|
||||
property RemoteRepository: string read FRemoteRepository write SetRemoteRepository;
|
||||
property RemoteRepository: TStringList read FRemoteRepository write FRemoteRepository;
|
||||
property RemoteRepositoryTmp: TStringList read FRemoteRepositoryTmp write FRemoteRepositoryTmp;
|
||||
property ActiveRepositoryIndex: Integer read FActiveRepositoryIndex write FActiveRepositoryIndex;
|
||||
property ForceDownloadAndExtract: Boolean read FForceDownloadAndExtract write FForceDownloadAndExtract;
|
||||
property DeleteZipAfterInstall: Boolean read FDeleteZipAfterInstall write FDeleteZipAfterInstall;
|
||||
property CheckForUpdates: Integer read FCheckForUpdates write FCheckForUpdates;
|
||||
@ -110,6 +113,8 @@ constructor TOptions.Create(const AFileName: String);
|
||||
var
|
||||
LocalRepo: String;
|
||||
begin
|
||||
FRemoteRepository := TStringList.Create;
|
||||
FRemoteRepositoryTmp := TStringList.Create;
|
||||
LocalRepo := AppendPathDelim(AppendPathDelim(LazarusIDE.GetPrimaryConfigPath) + cLocalRepository);
|
||||
FLocalPackagesDefault := LocalRepo + AppendPathDelim(cLocalRepositoryPackages);
|
||||
FLocalArchiveDefault := LocalRepo + AppendPathDelim(cLocalRepositoryArchive);
|
||||
@ -139,6 +144,8 @@ destructor TOptions.Destroy;
|
||||
begin
|
||||
if FChanged then
|
||||
Save;
|
||||
FRemoteRepository.Free;
|
||||
FRemoteRepositoryTmp.Free;
|
||||
FXML.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
@ -147,9 +154,10 @@ procedure TOptions.Load;
|
||||
begin
|
||||
FVersion := FXML.GetValue('Version/Value', 0);
|
||||
if FVersion = 0 then
|
||||
FRemoteRepository := FXML.GetValue('RemoteRepository/Value', '')
|
||||
FRemoteRepository.Text := FXML.GetValue('RemoteRepository/Value', '')
|
||||
else
|
||||
FRemoteRepository := FXML.GetValue('General/RemoteRepository/Value', '');
|
||||
FRemoteRepository.Text := FXML.GetValue('General/RemoteRepository/Value', '');
|
||||
FActiveRepositoryIndex := FXML.GetValue('General/ActiveRepositoryIndex/Value', 0);
|
||||
FForceDownloadAndExtract := FXML.GetValue('General/ForceDownloadAndExtract/Value', True);
|
||||
FDeleteZipAfterInstall := FXML.GetValue('General/DeleteZipAfterInstall/Value', True);
|
||||
FLastDownloadDir := FXML.GetValue('General/LastDownloadDir/Value', '');
|
||||
@ -176,7 +184,8 @@ end;
|
||||
procedure TOptions.Save;
|
||||
begin
|
||||
FXML.SetDeleteValue('Version/Value', OpkVersion, 0);
|
||||
FXML.SetDeleteValue('General/RemoteRepository/Value', FRemoteRepository, '');
|
||||
FXML.SetDeleteValue('General/RemoteRepository/Value', FRemoteRepository.Text, '');
|
||||
FXML.SetDeleteValue('General/ActiveRepositoryIndex/Value', FActiveRepositoryIndex, 0);
|
||||
FXML.SetDeleteValue('General/ForceDownloadAndExtract/Value', FForceDownloadAndExtract, True);
|
||||
FXML.SetDeleteValue('General/DeleteZipAfterInstall/Value', FDeleteZipAfterInstall, True);
|
||||
FXML.SetDeleteValue('General/LastDownloadDir/Value', FLastDownloadDir, '');
|
||||
@ -185,6 +194,7 @@ begin
|
||||
FXML.SetDeleteValue('General/CheckForUpdates/Value', FCheckForUpdates, 0);
|
||||
FXML.SetDeleteExtendedValue('General/LastUpdate/Value', FLastUpdate, 0.0);
|
||||
|
||||
|
||||
FXML.SetDeleteValue('Proxy/Enabled/Value', FProxySettings.FEnabled, false);
|
||||
FXML.SetDeleteValue('Proxy/Server/Value', FProxySettings.FServer, '');
|
||||
FXML.SetDeleteValue('Proxy/Port/Value', FProxySettings.FPort, 0);
|
||||
@ -205,7 +215,8 @@ end;
|
||||
|
||||
procedure TOptions.LoadDefault;
|
||||
begin
|
||||
FRemoteRepository := cRemoteRepository;
|
||||
FRemoteRepository.Add(cRemoteRepository);
|
||||
FActiveRepositoryIndex := 0;
|
||||
FForceDownloadAndExtract := True;
|
||||
FDeleteZipAfterInstall := True;
|
||||
FCheckForUpdates := 0;
|
||||
@ -237,15 +248,5 @@ begin
|
||||
CreateDirUTF8(FLocalRepositoryUpdate);
|
||||
end;
|
||||
|
||||
procedure TOptions.SetRemoteRepository(const ARemoteRepository: String);
|
||||
begin
|
||||
if FRemoteRepository <> ARemoteRepository then
|
||||
begin
|
||||
FRemoteRepository := Trim(ARemoteRepository);
|
||||
if FRemoteRepository[Length(FRemoteRepository)] <> '/' then
|
||||
FRemoteRepository := FRemoteRepository + '/';
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -86,16 +86,6 @@ object OptionsFrm: TOptionsFrm
|
||||
Caption = 'Remote repository:'
|
||||
ParentColor = False
|
||||
end
|
||||
object edRemoteRepository: TEdit
|
||||
Left = 15
|
||||
Height = 23
|
||||
Top = 32
|
||||
Width = 483
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
OnKeyPress = edRemoteRepositoryKeyPress
|
||||
TabOrder = 0
|
||||
Text = 'http://localhost/packages/'
|
||||
end
|
||||
object cbForceDownloadExtract: TCheckBox
|
||||
Left = 15
|
||||
Height = 19
|
||||
@ -104,7 +94,7 @@ object OptionsFrm: TOptionsFrm
|
||||
Caption = ' Force download and extract of packages'
|
||||
ParentShowHint = False
|
||||
ShowHint = True
|
||||
TabOrder = 1
|
||||
TabOrder = 0
|
||||
end
|
||||
object cbDeleteZipAfterInstall: TCheckBox
|
||||
Left = 15
|
||||
@ -114,7 +104,7 @@ object OptionsFrm: TOptionsFrm
|
||||
Caption = 'Delete downloaded zip files after installation/update'
|
||||
ParentShowHint = False
|
||||
ShowHint = True
|
||||
TabOrder = 2
|
||||
TabOrder = 1
|
||||
end
|
||||
object lbUpdates: TLabel
|
||||
Left = 15
|
||||
@ -140,7 +130,7 @@ object OptionsFrm: TOptionsFrm
|
||||
'Never'
|
||||
)
|
||||
Style = csDropDownList
|
||||
TabOrder = 3
|
||||
TabOrder = 2
|
||||
Text = 'Every few minutes'
|
||||
end
|
||||
object lbLastUpdate: TLabel
|
||||
@ -151,6 +141,26 @@ object OptionsFrm: TOptionsFrm
|
||||
Caption = 'Last update:'
|
||||
ParentColor = False
|
||||
end
|
||||
object bOpen: TButton
|
||||
Left = 476
|
||||
Height = 25
|
||||
Top = 31
|
||||
Width = 27
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = '...'
|
||||
OnClick = bOpenClick
|
||||
TabOrder = 3
|
||||
end
|
||||
object cbRemoteRepository: TComboBox
|
||||
Left = 16
|
||||
Height = 23
|
||||
Top = 32
|
||||
Width = 457
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
ItemHeight = 15
|
||||
Style = csDropDownList
|
||||
TabOrder = 4
|
||||
end
|
||||
end
|
||||
end
|
||||
object tsProxy: TTabSheet
|
||||
@ -595,6 +605,6 @@ object OptionsFrm: TOptionsFrm
|
||||
end
|
||||
object SDD: TSelectDirectoryDialog
|
||||
left = 448
|
||||
top = 32
|
||||
top = 112
|
||||
end
|
||||
end
|
||||
|
@ -47,18 +47,19 @@ type
|
||||
bOk: TButton;
|
||||
bRestore: TButton;
|
||||
bFilesAdd: TButton;
|
||||
bOpen: TButton;
|
||||
cbProxy: TCheckBox;
|
||||
cbForceDownloadExtract: TCheckBox;
|
||||
cbDeleteZipAfterInstall: TCheckBox;
|
||||
cbCheckForUpdates: TComboBox;
|
||||
cbSelectProfile: TComboBox;
|
||||
cbRemoteRepository: TComboBox;
|
||||
edLocalRepositoryUpdate: TDirectoryEdit;
|
||||
edLocalRepositoryPackages: TDirectoryEdit;
|
||||
edLocalRepositoryArchive: TDirectoryEdit;
|
||||
edProxyPassword: TEdit;
|
||||
edProxyServer: TEdit;
|
||||
edProxyUser: TEdit;
|
||||
edRemoteRepository: TEdit;
|
||||
gbProxySettings: TGroupBox;
|
||||
lbFilterFiles: TLabel;
|
||||
lbFilterDirs: TLabel;
|
||||
@ -99,6 +100,7 @@ type
|
||||
procedure bFilesDeleteClick(Sender: TObject);
|
||||
procedure bFilesEditClick(Sender: TObject);
|
||||
procedure bOkClick(Sender: TObject);
|
||||
procedure bOpenClick(Sender: TObject);
|
||||
procedure bRestoreClick(Sender: TObject);
|
||||
procedure cbProxyChange(Sender: TObject);
|
||||
procedure cbSelectProfileChange(Sender: TObject);
|
||||
@ -115,7 +117,7 @@ var
|
||||
OptionsFrm: TOptionsFrm;
|
||||
|
||||
implementation
|
||||
uses opkman_options, opkman_common, opkman_const;
|
||||
uses opkman_options, opkman_common, opkman_const, opkman_repositories;
|
||||
{$R *.lfm}
|
||||
|
||||
{ TOptionsFrm }
|
||||
@ -124,10 +126,10 @@ procedure TOptionsFrm.bOkClick(Sender: TObject);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
if Trim(edRemoteRepository.Text) = '' then
|
||||
if Trim(cbRemoteRepository.Text) = '' then
|
||||
begin
|
||||
MessageDlgEx(rsOptions_RemoteRepository_Information, mtInformation, [mbOk], Self);
|
||||
edRemoteRepository.SetFocus;
|
||||
cbRemoteRepository.SetFocus;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
@ -165,7 +167,9 @@ begin
|
||||
edLocalRepositoryUpdate.SetFocus;
|
||||
Exit;
|
||||
end;
|
||||
Options.RemoteRepository := edRemoteRepository.Text;
|
||||
if Options.RemoteRepositoryTmp.Count > 0 then
|
||||
Options.RemoteRepository.Text := Options.RemoteRepositoryTmp.Text;
|
||||
Options.ActiveRepositoryIndex := cbRemoteRepository.ItemIndex;
|
||||
Options.ForceDownloadAndExtract := cbForceDownloadExtract.Checked;
|
||||
Options.DeleteZipAfterInstall := cbDeleteZipAfterInstall.Checked;
|
||||
Options.CheckForUpdates := cbCheckForUpdates.ItemIndex;
|
||||
@ -200,6 +204,30 @@ begin
|
||||
ModalResult := mrOk;
|
||||
end;
|
||||
|
||||
procedure TOptionsFrm.bOpenClick(Sender: TObject);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
RepositoriesFrm := TRepositoriesFrm.Create(Self);
|
||||
try
|
||||
if RepositoriesFrm.ShowModal = mrOk then
|
||||
begin
|
||||
cbRemoteRepository.Clear;
|
||||
for I := 0 to Options.RemoteRepositoryTmp.Count - 1 do
|
||||
cbRemoteRepository.Items.Add(Options.RemoteRepositoryTmp.Strings[I]);
|
||||
if Options.ActiveRepositoryIndex <= cbRemoteRepository.Items.Count - 1 then
|
||||
cbRemoteRepository.ItemIndex := Options.ActiveRepositoryIndex
|
||||
else
|
||||
begin
|
||||
cbRemoteRepository.ItemIndex := 0;
|
||||
Options.ActiveRepositoryIndex := 0;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
RepositoriesFrm.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TOptionsFrm.GetSelectedText(AListBox: TListBox; var AIndex: Integer): String;
|
||||
var
|
||||
I: Integer;
|
||||
@ -338,13 +366,19 @@ begin
|
||||
end;
|
||||
|
||||
procedure TOptionsFrm.SetupControls(const AActivePageIndex: Integer = 0);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
Self.DoubleBuffered := True;
|
||||
Caption := rsOptions_FrmCaption;
|
||||
pgOptions.ActivePageIndex := AActivePageIndex;
|
||||
tsGeneral.Caption := rsOptions_tsGeneral_Caption;
|
||||
lbRemoteRepository.Caption := rsOptions_lbRemoteRepository_Caption;
|
||||
edRemoteRepository.Text := Options.RemoteRepository;
|
||||
Options.RemoteRepositoryTmp.Clear;
|
||||
for I := 0 to Options.RemoteRepository.Count - 1 do
|
||||
cbRemoteRepository.Items.Add(Options.RemoteRepository.Strings[I]);
|
||||
cbRemoteRepository.ItemIndex := Options.ActiveRepositoryIndex;
|
||||
|
||||
cbForceDownloadExtract.Checked := Options.ForceDownloadAndExtract;
|
||||
cbDeleteZipAfterInstall.Checked := Options.DeleteZipAfterInstall;
|
||||
cbForceDownloadExtract.Caption := rsOptions_cbForceDownloadExtract_Caption;
|
||||
|
129
components/onlinepackagemanager/opkman_repositories.lfm
Normal file
129
components/onlinepackagemanager/opkman_repositories.lfm
Normal file
@ -0,0 +1,129 @@
|
||||
object RepositoriesFrm: TRepositoriesFrm
|
||||
Left = 530
|
||||
Height = 367
|
||||
Top = 293
|
||||
Width = 561
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'RepositoriesFrm'
|
||||
ClientHeight = 367
|
||||
ClientWidth = 561
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
PopupMode = pmExplicit
|
||||
Position = poOwnerFormCenter
|
||||
LCLVersion = '1.7'
|
||||
object pnBottom: TPanel
|
||||
Left = 460
|
||||
Height = 332
|
||||
Top = 0
|
||||
Width = 101
|
||||
Align = alRight
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 332
|
||||
ClientWidth = 101
|
||||
TabOrder = 0
|
||||
object bAdd: TButton
|
||||
Left = 4
|
||||
Height = 25
|
||||
Top = 5
|
||||
Width = 88
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'Add'
|
||||
OnClick = bAddClick
|
||||
TabOrder = 0
|
||||
end
|
||||
object bEdit: TButton
|
||||
Tag = 1
|
||||
Left = 4
|
||||
Height = 25
|
||||
Top = 34
|
||||
Width = 88
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'Edit'
|
||||
OnClick = bAddClick
|
||||
TabOrder = 1
|
||||
end
|
||||
object bDelete: TButton
|
||||
Tag = 2
|
||||
Left = 4
|
||||
Height = 25
|
||||
Top = 63
|
||||
Width = 88
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'Delete'
|
||||
OnClick = bAddClick
|
||||
TabOrder = 2
|
||||
end
|
||||
end
|
||||
object pnBottom1: TPanel
|
||||
Left = 0
|
||||
Height = 35
|
||||
Top = 332
|
||||
Width = 561
|
||||
Align = alBottom
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 35
|
||||
ClientWidth = 561
|
||||
TabOrder = 1
|
||||
object bOk: TButton
|
||||
Left = 373
|
||||
Height = 25
|
||||
Top = 4
|
||||
Width = 88
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'OK'
|
||||
ModalResult = 1
|
||||
OnClick = bOkClick
|
||||
TabOrder = 0
|
||||
end
|
||||
object bCancel: TButton
|
||||
Left = 465
|
||||
Height = 25
|
||||
Top = 4
|
||||
Width = 88
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'Cancel'
|
||||
ModalResult = 2
|
||||
TabOrder = 1
|
||||
end
|
||||
end
|
||||
object imTree: TImageList
|
||||
left = 16
|
||||
top = 8
|
||||
Bitmap = {
|
||||
4C69010000001000000010000000A38D780095806C12B3A18B9FC5B49FFEC6B5
|
||||
A0FFC6B5A0FFC6B5A0FFC6B5A1FFBEAD98E3A5917C4BFFFFFF00988674000000
|
||||
0000000000000000000000000000FFEAD300AC9A886AD5C9BBF9E3D9CBFFE2D9
|
||||
CAFFE2D9CAFFE2D9CAFFE3D9CAFFE0D6C8FFC3B4A4CB84715C189B8874000000
|
||||
0000000000000000000000000000FFFFFF00AE9F8E87E5DBCEFFE7DDCFFFE8DE
|
||||
D2FFE8DED2FFE8DED2FFE8DED2FFE8DED0FFD1C5B7E67563502492806B000000
|
||||
0000000000000000000000000000FFFFFF00AC9C8B87DED2C2FFCBB69BFFC9B4
|
||||
99FFC9B499FFC9B499FFC8B398FFD6C5B0FFCEC1B3E673614E24907D69000000
|
||||
0000000000000000000000000000FFFFFF00AA9A8887DED3C4FFE0D3C4FFE1D5
|
||||
C6FFE1D5C6FFE1D5C6FFE1D5C6FFE1D5C5FFCBBEAFE672604E248E7C68000000
|
||||
0000000000000000000000000000FFFFFF00A8988687DACDBDFFCBB69CFFC9B4
|
||||
9AFFCAB49AFFCAB49AFFC9B499FFD4C4AEFFC9BCADE6715F4C248D7B67000000
|
||||
0000000000000000000000000000FFFFFF00A6958387D9CEBEFFDED2C2FFDFD3
|
||||
C4FFDFD3C4FFDFD3C4FFDFD3C4FFDED2C2FFC7B8A7E574614D238E7A65000000
|
||||
0000000000000000000000000000FFFFFF00A4938187D5C8B7FFCAB69BFFC9B4
|
||||
99FFC9B599FFC9B599FFC8B499FFC9BBA6FFC0B6A8F3B2AA9E92BCB6AB7FBAB4
|
||||
A87CB0AA9F489D968B09A39D9100FFFFFF00A2917E87D4C8B8FFDBD0C0FFDCD2
|
||||
C2FFDCD1C2FFDDD3C3FFCCC1B2FFCFC6BBFFDDD5CBFFDFD6CCFFDED5CBFFDCD4
|
||||
CAFFD1C9BEEFADA69B5FF1E8D900FFFFFF00A08F7C87D0C3B0FFCAB79CFFC9B5
|
||||
9AFFCAB69BFFCEB79CFFBEB09DFFDBD4CCFFE9E2D9FFEAE3DBFFEAE3DBFFE9E2
|
||||
D9FFDCD5CCFFA8A19686FFFFFF00FFFFFF009E8D7987CEC1AEFFCDBFA9FFCDBF
|
||||
A9FFC7BDA6FF95B08AFFB5AE9CFFC4BCB3FFDAD1C8FFE8DED7FFE8DED8FFDBD2
|
||||
CAFFC6BEB5FF9D968B84FFFFFF00FFFFFF009C8B7687CCC1ADFFD7CDBAFFD7CD
|
||||
BAFFD6CCB9FFC8CAB2FFC5BCACFFC7BFB6FFD1C9C0FFDCD2CAFFDCD3CBFFD2CA
|
||||
C2FFC8C1B8FC978F8570FFFFFF00FFFFFF009A887487CBBFABFFE0D7C6FFE1D8
|
||||
C8FFE1D8C8FFE4DBCAFFC3BAACFFCCC5BCFFE1DAD2FFEAE2DAFFEAE2DBFFE2DB
|
||||
D3FFCFC8BEFF9B918683FFFFFF00FFFFFF008C7B6773AD9E89ECB1A28EECB1A2
|
||||
8DECB1A28DECB1A28DEBA69A8AF2C3BAB1FED9D0C7FFE7DDD5FFE9DED7FFDAD1
|
||||
C9FFC4BCB3FF938A7E84FFFFFF00000000003830271A3F352A3C3D33283E3D33
|
||||
283E3D33283E3B30263D5951485B948C82BAB0A69CE7BAAFA6EABBB0A7EAB0A7
|
||||
9CE7958C82BB675F563EFFFFFF00000000000000000000000000000000000000
|
||||
000000000000000000000000000625221D2638322C4336312A4636312A463832
|
||||
2C4325211D26000000061F181300
|
||||
}
|
||||
end
|
||||
end
|
353
components/onlinepackagemanager/opkman_repositories.pas
Normal file
353
components/onlinepackagemanager/opkman_repositories.pas
Normal file
@ -0,0 +1,353 @@
|
||||
unit opkman_repositories;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
||||
StdCtrls, Menus, opkman_VirtualTrees;
|
||||
|
||||
type
|
||||
|
||||
{ TRepositoriesFrm }
|
||||
|
||||
TRepositoriesFrm = class(TForm)
|
||||
bEdit: TButton;
|
||||
bCancel: TButton;
|
||||
bDelete: TButton;
|
||||
bAdd: TButton;
|
||||
bOk: TButton;
|
||||
imTree: TImageList;
|
||||
pnBottom: TPanel;
|
||||
pnBottom1: TPanel;
|
||||
procedure bAddClick(Sender: TObject);
|
||||
procedure bOkClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
private
|
||||
FVST: TVirtualStringTree;
|
||||
FSortCol: Integer;
|
||||
FSortDir: opkman_VirtualTrees.TSortDirection;
|
||||
procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||
Column: TColumnIndex; {%H-}TextType: TVSTTextType; var CellText: String);
|
||||
procedure VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||
{%H-}Kind: TVTImageKind; Column: TColumnIndex; var {%H-}Ghosted: Boolean;
|
||||
var ImageIndex: Integer);
|
||||
procedure VSTCompareNodes(Sender: TBaseVirtualTree; Node1,
|
||||
Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
|
||||
procedure VSTFocuseChanged(Sender: TBaseVirtualTree; {%H-}Node: PVirtualNode; {%H-}Column: TColumnIndex);
|
||||
procedure VSTPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas;
|
||||
Node: PVirtualNode; {%H-}Column: TColumnIndex; {%H-}TextType: TVSTTextType);
|
||||
procedure VSTHeaderClick(Sender: TVTHeader; Column: TColumnIndex;
|
||||
Button: TMouseButton; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
|
||||
procedure VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
||||
procedure PopulateTree;
|
||||
procedure EnableDisableButtons;
|
||||
public
|
||||
end;
|
||||
|
||||
var
|
||||
RepositoriesFrm: TRepositoriesFrm;
|
||||
|
||||
implementation
|
||||
uses opkman_const, opkman_common, opkman_options, opkman_optionsfrm;
|
||||
{$R *.lfm}
|
||||
|
||||
type
|
||||
PData = ^TData;
|
||||
TData = record
|
||||
FAddress: string;
|
||||
FType: Integer;
|
||||
FImageIndex: Integer;
|
||||
end;
|
||||
|
||||
{ TRepositoriesFrm }
|
||||
|
||||
procedure TRepositoriesFrm.FormCreate(Sender: TObject);
|
||||
begin
|
||||
Caption := rsRepositories_Caption;
|
||||
bAdd.Caption := rsRepositories_bAdd_Caption;
|
||||
bEdit.Caption := rsRepositories_bEdit_Caption;
|
||||
bDelete.Caption := rsRepositories_bDelete_Caption;
|
||||
bOk.Caption := rsRepositories_bOk_Caption;
|
||||
bCancel.Caption := rsRepositories_bCancel_Caption;
|
||||
|
||||
FVST := TVirtualStringTree.Create(nil);
|
||||
with FVST do
|
||||
begin
|
||||
Parent := Self;
|
||||
Align := alClient;
|
||||
Anchors := [akLeft, akTop, akRight];
|
||||
Color := clBtnFace;
|
||||
DefaultNodeHeight := 22;
|
||||
Indent := 0;
|
||||
DefaultText := '';
|
||||
Colors.BorderColor := clBlack;
|
||||
BorderSpacing.Top := 5;
|
||||
BorderSpacing.Left := 5;
|
||||
BorderSpacing.Right := 0;
|
||||
BorderSpacing.Bottom := 0;
|
||||
Header.Height := 25;
|
||||
Header.Options := [hoAutoResize, hoVisible, hoColumnResize, hoRestrictDrag, hoShowSortGlyphs, hoAutoSpring];
|
||||
{$IFDEF LCLCarbon}
|
||||
Header.Options := Header.Options - [hoShowSortGlyphs];
|
||||
{$ENDIF}
|
||||
Header.AutoSizeIndex := 1;
|
||||
Header.Height := 25;
|
||||
with Header.Columns.Add do
|
||||
begin
|
||||
Position := 1;
|
||||
Width := 250;
|
||||
Text := rsRepositories_VST_HeaderColumn;
|
||||
end;
|
||||
Header.SortColumn := 0;
|
||||
TabOrder := 0;
|
||||
TreeOptions.MiscOptions := [toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning];
|
||||
TreeOptions.PaintOptions := [toHideFocusRect, toPopupMode, toShowButtons, toShowDropmark, toThemeAware, toUseBlendedImages];
|
||||
TreeOptions.SelectionOptions := [toFullRowSelect, toRightClickSelect];
|
||||
TreeOptions.AutoOptions := [toAutoTristateTracking];
|
||||
Images := imTree;
|
||||
OnGetText := @VSTGetText;
|
||||
OnGetImageIndex := @VSTGetImageIndex;
|
||||
OnCompareNodes := @VSTCompareNodes;
|
||||
OnFocusChanged := @VSTFocuseChanged;
|
||||
OnPaintText := @VSTPaintText;
|
||||
OnHeaderClick := @VSTHeaderClick;
|
||||
OnFreeNode := @VSTFreeNode;
|
||||
end;
|
||||
FVST.NodeDataSize := SizeOf(TData);
|
||||
PopulateTree;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.bAddClick(Sender: TObject);
|
||||
var
|
||||
PrevNode, Node: PVirtualNode;
|
||||
Data: PData;
|
||||
Value: String;
|
||||
begin
|
||||
case (Sender as TButton).Tag of
|
||||
0: begin
|
||||
Value := InputBox(rsRepositories_InputBox_Caption0, rsRepositories_InputBox_Text, '');
|
||||
if Value <> '' then
|
||||
begin
|
||||
Node := FVST.AddChild(nil);
|
||||
Data := FVST.GetNodeData(Node);
|
||||
Data^.FAddress := Trim(Value);
|
||||
Data^.FAddress := FixProtocol(Data^.FAddress);
|
||||
if Data^.FAddress[Length(Data^.FAddress)] <> '/' then
|
||||
Data^.FAddress := Data^.FAddress + '/';
|
||||
Data^.FType := 1;
|
||||
Data^.FImageIndex := 0;
|
||||
FVST.Selected[Node] := True;
|
||||
FVST.FocusedNode := Node;
|
||||
FVST.SortTree(0, FSortDir);
|
||||
end;
|
||||
end;
|
||||
1: begin
|
||||
Node := FVST.GetFirstSelected;
|
||||
if Node <> nil then
|
||||
begin
|
||||
Data := FVST.GetNodeData(Node);
|
||||
Value := InputBox(rsRepositories_InputBox_Caption1, rsRepositories_InputBox_Text, Data^.FAddress);
|
||||
if Value <> '' then
|
||||
begin
|
||||
Data^.FAddress := Trim(Value);
|
||||
Data^.FAddress := FixProtocol(Data^.FAddress);
|
||||
if Data^.FAddress[Length(Data^.FAddress)] <> '/' then
|
||||
Data^.FAddress := Data^.FAddress + '/';
|
||||
FVST.ReinitNode(Node, False);
|
||||
FVST.RepaintNode(Node);
|
||||
end;
|
||||
FVST.SortTree(0, FSortDir);
|
||||
end;
|
||||
end;
|
||||
2: begin
|
||||
Node := FVST.GetFirstSelected;
|
||||
if Node <> nil then
|
||||
begin
|
||||
Data := FVST.GetNodeData(Node);
|
||||
if MessageDlgEx(Format(rsRepositories_Confirmation0, [Data^.FAddress]), mtConfirmation, [mbYes, mbNo], Self) = mrYes then
|
||||
begin
|
||||
PrevNode := FVST.GetPrevious(Node);
|
||||
FVST.DeleteNode(Node);
|
||||
if PrevNode <> nil then
|
||||
begin
|
||||
FVST.Selected[PrevNode] := True;
|
||||
FVST.FocusedNode := PrevNode;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.bOkClick(Sender: TObject);
|
||||
var
|
||||
Node: PVirtualNode;
|
||||
Data: PData;
|
||||
begin
|
||||
Options.RemoteRepositoryTmp.Clear;
|
||||
FVST.BeginUpdate;
|
||||
FVST.SortTree(0, opkman_VirtualTrees.sdAscending);
|
||||
Node := FVST.GetFirst;
|
||||
while Assigned(Node) do
|
||||
begin
|
||||
Data := FVST.GetNodeData(Node);
|
||||
Options.RemoteRepositoryTmp.Add(Data^.FAddress);
|
||||
Node := FVST.GetNext(Node);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FVST.Clear;
|
||||
FVST.Free;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||
Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
|
||||
var
|
||||
Data: PData;
|
||||
begin
|
||||
Data := FVST.GetNodeData(Node);
|
||||
if Column = 0 then
|
||||
CellText := Data^.FAddress;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
|
||||
var ImageIndex: Integer);
|
||||
var
|
||||
Data: PData;
|
||||
begin
|
||||
if Column <> 0 then
|
||||
Exit;
|
||||
Data := FVST.GetNodeData(Node);
|
||||
ImageIndex := Data^.FImageIndex;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.VSTCompareNodes(Sender: TBaseVirtualTree; Node1,
|
||||
Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
|
||||
var
|
||||
Data1: PData;
|
||||
Data2: PData;
|
||||
begin
|
||||
Data1 := Sender.GetNodeData(Node1);
|
||||
Data2 := Sender.GetNodeData(Node2);
|
||||
case Column of
|
||||
0: if Data1^.FType > Data2^.FType then
|
||||
Result := 1
|
||||
else if Data1^.FType < Data2^.FType then
|
||||
Result := 0
|
||||
else if Data1^.FType = Data2^.FType then
|
||||
Result := CompareText(Data1^.FAddress, Data2^.FAddress);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.VSTFocuseChanged(Sender: TBaseVirtualTree;
|
||||
Node: PVirtualNode; Column: TColumnIndex);
|
||||
begin
|
||||
EnableDisableButtons;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.VSTPaintText(Sender: TBaseVirtualTree;
|
||||
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
|
||||
TextType: TVSTTextType);
|
||||
var
|
||||
Data: PData;
|
||||
begin
|
||||
Data := FVST.GetNodeData(Node);
|
||||
if Data^.FType = 0 then
|
||||
TargetCanvas.Font.Style := TargetCanvas.Font.Style + [fsBold]
|
||||
else
|
||||
TargetCanvas.Font.Style := TargetCanvas.Font.Style - [fsBold]
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.VSTHeaderClick(Sender: TVTHeader;
|
||||
Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
begin
|
||||
if (Column <> 0) and (Column <> 1) and (Column <> 3) then
|
||||
Exit;
|
||||
if Button = mbLeft then
|
||||
begin
|
||||
with Sender, Treeview do
|
||||
begin
|
||||
if (SortColumn = NoColumn) or (SortColumn <> Column) then
|
||||
begin
|
||||
SortColumn := Column;
|
||||
SortDirection := opkman_VirtualTrees.sdAscending;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if SortDirection = opkman_VirtualTrees.sdAscending then
|
||||
SortDirection := opkman_VirtualTrees.sdDescending
|
||||
else
|
||||
SortDirection := opkman_VirtualTrees.sdAscending;
|
||||
FSortDir := SortDirection;
|
||||
end;
|
||||
SortTree(SortColumn, SortDirection, False);
|
||||
FSortCol := Sender.SortColumn;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
||||
var
|
||||
Data: PData;
|
||||
begin
|
||||
Data := FVST.GetNodeData(Node);
|
||||
Finalize(Data^);
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.EnableDisableButtons;
|
||||
var
|
||||
SelNode: PVirtualNode;
|
||||
SelData: PData;
|
||||
begin
|
||||
bEdit.Enabled := False;
|
||||
bDelete.Enabled := False;
|
||||
if FVST.RootNodeCount = 0 then
|
||||
Exit;
|
||||
SelNode := FVST.GetFirstSelected;
|
||||
if SelNode = nil then
|
||||
Exit;
|
||||
SelData := FVST.GetNodeData(SelNode);
|
||||
bEdit.Enabled := SelData^.FType > 0;
|
||||
bDelete.Enabled := SelData^.FType > 0;
|
||||
end;
|
||||
|
||||
procedure TRepositoriesFrm.PopulateTree;
|
||||
var
|
||||
I: Integer;
|
||||
Node: PVirtualNode;
|
||||
Data: PData;
|
||||
begin
|
||||
if Trim(Options.RemoteRepositoryTmp.Text) = '' then
|
||||
Options.RemoteRepositoryTmp.Text := Options.RemoteRepository.Text;
|
||||
for I := 0 to Options.RemoteRepositoryTmp.Count - 1 do
|
||||
begin
|
||||
if Trim(Options.RemoteRepositoryTmp.Strings[I]) <> '' then
|
||||
begin
|
||||
Node := FVST.AddChild(nil);
|
||||
Data := FVST.GetNodeData(Node);
|
||||
Data^.FAddress := Options.RemoteRepositoryTmp.Strings[I];
|
||||
if I = 0 then
|
||||
Data^.FType := 0
|
||||
else
|
||||
Data^.FType := 1;
|
||||
Data^.FImageIndex := 0;
|
||||
end;
|
||||
end;
|
||||
FVST.SortTree(0, opkman_VirtualTrees.sdAscending);
|
||||
Node := FVST.GetFirst;
|
||||
if Node <> nil then
|
||||
begin
|
||||
FVST.Selected[Node] := True;
|
||||
FVST.FocusedNode := Node;
|
||||
end;
|
||||
EnableDisableButtons;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -306,7 +306,7 @@ begin
|
||||
//add repository(DataType = 0)
|
||||
RootNode := FVST.AddChild(nil);
|
||||
RootData := FVST.GetNodeData(RootNode);
|
||||
RootData^.Repository := Options.RemoteRepository;
|
||||
RootData^.Repository := Options.RemoteRepository[Options.ActiveRepositoryIndex];
|
||||
RootData^.DataType := 0;
|
||||
for I := 0 to SerializablePackages.Count - 1 do
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user