unit ManageExamples; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, lazutf8classes, ListFilterEdit, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, ButtonPanel, Buttons, EditBtn, LCLProc, IDEWindowIntf, LazIDEIntf, MainIntf, EnvironmentOpts, LazarusIDEStrConsts; type { TManageExamplesForm } TManageExamplesForm = class(TForm) BuildAllSelectedButton: TBitBtn; SelectPanel: TPanel; RelativeCheckBox: TCheckBox; DescriptionMemo: TMemo; Splitter1: TSplitter; TestCaseCheckBox: TCheckBox; ExamplesCheckBox: TCheckBox; DirectoryComboBox: TComboBox; ProjectFilter: TListFilterEdit; OpenSelectedButton: TBitBtn; Label1: TLabel; ProjectsListBox: TListBox; RootRadioGroup: TRadioGroup; SelectAllButton: TBitBtn; ButtonPanel1: TButtonPanel; RootDirectoryEdit: TDirectoryEdit; ActionGroupBox: TGroupBox; SelectNoneButton: TBitBtn; ProjectsGroupBox: TGroupBox; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure BuildAllSelectedButtonClick(Sender: TObject); procedure OpenSelectedButtonClick(Sender: TObject); procedure ProjectsListBoxSelectionChange(Sender: TObject; User: boolean); procedure RelativeCheckBoxClick(Sender: TObject); procedure RootRadioGroupClick(Sender: TObject); procedure DirectoryComboBoxChange(Sender: TObject); procedure RootDirectoryEditChange(Sender: TObject); procedure SelectAllButtonClick(Sender: TObject); procedure SelectNoneButtonClick(Sender: TObject); procedure ExamplesCheckBoxChange(Sender: TObject); private fSelectedFilename: string; fFirstSelectedIndex: Integer; fChangingSelections: Boolean; fNeedsFindDirectories: Boolean; fNeedsFindProjects: Boolean; fUpdating: Boolean; fIdleConnected: boolean; procedure FillDirectoriesPending; procedure FillProjectsPending; procedure SetIdleConnected(const AValue: boolean); procedure OnIdle(Sender: TObject; var Done: Boolean); public constructor Create(AnOwner: TComponent); override; destructor Destroy; override; property IdleConnected: boolean read fIdleConnected write SetIdleConnected; end; function ShowManageExamplesDlg: TModalResult; implementation {$R *.lfm} function ShowManageExamplesDlg: TModalResult; var theForm: TManageExamplesForm; begin Result:=mrCancel; theForm:=TManageExamplesForm.Create(Nil); try Result:=theForm.ShowModal; if Result=mrYes then MainIDEInterface.DoOpenProjectFile(theForm.fSelectedFilename, [ofOnlyIfExists,ofAddToRecent,ofUseCache]); finally theForm.Free; end; end; type { TListFileSearcher } TListFileSearcher = class(TFileSearcher) private fForm: TManageExamplesForm; protected procedure DoFileFound; override; public constructor Create(aForm: TManageExamplesForm); end; { TListFileSearcher } procedure TListFileSearcher.DoFileFound; begin fForm.ProjectFilter.Items.Add(FileName); end; constructor TListFileSearcher.Create(aForm: TManageExamplesForm); begin fForm := aForm; end; { TManageExamplesForm } constructor TManageExamplesForm.Create(AnOwner: TComponent); begin inherited Create(AnOwner); fFirstSelectedIndex:=-1; fChangingSelections:=False; fUpdating:=False; fNeedsFindDirectories:=False; fNeedsFindProjects:=False; Caption:=lisKMExampleProjects; ExamplesCheckBox.Caption:=lisIncludeExamples; TestCaseCheckBox.Caption:=lisIncludeTestcases; RootRadioGroup.Caption:=lisSearchProjectsFrom; RootRadioGroup.Items.Add(lisLazarusSource); RootRadioGroup.Items.Add(lisCEOtherGroup); RootRadioGroup.ItemIndex:=0; RootRadioGroupClick(RootRadioGroup); ProjectsGroupBox.Caption:=lisMEProjects; ActionGroupBox.Caption:=lisMEAction; RelativeCheckBox.Caption:=lisRelativePaths; OpenSelectedButton.Caption:=lisExamplesOpenFirstSelected; BuildAllSelectedButton.Caption:=lisExamplesBuildAllSelected; SelectAllButton.Caption:=lisMenuSelectAll; SelectNoneButton.Caption:=lisSAMSelectNone; OpenSelectedButton.LoadGlyphFromLazarusResource('laz_open'); BuildAllSelectedButton.LoadGlyphFromLazarusResource('menu_build_all'); SelectAllButton.LoadGlyphFromLazarusResource('menu_select_all'); SelectNoneButton.LoadGlyphFromLazarusResource('ce_default'); FillDirectoriesPending; FillProjectsPending; end; destructor TManageExamplesForm.Destroy; begin inherited Destroy; end; procedure TManageExamplesForm.FormCreate(Sender: TObject); begin IDEDialogLayoutList.ApplyLayout(Self); end; procedure TManageExamplesForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin IDEDialogLayoutList.SaveLayout(Self); end; procedure TManageExamplesForm.FillDirectoriesPending; begin fNeedsFindDirectories:=True; IdleConnected:=True; end; procedure TManageExamplesForm.FillProjectsPending; begin fNeedsFindProjects:=True; IdleConnected:=True; end; procedure TManageExamplesForm.SetIdleConnected(const AValue: boolean); begin if fIdleConnected=AValue then exit; fIdleConnected:=AValue; if fIdleConnected then Application.AddOnIdleHandler(@OnIdle) else Application.RemoveOnIdleHandler(@OnIdle); end; procedure TManageExamplesForm.OnIdle(Sender: TObject; var Done: Boolean); var Searcher: TListFileSearcher; AllDirs: TStringList; i: Integer; LastDir: String; begin IdleConnected:=false; if fUpdating then Exit; fUpdating:=True; if fNeedsFindDirectories then begin Screen.Cursor:=crHourGlass; Application.ProcessMessages; DirectoryComboBox.Items.Clear; DirectoryComboBox.Text:=''; RootDirectoryEdit.Text:=''; AllDirs:=FindAllDirectories(EnvironmentOptions.GetParsedLazarusDirectory); try for i:=0 to AllDirs.Count-1 do begin LastDir:=ExtractFileName(AllDirs[i]); if (ExamplesCheckBox.Checked and (LastDir='examples')) or (TestCaseCheckBox.Checked and (LastDir='tests')) then DirectoryComboBox.Items.Add(AllDirs[i]); end; // Add something to combobox to prevent crash with GTK2. if DirectoryComboBox.Items.Count = 0 then DirectoryComboBox.Items.Add('[empty]'); DirectoryComboBox.ItemIndex:=0; DirectoryComboBoxChange(DirectoryComboBox); finally AllDirs.Free; fNeedsFindDirectories:=False; Screen.Cursor:=crDefault; end; end; if fNeedsFindProjects and (RootDirectoryEdit.Text<>'') then try Screen.Cursor:=crHourGlass; Application.ProcessMessages; ProjectFilter.Items.Clear; Searcher:=TListFileSearcher.Create(Self); Searcher.Search(RootDirectoryEdit.Text, '*.lpi'); ProjectFilter.InvalidateFilter; DescriptionMemo.Clear; finally Searcher.Free; fNeedsFindProjects:=False; Screen.Cursor:=crDefault; end; fUpdating:=False; end; procedure TManageExamplesForm.RootRadioGroupClick(Sender: TObject); var LazSrc: Boolean; begin LazSrc:=RootRadioGroup.ItemIndex=0; ExamplesCheckBox.Enabled:=LazSrc; TestCaseCheckBox.Enabled:=LazSrc; DirectoryComboBox.Enabled:=LazSrc; RootDirectoryEdit.Enabled:=not LazSrc; end; procedure TManageExamplesForm.DirectoryComboBoxChange(Sender: TObject); begin if DirectoryExists(DirectoryComboBox.Text) then begin RootDirectoryEdit.Text:=DirectoryComboBox.Text; FillProjectsPending; end; end; procedure TManageExamplesForm.RootDirectoryEditChange(Sender: TObject); begin FillProjectsPending; end; procedure TManageExamplesForm.ExamplesCheckBoxChange(Sender: TObject); begin FillDirectoriesPending; end; procedure TManageExamplesForm.OpenSelectedButtonClick(Sender: TObject); begin if fFirstSelectedIndex <> -1 then begin if FileExistsUTF8(ProjectsListBox.Items[fFirstSelectedIndex]) then begin fSelectedFilename:=ProjectsListBox.Items[fFirstSelectedIndex]; ModalResult:=mrYes; // mrYes means the selected file will be opened. end else begin ShowMessage(Format(lisFileNotFound3, [ProjectsListBox.Items[fFirstSelectedIndex]])); end; end; end; procedure TManageExamplesForm.BuildAllSelectedButtonClick(Sender: TObject); var i: Integer; begin for i:=0 to ProjectsListBox.Items.Count-1 do begin if ProjectsListBox.Selected[i] then begin ; // ToDo end; end; end; procedure TManageExamplesForm.SelectAllButtonClick(Sender: TObject); begin fChangingSelections:=True; ProjectsListBox.SelectAll; fChangingSelections:=False; ProjectsListBoxSelectionChange(ProjectsListBox, False); // In the end update buttons end; procedure TManageExamplesForm.SelectNoneButtonClick(Sender: TObject); var i: Integer; begin fChangingSelections:=True; for i:=0 to ProjectsListBox.Items.Count-1 do ProjectsListBox.Selected[i]:=False; fChangingSelections:=False; ProjectsListBoxSelectionChange(ProjectsListBox, False); end; procedure TManageExamplesForm.RelativeCheckBoxClick(Sender: TObject); begin ; end; // Project list selection changes. Adjust buttons. procedure TManageExamplesForm.ProjectsListBoxSelectionChange(Sender: TObject; User: boolean); var HasSelected: Boolean; ReadMe, RealReadMe: String; i: Integer; begin if not fChangingSelections then begin HasSelected := ProjectsListBox.SelCount > 0; OpenSelectedButton.Enabled := HasSelected; // BuildAllSelectedButton.Enabled := HasSelected; SelectNoneButton.Enabled := HasSelected; // Find the first selected item and show README.txt contents. if HasSelected then for i:=0 to ProjectsListBox.Items.Count-1 do if ProjectsListBox.Selected[i] then begin fFirstSelectedIndex:=i; ReadMe:=ExtractFilePath(ProjectsListBox.Items[i])+'README.txt'; RealReadMe:=FindDiskFileCaseInsensitive(ReadMe); if RealReadMe <> '' then LoadStringsFromFileUTF8(DescriptionMemo.Lines,RealReadMe) else DescriptionMemo.Clear; Break; end else fFirstSelectedIndex:=-1; end; end; end.