{ *************************************************************************** * * * This source is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This code is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * A copy of the GNU General Public License is available on the World * * Wide Web at . You can also * * obtain it by writing to the Free Software Foundation, * * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * * * *************************************************************************** Author: Balázs Székely Abstract: Implementation of the main dialog. } unit opkman_mainfrm; {$mode objfpc}{$H+} interface uses Classes, SysUtils, fpjson, Graphics, laz.VirtualTrees, md5, // LCL Forms, Controls, Dialogs, StdCtrls, ExtCtrls, Buttons, Menus, ComCtrls, Clipbrd, InterfaceBase, LCLIntf, LCLVersion, LCLProc, LCLPlatformDef, // LazUtils LazFileUtils, LazIDEIntf, LazVersion, // IdeIntf IDECommands, PackageIntf, // OpkMan opkman_downloader, opkman_installer, opkman_updates, opkman_serializablepackages, opkman_visualtree, opkman_const, opkman_common, opkman_progressfrm, opkman_zipper, opkman_packagelistfrm, opkman_options, opkman_optionsfrm, opkman_createrepositorypackagefrm, opkman_maindm, opkman_createjsonforupdatesfrm, opkman_createrepositoryfrm; type { TMainFrm } TMainFrm = class(TForm) bReturn: TButton; cbFilterBy: TComboBox; cbPackageCategory: TComboBox; cbPackageState: TComboBox; cbPackageType: TComboBox; miSaveChecked: TMenuItem; miFromExteranlSource: TMenuItem; miFromRepository: TMenuItem; miSaveInstalled: TMenuItem; miSep2: TMenuItem; miSep3: TMenuItem; miSep1: TMenuItem; miCreateRepository: TMenuItem; miLoad: TMenuItem; miSave: TMenuItem; miDateDsc: TMenuItem; miDateAsc: TMenuItem; miNameDsc: TMenuItem; miNameAsc: TMenuItem; miByDate: TMenuItem; miByName: TMenuItem; miSaveToFile: TMenuItem; miJSONSort: TMenuItem; miResetRating: TMenuItem; miCopyToClpBrd: TMenuItem; miCreateJSONForUpdates: TMenuItem; miCreateRepositoryPackage: TMenuItem; OD: TOpenDialog; pnReturn: TPanel; pmInstall: TPopupMenu; SD: TSaveDialog; tbCleanUp1: TToolButton; tbInstall1: TToolButton; tbUninstall: TToolButton; tbOptions: TToolButton; cbAll: TCheckBox; edFilter: TEdit; lbFilterBy: TLabel; miJSONShow: TMenuItem; miJSONHide: TMenuItem; mJSON: TMemo; pmMemo: TPopupMenu; pnFilter: TPanel; pnMessage: TPanel; pnToolBar: TPanel; pnTop: TPanel; pnMain: TPanel; pmTree: TPopupMenu; pmCreate: TPopupMenu; SDD: TSelectDirectoryDialog; spCollapse: TSpeedButton; spClear: TSpeedButton; spExpand: TSpeedButton; tbButtons: TToolBar; imTBNor: TImageList; tbDownload: TToolButton; tbInstall: TToolButton; tbHelp: TToolButton; tbRefresh: TToolButton; tbCleanUp: TToolButton; tbCreate: TToolButton; tbUpdate: TToolButton; tbOpenRepo: TToolButton; tmWait: TTimer; procedure bReturnClick(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure miCopyToClpBrdClick(Sender: TObject); procedure miCreateJSONForUpdatesClick(Sender: TObject); procedure miCreateRepositoryClick(Sender: TObject); procedure miCreateRepositoryPackageClick(Sender: TObject); procedure miFromExteranlSourceClick(Sender: TObject); procedure miFromRepositoryClick(Sender: TObject); procedure miLoadClick(Sender: TObject); procedure miNameAscClick(Sender: TObject); procedure miResetRatingClick(Sender: TObject); procedure miSaveCheckedClick(Sender: TObject); procedure miSaveInstalledClick(Sender: TObject); procedure miSaveToFileClick(Sender: TObject); procedure pnReturnResize(Sender: TObject); procedure pnToolBarResize(Sender: TObject); procedure tbCleanUpClick(Sender: TObject); procedure tbCreateClick(Sender: TObject); procedure tbDownloadClick(Sender: TObject); procedure tbHelpClick(Sender: TObject); procedure tbInstallClick(Sender: TObject); procedure tbOpenRepoClick(Sender: TObject); procedure tbOptionsClick(Sender: TObject); procedure tbRefreshClick(Sender: TObject); procedure cbAllClick(Sender: TObject); procedure cbFilterByChange(Sender: TObject); procedure cbPackageCategoryChange(Sender: TObject); procedure cbPackageStateChange(Sender: TObject); procedure cbPackageTypeChange(Sender: TObject); procedure edFilterChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormKeyPress(Sender: TObject; var Key: char); procedure FormShow(Sender: TObject); procedure miJSONShowClick(Sender: TObject); procedure pnMainResize(Sender: TObject); procedure pnTopResize(Sender: TObject); procedure spClearClick(Sender: TObject); procedure spExpandClick(Sender: TObject); procedure tbUninstallClick(Sender: TObject); procedure tbUpdateClick(Sender: TObject); procedure tmWaitTimer(Sender: TObject); private FHintTimeOut: Integer; FFormIsHiden: Boolean; procedure EnableDisableControls(const AEnable: Boolean); procedure SetupMessage(const AMessage: String = ''); procedure SetupControls; procedure SetupColors; procedure GetPackageList(const ARepositoryHasChanged: Boolean = False); procedure DoOnChecking(Sender: TObject; const AIsAllChecked: Boolean); procedure DoOnChecked(Sender: TObject); procedure DoOnJSONProgress(Sender: TObject); procedure DoOnJSONDownloadCompleted(Sender: TObject; AJSON: TJSONStringType; AErrTyp: TErrorType; const AErrMsg: String = ''); procedure DoOnProcessJSON(Sender: TObject); procedure DoDeactivate(Sender: TObject); function IsSomethingChecked(const AResolveDependencies: Boolean = True): Boolean; function Download(const ADstDir: String; var ADoExtract: Boolean): TModalResult; function Extract(const ASrcDir, ADstDir: String; var ADoOpen: Boolean; const AIsUpdate: Boolean = False): TModalResult; function Install(var AInstallStatus: TInstallStatus; var ANeedToRebuild: Boolean): TModalResult; function UpdateP(const ADstDir: String; var ADoExtract: Boolean): TModalResult; procedure Rebuild; function CheckDstDir(const ADstDir: String): Boolean; protected procedure DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy; const AXProportion, AYProportion: Double); override; public procedure ShowOptions(const AActivePageIndex: Integer = 0); end; var MainFrm: TMainFrm; implementation {$R *.lfm} { TMainFrm } procedure TMainFrm.FormCreate(Sender: TObject); begin if MainDM = nil then MainDM := TMainDM.Create(self); VisualTree := TVisualTree.Create(pnMain, MainDM.Images, pmTree); VisualTree.OnChecking := @DoOnChecking; VisualTree.OnChecked := @DoOnChecked; SerializablePackages.OnProcessJSON := @DoOnProcessJSON; PackageDownloader.OnJSONProgress := @DoOnJSONProgress; PackageDownloader.OnJSONDownloadCompleted := @DoOnJSONDownloadCompleted; spExpand.Caption := ''; spExpand.Images := MainDM.Images; spExpand.ImageIndex := IMG_EXPAND; spCollapse.Caption := ''; spCollapse.Images := MainDM.Images; spCollapse.ImageIndex := IMG_COLLAPSE; spClear.Images := MainDM.Images; spClear.ImageIndex := IMG_CLEAR; tbButtons.DisabledImages := CreateDisabledImageList(imTBNor, self); FHintTimeOut := Application.HintHidePause; Updates := nil; CurLazVersion := IntToStr(laz_major) + '.' + IntToStr(laz_minor) + '.' + IntToStr(laz_release); CurFPCVersion := {$I %FPCVERSION%}; CurWidgetSet := LCLPlatformDisplayNames[GetDefaultLCLWidgetType]; Application.HintHidePause := 1000000; Application.AddOnDeactivateHandler(@DoDeactivate, False); end; procedure TMainFrm.FormDestroy(Sender: TObject); begin SerializablePackages.OnProcessJSON := nil; PackageDownloader.OnJSONProgress := nil; PackageDownloader.OnJSONDownloadCompleted := nil; Application.RemoveOnDeactivateHandler(@DoDeactivate); FreeAndNil(VisualTree); Application.HintHidePause := FHintTimeOut; end; procedure TMainFrm.FormKeyPress(Sender: TObject; var Key: char); begin if Key = #27 then Close; end; procedure TMainFrm.FormShow(Sender: TObject); begin if not FFormIsHiden then begin SetupControls; SetupColors; tmWait.Enabled := True; end end; procedure TMainFrm.tmWaitTimer(Sender: TObject); begin tmWait.Enabled := False; if (Options.CheckForUpdates <> 5) then begin Updates := TUpdates.Create; Updates.StartUpdate; end; GetPackageList; end; procedure TMainFrm.GetPackageList(const ARepositoryHasChanged: Boolean = False); var JSONFile: String; JSON: TJSONStringType; MS: TMemoryStream; SuccessfullyLoaded: Boolean; begin cbFilterBy.ItemIndex := 0; cbFilterByChange(cbFilterBy); Caption := rsLazarusPackageManager; EnableDisableControls(False); VisualTree.VST.Clear; VisualTree.VST.Invalidate; if ARepositoryHasChanged then begin SetupMessage(rsMainFrm_rsMessageChangingRepository); Sleep(1500); end; SuccessfullyLoaded := False; JSONFile := ExtractFilePath(LocalRepositoryConfigFile) + 'packagelist' + '_' + MD5Print(MD5String(Options.RemoteRepository[Options.ActiveRepositoryIndex])) + '.json'; if Options.LoadJsonLocally and (Options.LoadJsonLocallyCnt < 25) and FileExists(JSONFile) and (FileSizeUtf8(JSONFile) > 0) then begin MS := TMemoryStream.Create; try MS.LoadFromFile(JSONFile); MS.Position := 0; SetLength({%H-}JSON, MS.Size); MS.Read(Pointer(JSON)^, Length(JSON)); try SuccessfullyLoaded := SerializablePackages.JSONToPackages(JSON); except end; if SuccessfullyLoaded then begin DoOnJSONDownloadCompleted(Self, JSON, etNone); Options.LoadJsonLocallyCnt := Options.LoadJsonLocallyCnt + 1; end else Options.LoadJsonLocallyCnt := 25; Options.Changed := True; finally MS.Free; end; end; if not SuccessfullyLoaded then begin if Options.LoadJsonLocally then begin Options.LoadJsonLocallyCnt := 0; Options.Changed := True; end; SetupMessage(rsMainFrm_rsMessageDownload); PackageDownloader.DownloadJSON(Options.ConTimeOut*1000); end; end; function TMainFrm.IsSomethingChecked(const AResolveDependencies: Boolean = True): Boolean; begin Result := VisualTree.VST.CheckedCount > 0; if Result then begin if AResolveDependencies then if VisualTree.ResolveDependencies = mrCancel then begin Result := False; Exit; end; VisualTree.GetPackageList; VisualTree.UpdatePackageStates; end else MessageDlgEx(rsMainFrm_rsNoPackageToDownload, mtInformation, [mbOk], Self) end; function TMainFrm.CheckDstDir(const ADstDir: String): Boolean; begin Result := True; if not DirectoryExists(ADstDir) then begin if not ForceDirectories(ADstDir) then begin MessageDlgEx(Format(rsMainFrm_rsDestDirError, [ADstDir]), mtError, [mbOk], Self); Result := False; end; end; end; procedure TMainFrm.DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy; const AXProportion, AYProportion: Double); begin inherited; if AMode in [lapAutoAdjustWithoutHorizontalScrolling, lapAutoAdjustForDPI] then VisualTree.AutoAdjustLayout(AXProportion, AYProportion); end; function TMainFrm.Download(const ADstDir: String; var ADoExtract: Boolean): TModalResult; begin if not CheckDstDir(ADstDir) then begin Result := mrCancel; Exit; end; ADoExtract := False; ProgressFrm := TProgressFrm.Create(MainFrm); try ProgressFrm.SetupControls(0); PackageDownloader.OnPackageDownloadProgress := @ProgressFrm.DoOnPackageDownloadProgress; PackageDownloader.OnPackageDownloadError := @ProgressFrm.DoOnPackageDownloadError; PackageDownloader.OnPackageDownloadCompleted := @ProgressFrm.DoOnPackageDownloadCompleted; PackageDownloader.DownloadPackages(ADstDir); Result := ProgressFrm.ShowModal; if Result = mrOK then ADoExtract := ProgressFrm.cbExtractOpen.Checked; finally ProgressFrm.Free; end; end; function TMainFrm.Extract(const ASrcDir, ADstDir: String; var ADoOpen: Boolean; const AIsUpdate: Boolean = False): TModalResult; begin if not CheckDstDir(ADstDir) then begin Result := mrCancel; Exit; end; ProgressFrm := TProgressFrm.Create(MainFrm); try PackageUnzipper := TPackageUnzipper.Create; ProgressFrm.SetupControls(1); PackageUnzipper.OnZipProgress := @ProgressFrm.DoOnZipProgress; PackageUnzipper.OnZipError := @ProgressFrm.DoOnZipError; PackageUnzipper.OnZipCompleted := @ProgressFrm.DoOnZipCompleted; PackageUnzipper.StartUnZip(ASrcDir, ADstDir, AIsUpdate); Result := ProgressFrm.ShowModal; if Result = mrOk then ADoOpen := ProgressFrm.cbExtractOpen.Checked; finally ProgressFrm.Free; end; end; function TMainFrm.Install(var AInstallStatus: TInstallStatus; var ANeedToRebuild: Boolean): TModalResult; begin ProgressFrm := TProgressFrm.Create(MainFrm); try ProgressFrm.SetupControls(2); Result := ProgressFrm.ShowModal; if Result = mrOk then begin AInstallStatus := ProgressFrm.InstallStatus; ANeedToRebuild := ProgressFrm.NeedToRebuild; end; finally ProgressFrm.Free; end; end; function TMainFrm.UpdateP(const ADstDir: String; var ADoExtract: Boolean): TModalResult; begin if not CheckDstDir(ADstDir) then begin Result := mrCancel; Exit; end; ADoExtract := False; ProgressFrm := TProgressFrm.Create(MainFrm); try ProgressFrm.SetupControls(3); PackageDownloader.OnPackageDownloadProgress := @ProgressFrm.DoOnPackageDownloadProgress; PackageDownloader.OnPackageDownloadError := @ProgressFrm.DoOnPackageDownloadError; PackageDownloader.OnPackageDownloadCompleted := @ProgressFrm.DoOnPackageDownloadCompleted; PackageDownloader.OnPackageUpdateProgress := @ProgressFrm.DoOnPackageUpdateProgress; PackageDownloader.OnPackageUpdateCompleted := @ProgressFrm.DoOnPackageUpdateCompleted; PackageDownloader.UpdatePackages(ADstDir); Result := ProgressFrm.ShowModal; if Result = mrOK then ADoExtract := ProgressFrm.cbExtractOpen.Checked; finally ProgressFrm.Free; end; end; procedure TMainFrm.DoOnJSONDownloadCompleted(Sender: TObject; AJSON: TJSONStringType; AErrTyp: TErrorType; const AErrMsg: String = ''); begin case AErrTyp of etNone: begin if (not Options.LoadJsonLocally) then SetupMessage(rsMainFrm_rsMessageParsingJSON); if (SerializablePackages.Count = 0) then begin EnableDisableControls(True); SetupMessage(rsMainFrm_rsMessageNoPackage); MessageDlgEx(rsMainFrm_rsMessageError1 + sLineBreak + SerializablePackages.LastError, mtInformation, [mbOk], Self); Exit; end; VisualTree.PopulateTree; VisualTree.UpdatePackageUStatus; EnableDisableControls(True); SetupMessage; mJSON.Text := AJSON; cbAll.Checked := False; Caption := rsLazarusPackageManager + ' ' + SerializablePackages.QuickStatistics; end; etConfig: begin EnableDisableControls(True); SetupMessage(rsMainFrm_rsMessageNoPackage); Caption := rsLazarusPackageManager; if MessageDlgEx('"' + AErrMsg + '"', mtConfirmation, [mbYes, mbNo], Self) = mrYes then ShowOptions; end; etTimeOut, etHTTPClient: begin EnableDisableControls(True); SetupMessage(rsMainFrm_rsMessageNoPackage); Caption := rsLazarusPackageManager; MessageDlgEx(rsMainFrm_rsMessageError0 + sLineBreak + '"' + AErrMsg + '"', mtInformation, [mbOk], Self); end; end; end; procedure TMainFrm.DoOnJSONProgress(Sender: TObject); begin Application.ProcessMessages; end; procedure TMainFrm.DoOnProcessJSON(Sender: TObject); begin Application.ProcessMessages; end; procedure TMainFrm.DoDeactivate(Sender: TObject); begin if Assigned(VisualTree.ShowHintFrm) then if VisualTree.ShowHintFrm.Visible then VisualTree.ShowHintFrm.Hide; end; procedure TMainFrm.ShowOptions(const AActivePageIndex: Integer = 0); var OldIndex: Integer; DefaultTheme: Boolean; begin OptionsFrm := TOptionsFrm.Create(MainFrm); try OptionsFrm.SetupControls(AActivePageIndex); OldIndex := Options.ActiveRepositoryIndex; DefaultTheme := Options.UseDefaultTheme; if OptionsFrm.ShowModal = mrOk then begin tbRefresh.Enabled := Trim(Options.RemoteRepository[Options.ActiveRepositoryIndex]) <> ''; GetPackageList(OldIndex <> Options.ActiveRepositoryIndex); if DefaultTheme <> Options.UseDefaultTheme then SetupColors; end; finally OptionsFrm.Free; end; end; procedure TMainFrm.EnableDisableControls(const AEnable: Boolean); begin cbAll.Enabled := (AEnable) and (SerializablePackages.Count > 0); cbFilterBy.Enabled := (AEnable) and (SerializablePackages.Count > 0); pnFilter.Enabled := (AEnable) and (SerializablePackages.Count > 0); cbPackageState.Enabled := (AEnable) and (SerializablePackages.Count > 0); cbPackageType.Enabled := (AEnable) and (SerializablePackages.Count > 0); spExpand.Enabled := (AEnable) and (SerializablePackages.Count > 0); spCollapse.Enabled := (AEnable) and (SerializablePackages.Count > 0); VisualTree.VST.Enabled := (AEnable) and (SerializablePackages.Count > 0); if edFilter.CanFocus then edFilter.SetFocus; 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); tbUninstall.Enabled := (AEnable) and (SerializablePackages.Count > 0) and (VisualTree.VST.CheckedCount > 0); tbUpdate.Enabled := (AEnable) and (SerializablePackages.Count > 0) and (VisualTree.VST.CheckedCount > 0); tbOpenRepo.Enabled := (AEnable); tbCleanUp.Enabled := (AEnable) and (SerializablePackages.Count > 0); tbCreate.Visible := Options.UserProfile = 1; if tbCreate.Visible then begin tbCreate.Left := tbOptions.Left - 10; tbCreate.Enabled := (AEnable); end; pnToolBarResize(pnToolbar); tbOptions.Enabled := (AEnable); tbHelp.Enabled := (AEnable); end; procedure TMainFrm.SetupMessage(const AMessage: String = ''); begin if AMessage = '' then begin pnMessage.SendToBack; pnMessage.Visible := False; end else begin pnMessage.Caption := AMessage; pnMessage.Visible := True; pnMessage.BringToFront; Application.ProcessMessages; end; end; procedure TMainFrm.DoOnChecking(Sender: TObject; const AIsAllChecked: Boolean); begin cbAll.OnClick := nil; cbAll.Checked := AIsAllChecked; cbAll.OnClick := @cbAllClick; end; procedure TMainFrm.DoOnChecked(Sender: TObject); begin EnableDisableControls(True); end; procedure TMainFrm.cbAllClick(Sender: TObject); begin VisualTree.CheckNodes(cbAll.Checked); EnableDisableControls(True); end; procedure TMainFrm.cbFilterByChange(Sender: TObject); begin VisualTree.ResetFilter; case cbFilterBy.ItemIndex of 0..1, 4..9, 11..12: begin cbPackageType.Visible := False; cbPackageState.Visible := False; cbPackageCategory.Visible := False; pnFilter.Visible := True; edFilter.Text := ''; if edFilter.CanFocus then edFilter.SetFocus; end; 2: begin pnFilter.Visible := False; cbPackageType.Visible := False; cbPackageState.Visible := False; cbPackageCategory.Visible := True; cbPackageCategory.ItemIndex := 0; if cbPackageCategory.CanFocus then cbPackageCategory.SetFocus; end; 3: begin pnFilter.Visible := False; cbPackageType.Visible := False; cbPackageState.Visible := True; cbPackageCategory.Visible := False; cbPackageState.ItemIndex := 0; if cbPackageState.CanFocus then cbPackageState.SetFocus; end; 10: begin pnFilter.Visible := False; cbPackageState.Visible := False; cbPackageType.Visible := True; cbPackageCategory.Visible := False; cbPackageType.ItemIndex := 0; if cbPackageType.CanFocus then cbPackageType.SetFocus; end; end; cbPackageState.Height := cbFilterBy.Height; cbPackageState.Top := (pnTop.Height - cbPackageState.Height) div 2; cbPackageType.Height := cbFilterBy.Height; cbPackageType.Top := (pnTop.Height - cbPackageType.Height) div 2; cbPackageCategory.Height := cbFilterBy.Height; cbPackageCategory.Top := (pnTop.Height - cbPackageCategory.Height) div 2; end; procedure TMainFrm.cbPackageCategoryChange(Sender: TObject); begin if cbPackageCategory.ItemIndex > 0 then VisualTree.FilterTree(TFilterBy(cbFilterBy.ItemIndex), 'PackageCategory', cbPackageCategory.ItemIndex - 1) else VisualTree.ResetFilter; end; procedure TMainFrm.cbPackageTypeChange(Sender: TObject); begin if cbPackageType.ItemIndex > 0 then VisualTree.FilterTree(TFilterBy(cbFilterBy.ItemIndex), 'PackageType', cbPackageType.ItemIndex - 1) else VisualTree.ResetFilter; end; procedure TMainFrm.cbPackageStateChange(Sender: TObject); begin if cbPackageState.ItemIndex > 0 then VisualTree.FilterTree(TFilterBy(cbFilterBy.ItemIndex), 'PackageState', cbPackageState.ItemIndex - 1) else VisualTree.ResetFilter; end; procedure TMainFrm.edFilterChange(Sender: TObject); begin if edFilter.Text <> '' then VisualTree.FilterTree(TFilterBy(cbFilterBy.ItemIndex), edFilter.Text) else VisualTree.ResetFilter; end; procedure TMainFrm.pnTopResize(Sender: TObject); begin cbFilterBy.Left := (pnTop.Width - pnFilter.Width - cbFilterBy.Width + lbFilterBy.Width - 5) div 2; pnFilter.Left := cbFilterBy.Left + cbFilterBy.Width + 5; cbPackageType.Left := pnFilter.Left; cbPackageState.Left := pnFilter.Left; cbPackageCategory.Left := pnFilter.Left; lbFilterBy.Left := cbFilterBy.Left - 8 - lbFilterBy.Width; end; procedure TMainFrm.spClearClick(Sender: TObject); begin edFilter.OnChange := nil; edFilter.Text := ''; VisualTree.ResetFilter; edFilter.OnChange := @edFilterChange; end; procedure TMainFrm.spExpandClick(Sender: TObject); begin case TSpeedButton(Sender).Tag of 1: VisualTree.ExpandEx; 2: VisualTree.CollapseEx; end; end; procedure TMainFrm.tbOptionsClick(Sender: TObject); begin ShowOptions; end; procedure TMainFrm.tbHelpClick(Sender: TObject); begin OpenURL('https://wiki.freepascal.org/Online_Package_Manager'); end; procedure TMainFrm.tbRefreshClick(Sender: TObject); begin GetPackageList; end; procedure TMainFrm.tbDownloadClick(Sender: TObject); var DstDir: String; CanGo: Boolean; DoExtract: Boolean; DoOpen: Boolean; begin if not IsSomethingChecked(False) then Exit; SDD.InitialDir := Options.LastDownloadDir; if SDD.Execute then begin CanGo := True; DstDir := AppendPathDelim(SDD.FileName); VisualTree.UpdatePackageStates; PackageListFrm := TPackageListFrm.Create(MainFrm); try PackageListFrm.lbMessage.Caption := rsMainFrm_PackageAlreadyDownloaded; PackageListFrm.PopulateList(1, DstDir); if PackageListFrm.Count > 0 then CanGo := PackageListFrm.ShowModal = mrYes else CanGo := True; finally PackageListFrm.Free; end; end else CanGo := False; if CanGo then begin Options.LastDownloadDir := DstDir; Options.Changed := True; PackageAction := paDownloadTo; DoExtract := False; if Download(DstDir, DoExtract) = mrOK then begin if SerializablePackages.ExtractCount > 0 then begin if DoExtract then begin DoOpen := False; if Extract(DstDir, DstDir, DoOpen) = mrOk then begin if DoOpen then OpenDocument(DstDir); end; end; end; end; end; SerializablePackages.RemoveErrorState; end; procedure TMainFrm.Rebuild; begin FFormIsHiden := True; Self.Hide; IDECommands.ExecuteIDECommand(Self, ecBuildLazarus); Self.Show; FFormIsHiden := False; end; procedure TMainFrm.tbUpdateClick(Sender: TObject); var CanGo: Boolean; DoOpen: Boolean; DoExtract: Boolean; InstallStatus: TInstallStatus; NeedToRebuild: Boolean; begin if not IsSomethingChecked(True) then Exit; CanGo := True; if Options.IncompatiblePackages then begin PackageListFrm := TPackageListFrm.Create(MainFrm); try PackageListFrm.lbMessage.Caption := rsMainFrm_PackageIncompatible; PackageListFrm.PopulateList(3); if PackageListFrm.Count > 0 then CanGo := PackageListFrm.ShowModal = mrYes else CanGo := True; finally PackageListFrm.Free; end; end; if CanGo then begin NeedToRebuild := False; VisualTree.UpdatePackageStates; if Options.AlreadyInstalledPackages then begin PackageListFrm := TPackageListFrm.Create(MainFrm); try PackageListFrm.lbMessage.Caption := rsMainFrm_PackageUpdate0; PackageListFrm.PopulateList(2); if PackageListFrm.Count > 0 then CanGo := PackageListFrm.ShowModal = mrYes else CanGo := True; finally PackageListFrm.Free; end; end; if CanGo then begin if MessageDlgEx(rsMainFrm_PackageUpdateWarning, mtConfirmation, [mbYes, mbNo], Self) <> mrYes then Exit; PackageAction := paUpdate; VisualTree.UpdatePackageStates; if SerializablePackages.DownloadCount > 0 then begin DoExtract := True; CanGo := UpdateP(Options.LocalRepositoryUpdateExpanded, DoExtract) = mrOK; VisualTree.UpdatePackageStates; end; if CanGo then begin if SerializablePackages.ExtractCount > 0 then begin DoOpen := False; CanGo := Extract(Options.LocalRepositoryUpdateExpanded, Options.LocalRepositoryPackagesExpanded, DoOpen, True) = mrOk; VisualTree.UpdatePackageStates; end; if CanGo then begin if Options.DeleteZipAfterInstall then SerializablePackages.DeleteDownloadedZipFiles; if SerializablePackages.InstallCount > 0 then begin InstallStatus := isFailed; if Install(InstallStatus, NeedToRebuild) = mrOk then begin if (InstallStatus = isSuccess) or (InstallStatus = isPartiallyFailed) then begin SerializablePackages.MarkRuntimePackages; VisualTree.UpdatePackageStates; if NeedToRebuild then Rebuild; end; end; end; end; end; end; end; if not NeedToRebuild then SerializablePackages.RemoveErrorState; end; procedure TMainFrm.tbUninstallClick(Sender: TObject); function IsAtLeastOnePackageInstalled: Boolean; var I, J: Integer; LazarusPackage: TLazarusPackage; begin Result := False; for I := 0 to SerializablePackages.Count - 1 do begin for J := 0 to SerializablePackages.Items[I].LazarusPackages.Count - 1 do begin LazarusPackage := TLazarusPackage(SerializablePackages.Items[I].LazarusPackages.Items[J]); if (LazarusPackage.Checked) and (LazarusPackage.PackageState = psInstalled) then begin Result := True; Exit; end; end; end; end; function GetIDEPackage(const AFileName: String): TIDEPackage; var I: Integer; IDEPackge: TIDEPackage; begin Result := nil; for I := 0 to PackageEditingInterface.GetPackageCount - 1 do begin IDEPackge := PackageEditingInterface.GetPackages(I); if CompareText(IDEPackge.Filename, AFileName) = 0 then begin Result := IDEPackge; Break; end; end; end; var I, J: Integer; LazarusPackage: TLazarusPackage; IDEPackage: TIDEPackage; FileName: String; NeedToRebuild: Boolean; begin if not IsSomethingChecked(False) then Exit; if IsAtLeastOnePackageInstalled then begin if MessageDlgEx(Format(rsMainFrm_rsUninstall, [' ']), mtInformation, [mbYes, mbNo], Self) <> mrYes then Exit; end else begin MessageDlgEx(rsMainFrm_rsUninstall_Nothing, mtInformation, [mbOk], Self); Exit; end; NeedToRebuild := False; for I := 0 to SerializablePackages.Count - 1 do begin for J := 0 to SerializablePackages.Items[I].LazarusPackages.Count - 1 do begin LazarusPackage := TLazarusPackage(SerializablePackages.Items[I].LazarusPackages.Items[J]); if (LazarusPackage.Checked) and (LazarusPackage.PackageState = psInstalled) then begin case LazarusPackage.PackageType of lptRunTime, lptRunTimeOnly: begin FileName := StringReplace(LazarusPackage.Name, '.lpk', '.opkman', [rfIgnoreCase]); if FileExists(Options.LocalRepositoryPackagesExpanded + SerializablePackages.Items[I].PackageBaseDir + LazarusPackage.PackageRelativePath + FileName) then DeleteFile(Options.LocalRepositoryPackagesExpanded + SerializablePackages.Items[I].PackageBaseDir + LazarusPackage.PackageRelativePath + FileName); NeedToRebuild := True; end; lptDesignTime, lptRunAndDesignTime: begin IDEPackage := GetIDEPackage(LazarusPackage.InstalledFileName); if IDEPackage <> nil then begin if PackageEditingInterface.UninstallPackage(IDEPackage, False) <> mrOk then begin NeedToRebuild := False; MessageDlgEx(Format(rsMainFrm_rsUninstall_Error, [LazarusPackage.Name]), mtError, [mbOk], Self); Exit; end else NeedToRebuild := True; end; end; end; end; end; end; if NeedToRebuild then Rebuild; end; procedure TMainFrm.tbInstallClick(Sender: TObject); var CanGo: Boolean; DoExtract: Boolean; DoOpen: Boolean; InstallStatus: TInstallStatus; NeedToRebuild: Boolean; begin if not IsSomethingChecked then Exit; CanGo := True; if Options.IncompatiblePackages then begin PackageListFrm := TPackageListFrm.Create(MainFrm); try PackageListFrm.lbMessage.Caption := rsMainFrm_PackageIncompatible; PackageListFrm.PopulateList(3); if PackageListFrm.Count > 0 then CanGo := PackageListFrm.ShowModal = mrYes else CanGo := True; finally PackageListFrm.Free; end; end; if CanGo then begin if Options.AlreadyInstalledPackages then begin PackageListFrm := TPackageListFrm.Create(MainFrm); try PackageListFrm.lbMessage.Caption := rsMainFrm_PackageAlreadyInstalled; PackageListFrm.PopulateList(0); if PackageListFrm.Count > 0 then CanGo := PackageListFrm.ShowModal = mrYes else CanGo := True; finally PackageListFrm.Free; end; end; if CanGo then begin PackageAction := paInstall; VisualTree.UpdatePackageStates; if SerializablePackages.DownloadCount > 0 then begin DoExtract := True; CanGo := Download(Options.LocalRepositoryArchiveExpanded, DoExtract) = mrOK; VisualTree.UpdatePackageStates; end; if CanGo then begin if SerializablePackages.ExtractCount > 0 then begin DoOpen := False; CanGo := Extract(Options.LocalRepositoryArchiveExpanded, Options.LocalRepositoryPackagesExpanded, DoOpen) = mrOk; VisualTree.UpdatePackageStates; end; if CanGo then begin if Options.DeleteZipAfterInstall then SerializablePackages.DeleteDownloadedZipFiles; if SerializablePackages.InstallCount > 0 then begin InstallStatus := isFailed; NeedToRebuild := False; if Install(InstallStatus, NeedToRebuild) = mrOk then begin SerializablePackages.MarkRuntimePackages; VisualTree.UpdatePackageStates; if (InstallStatus = isSuccess) or (InstallStatus = isPartiallyFailed) then if NeedToRebuild then Rebuild; end; end; end; end; end; end; if not NeedToRebuild then SerializablePackages.RemoveErrorState; end; procedure TMainFrm.miFromRepositoryClick(Sender: TObject); begin tbInstallClick(tbInstall); end; procedure TMainFrm.miFromExteranlSourceClick(Sender: TObject); begin tbUpdateClick(tbUpdate); end; procedure TMainFrm.tbOpenRepoClick(Sender: TObject); begin OpenDocument(Options.LocalRepositoryPackagesExpanded); end; procedure TMainFrm.tbCleanUpClick(Sender: TObject); var Cnt: Integer; begin if MessageDlgEx(rsMainFrm_rsRepositoryCleanup0, mtInformation, [mbYes, mbNo], Self) = mrYes then begin Screen.BeginWaitCursor; try Cnt := SerializablePackages.Cleanup; finally Screen.EndWaitCursor; end; MessageDlgEx(Format(rsMainFrm_rsRepositoryCleanup1, [IntToStr(Cnt)]), mtInformation, [mbOk], Self); end; end; procedure TMainFrm.tbCreateClick(Sender: TObject); begin CreateRepositoryPackagesFrm := TCreateRepositoryPackagesFrm.Create(MainFrm); try CreateRepositoryPackagesFrm.SetType(0); CreateRepositoryPackagesFrm.ShowModal; finally CreateRepositoryPackagesFrm.Free; end; end; procedure TMainFrm.pnToolBarResize(Sender: TObject); var I: Integer; W: Integer; begin W := 0; for I := 0 to tbButtons.ButtonCount - 1 do if tbButtons.Buttons[I].Visible then W := W + tbButtons.Buttons[I].Width; tbButtons.Width := W + 2; if tbButtons.Width < 450 then tbButtons.Width := 450; tbButtons.Left := (pnToolBar.Width - tbButtons.Width) div 2; tbButtons.Height := tbButtons.Buttons[0].Height; tbButtons.Top := (pnToolBar.Height - tbButtons.Height) div 2; end; procedure TMainFrm.miCreateRepositoryPackageClick(Sender: TObject); begin tbCreateClick(tbCreate); end; procedure TMainFrm.miCreateJSONForUpdatesClick(Sender: TObject); var Msg: String; begin case VisualTree.GetCheckedRepositoryPackages of 0: Msg := rsCreateJSONForUpdatesFrm_Message0; 1: Msg := ''; 2: Msg := rsCreateJSONForUpdatesFrm_Message1; end; if Msg <> '' then begin MessageDlgEx(Msg, mtInformation, [mbOk], MainFrm); Exit; end; VisualTree.GetPackageList; CreateJSONForUpdatesFrm := TCreateJSONForUpdatesFrm.Create(MainFrm); try CreateJSONForUpdatesFrm.PopluateTree; CreateJSONForUpdatesFrm.ShowModal; finally CreateJSONForUpdatesFrm.Free; end; end; procedure TMainFrm.miCreateRepositoryClick(Sender: TObject); var CreateRepositoryFrm: TCreateRepositoryFrm; begin CreateRepositoryFrm := TCreateRepositoryFrm.Create(MainFrm); try CreateRepositoryFrm.ShowModal; finally CreateRepositoryFrm.Free; end; end; procedure TMainFrm.miCopyToClpBrdClick(Sender: TObject); var Data: PData; Node: PVirtualNode; begin Node := VisualTree.VST.GetFirstSelected; if Node <> nil then begin Data := VisualTree.VST.GetNodeData(Node); case Data^.DataType of 17: Clipboard.AsText := Data^.HomePageURL; 18: Clipboard.AsText := Data^.DownloadURL; end; end; end; procedure TMainFrm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if ssCtrl in Shift then begin if (Key = 82) and (tbRefresh.Enabled) then tbRefreshClick(tbRefresh) else if (Key = 68) and (tbDownload.Enabled) then tbDownloadClick(tbDownload) else if (Key = 73) and (tbInstall.Enabled) then tbInstallClick(tbInstall) else if (Key = 69) and (tbUpdate.Enabled) then tbUpdateClick(tbUpdate) else if (Key = 85) and (tbUninstall.Enabled) then tbUninstallClick(tbUninstall) else if (Key = 76) and (tbOpenRepo.Enabled) then tbOpenRepoClick(tbOpenRepo) else if (Key = 67) and (tbCleanUp.Enabled) then tbCleanUpClick(tbCleanUp) else if (Key = 80) and (tbInstall.Enabled) then miCreateRepositoryPackageClick(miCreateRepositoryPackage) else if (Key = 79) and (tbOptions.Enabled) then tbOptionsClick(tbOptions) else if (Key = 72) and (tbHelp.Enabled) then tbHelpClick(tbHelp); end; end; procedure TMainFrm.miResetRatingClick(Sender: TObject); var Data: PData; Node: PVirtualNode; MetaPkg: TMetaPackage; begin if MessageDlgEx(rsMainFrm_miResetRating + '?', mtConfirmation, [mbYes, mbNo], Self) <> mrYes then Exit; Node := VisualTree.VST.GetFirstSelected; if Node <> nil then begin Data := VisualTree.VST.GetNodeData(Node); if Data^.DataType = 1 then begin Data^.Rating := 0; MetaPkg := SerializablePackages.FindMetaPackage(Data^.PackageName, fpbPackageName); if MetaPkg <> nil then MetaPkg.Rating := 0; VisualTree.VST.ReinitNode(Node, False); VisualTree.VST.RepaintNode(Node); end; end; end; procedure TMainFrm.miSaveCheckedClick(Sender: TObject); var Node: PVirtualNode; Data: PData; SL: TStringList; begin SD.DefaultExt := '.*.opm'; SD.Filter := '*.opm|*.opm'; SL := TStringList.Create; try Node := VisualTree.VST.GetFirst; while Node <> nil do begin if VisualTree.VST.CheckState[Node] = csCheckedNormal then begin Data := VisualTree.VST.GetNodeData(Node); if (Data^.DataType = 2) then SL.Add(Data^.LazarusPackageName); end; Node := VisualTree.VST.GetNext(Node); end; if Trim(SL.Text) = '' then MessageDlgEx(rsMainFrm_rsMessageNothingChacked, mtInformation, [mbOk], Self) else if SD.Execute then begin SL.SaveToFile(SD.FileName); MessageDlgEx(Format(rsMainFrm_resMessageChecksSaved, [IntToStr(SL.Count)]), mtInformation, [mbOk], Self) end; finally SL.Free; end; end; procedure TMainFrm.miSaveInstalledClick(Sender: TObject); var Node: PVirtualNode; Data: PData; SL: TStringList; begin SD.DefaultExt := '.*.opm'; SD.Filter := '*.opm|*.opm'; SL := TStringList.Create; try Node := VisualTree.VST.GetFirst; while Node <> nil do begin Data := VisualTree.VST.GetNodeData(Node); if (Data^.DataType = 2) and (Data^.InstalledVersion <> '') then SL.Add(Data^.LazarusPackageName); Node := VisualTree.VST.GetNext(Node); end; if Trim(SL.Text) = '' then MessageDlgEx(rsMainFrm_rsMessageNothingInstalled, mtInformation, [mbOk], Self) else if SD.Execute then begin SL.SaveToFile(SD.FileName); MessageDlgEx(Format(rsMainFrm_resMessageChecksSaved, [IntToStr(SL.Count)]), mtInformation, [mbOk], Self) end; finally SL.Free; end; end; procedure TMainFrm.miLoadClick(Sender: TObject); var SL: TStringList; TrimmedS: String; I, CheckCount: Integer; Node: PVirtualNode; Data: PData; begin if OD.Execute then begin CheckCount := 0; SL := TStringList.Create; try SL.LoadFromFile(OD.FileName); for I := 0 to SL.Count - 1 do begin TrimmedS := Trim(SL.Strings[I]); Node := VisualTree.VST.GetFirst; while Node <> nil do begin Data := VisualTree.VST.GetNodeData(Node); if CompareText(Trim(Data^.LazarusPackageName), TrimmedS) = 0 then begin VisualTree.VST.CheckState[Node] := csCheckedNormal; Inc(CheckCount); Break; end; Node := VisualTree.VST.GetNext(Node); end; end; finally SL.Free; end; if CheckCount > 0 then MessageDlgEx(Format(rsMainFrm_resMessageChecksLoaded, [IntToStr(CheckCount)]), mtInformation, [mbOk], Self) end; end; procedure TMainFrm.pnMainResize(Sender: TObject); begin pnMessage.Left := (pnMain.Width - pnMessage.Width) div 2; pnMessage.Top := (pnMain.Height - pnMessage.Height) div 2; end; procedure TMainFrm.miJSONShowClick(Sender: TObject); begin if not mJSON.Visible then begin VisualTree.VST.Visible := False; pnTop.Visible := False; pnToolBar.Visible := False; pnReturn.Height := 50; pnReturn.Visible := True; mJSON.Visible := True; mJSON.BringToFront; end else begin mJSON.SendToBack; mJSON.Visible := False; pnReturn.Visible := False; pnTop.Visible := True; pnToolBar.Visible := True; VisualTree.VST.Visible := True; end; end; procedure TMainFrm.bReturnClick(Sender: TObject); begin miJSONShowClick(miJSONShow); end; procedure TMainFrm.FormCloseQuery(Sender: TObject; var CanClose: boolean); begin if Assigned(Updates) then begin Updates.StopUpdate; Updates.Terminate; while Assigned(Updates) do CheckSynchronize(100); // wait for update thread to terminate // Remains the slightest chance of a mem leak, since the update thread needs still enough cpu time to finish running the destructor end; end; procedure TMainFrm.miNameAscClick(Sender: TObject); var JSON: TJSONStringType; begin JSON := ''; case (Sender as TMenuItem).Tag of 0: SerializablePackages.Sort(stName, soAscendent); 1: SerializablePackages.Sort(stName, soDescendent); 2: SerializablePackages.Sort(stDate, soAscendent); 3: SerializablePackages.Sort(stDate, soDescendent); end; SerializablePackages.PackagesToJSON(JSON); mJSON.Lines.BeginUpdate; try mJSON.Clear; mJSON.Text := JSON; finally mJSON.Lines.EndUpdate; end; end; procedure TMainFrm.miSaveToFileClick(Sender: TObject); var JSON: TJSONStringType; Ms: TMemoryStream; begin SD.DefaultExt := '.*.json'; SD.Filter := '*.json|*.json'; if SD.Execute then begin JSON := ''; SerializablePackages.PackagesToJSON(JSON); Ms := TMemoryStream.Create; try Ms.Write(Pointer(JSON)^, Length(JSON)); Ms.Position := 0; Ms.SaveToFile(SD.FileName); finally Ms.Free; end; end; end; procedure TMainFrm.pnReturnResize(Sender: TObject); begin bReturn.Left := (pnReturn.Width - bReturn.Width) div 2 ; bReturn.Top := (pnReturn.Height - bReturn.Height) div 2; end; procedure TMainFrm.SetupControls; var I: Integer; begin Caption := rsLazarusPackageManager; cbFilterBy.Clear; cbFilterBy.Items.Add(rsMainFrm_VSTHeaderColumn_PackageName); cbFilterBy.Items.Add(rsMainFrm_VSTHeaderColumn_LazarusPackage); cbFilterBy.Items.Add(rsMainFrm_VSTText_PackageCategory); cbFilterBy.Items.Add(rsMainFrm_VSTText_PackageStatus); cbFilterBy.Items.Add(rsMainFrm_VSTText_Version); cbFilterBy.Items.Add(rsMainFrm_VSTText_Description); cbFilterBy.Items.Add(rsMainFrm_VSTText_Author); cbFilterBy.Items.Add(rsMainFrm_VSTText_LazCompatibility); cbFilterBy.Items.Add(rsMainFrm_VSTText_FPCCompatibility); cbFilterBy.Items.Add(rsMainFrm_VSTText_SupportedWidgetsets); cbFilterBy.Items.Add(rsMainFrm_VSTText_Packagetype); cbFilterBy.Items.Add(rsMainFrm_VSTText_Dependecies); cbFilterBy.Items.Add(rsMainFrm_VSTText_License); cbFilterBy.ItemIndex := 0; cbPackageType.Clear; cbPackageType.Items.Add(''); cbPackageType.Items.Add(rsMainFrm_VSTText_PackageType2); cbPackageType.Items.Add(rsMainFrm_VSTText_PackageType1); cbPackageType.Items.Add(rsMainFrm_VSTText_PackageType0); cbPackageType.Items.Add(rsMainFrm_VSTText_PackageType3); cbPackageState.Clear; cbPackageState.Items.Add(''); cbPackageState.Items.Add(rsMainFrm_VSTText_PackageState0); cbPackageState.Items.Add(rsMainFrm_VSTText_PackageState1); cbPackageState.Items.Add(rsMainFrm_VSTText_PackageState2); cbPackageState.Items.Add(rsMainFrm_VSTText_PackageState3); cbPackageCategory.Clear; cbPackageCategory.Items.Add(''); for I := 0 to MaxCategories - 1 do cbPackageCategory.Items.Add(Categories[I]); tbRefresh.Caption := rsMainFrm_TBRefresh_Caption; tbRefresh.Hint := rsMainFrm_TBRefresh_Hint; tbDownload.Caption := rsMainFrm_TBDownload_Caption; tbDownload.Hint := rsMainFrm_TBDownload_Hint; tbInstall.Caption := rsMainFrm_TBInstall_Caption; tbInstall.Hint := rsMainFrm_TBInstall_Hint; tbUpdate.Caption := rsMainFrm_TBUpdate_Caption; tbUpdate.Hint := rsMainFrm_TBUpdate_Hint; tbUninstall.Caption := rsMainFrm_TBUninstall_Caption; tbUninstall.Hint := rsMainFrm_TBUninstall_Hint; tbOpenRepo.Caption := rsMainFrm_TBOpenRepo_Caption; tbOpenRepo.Hint := rsMainFrm_TBOpenRepo_Hint; tbCleanUp.Caption := rsMainFrm_TBCleanUp_Caption; tbCleanUp.Hint := rsMainFrm_TBCleanUp_Hint; tbCreate.Caption := rsMainFrm_TBRepository_Caption; tbCreate.Hint := rsMainFrm_TBRepository_Hint; tbOptions.Caption := rsMainFrm_TBOptions_Caption; tbOptions.Hint := rsMainFrm_TBOptions_Hint; tbHelp.Caption := rsMainFrm_TBHelp_Caption; tbHelp.Hint := rsMainFrm_TBHelp_Hint; miFromRepository.Caption := rsMainFrm_VSTHeaderColumn_Repository; miFromRepository.Hint := rsMainFrm_VSTHeaderColumn_Repository_Hint; miFromExteranlSource.Caption := rsMainFrm_VSTHeaderColumn_Update; miFromExteranlSource.Hint := rsMainFrm_VSTHeaderColumn_Update_Hint; miCreateRepositoryPackage.Caption := rsMainFrm_miCreateRepositoryPackage; miCreateJSONForUpdates.Caption := rsMainFrm_miCreateJSONForUpdates; miCreateRepository.Caption := rsMainFrm_miCreateRepository; miJSONShow.Caption := rsMainFrm_miJSONShow; miJSONHide.Caption := rsMainFrm_miJSONHide; miJSONSort.Caption := rsMainFrm_miJSONSort; miByName.Caption := rsMainFrm_miByName; miNameAsc.Caption := rsMainFrm_miAscendent; miNameDsc.Caption := rsMainFrm_miDescendent; miByDate.Caption := rsMainFrm_miByDate; miDateAsc.Caption := rsMainFrm_miAscendent; miDateDsc.Caption := rsMainFrm_miDescendent; miSaveToFile.Caption := rsMainFrm_miSaveToFile; miCopyToClpBrd.Caption := rsMainFrm_miCopyToClpBrd; miResetRating.Caption := rsMainFrm_miResetRating; miSave.Caption := rsMainFrm_miSave; miSaveChecked.Caption := rsMainFrm_miSaveChecked; miSaveInstalled.Caption := rsMainFrm_miLoadInstalled; miLoad.Caption := rsMainFrm_miLoad; edFilter.Hint := rsMainFrm_edFilter_Hint; spClear.Hint := rsMainFrm_spClear_Hint; cbFilterBy.Top := (pnTop.Height - cbFilterBy.Height) div 2; pnFilter.Height := cbFilterBy.Height; pnFilter.Top := (pnTop.Height - pnFilter.Height) div 2; cbPackageState.Top := (pnTop.Height - cbPackageState.Height) div 2; cbPackageType.Top := (pnTop.Height - cbPackageType.Height) div 2; cbPackageCategory.Top := (pnTop.Height - cbPackageCategory.Height) div 2; cbAll.Top := (pnTop.Height - cbAll.Height) div 2; cbAll.Hint := rsMainFrm_cbAll_Hint; spExpand.Top:= (pnTop.Height - spExpand.Height + 1) div 2; spExpand.Hint := rsMainFrm_spExpand_Hint; spCollapse.Top:= (pnTop.Height - spCollapse.Height + 1) div 2; spCollapse.Hint := rsMainFrm_spCollapse_Hint; cbAll.Caption := rsMainFrm_cbAll_Caption; lbFilterBy.Top := cbFilterBy.Top + (cbFilterBy.Height - lbFilterBy.Height) div 2; lbFilterBy.Caption := rsMainFrm_lbFilter_Caption; cbFilterBy.Hint := rsMainFrm_cbFilterBy_Hint; bReturn.Caption := rsMainFrm_bReturn_Caption; cbPackageCategory.Visible := False; cbPackageType.Visible := False; cbPackageState.Visible := False; end; procedure TMainFrm.SetupColors; begin VisualTree.SetupColors; if not Options.UseDefaultTheme then begin Self.Color := clBtnFace; pnMain.Color := clBtnFace; pnMessage.Color := clBtnFace; pnTop.Color := clBtnFace; mJSON.Color := clBtnFace; end else begin pnMain.Color := VisualTree.VST.GetDefaultColor(dctBrush); pnMessage.Color := VisualTree.VST.GetDefaultColor(dctBrush); end; end; end.