lazarus/ide/examplemanager.pas

376 lines
10 KiB
ObjectPascal

unit ExampleManager;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, lazutf8classes, ListFilterEdit, Forms, Controls, Dialogs,
StdCtrls, ExtCtrls, ButtonPanel, Buttons, EditBtn, LCLProc, FileUtil, LazFileUtils,
IDEWindowIntf, LazIDEIntf, MainIntf, EnvironmentOpts, LazarusIDEStrConsts;
type
{ TExampleManagerForm }
TExampleManagerForm = class(TForm)
BuildAllSelectedButton: TBitBtn;
cgIncludedDirs: TCheckGroup;
lblCenter: TLabel;
lbProjectCount: TLabel;
lbRootDirectory: TLabel;
SelectPanel: TPanel;
cbRelativePath: TCheckBox;
DescriptionMemo: TMemo;
Splitter1: TSplitter;
cbIncludeAllDirs: TCheckBox;
ProjectFilter: TListFilterEdit;
OpenSelectedButton: TBitBtn;
ProjectsListBox: TListBox;
SelectAllButton: TBitBtn;
ButtonPanel1: TButtonPanel;
edRootDirectory: TDirectoryEdit;
ActionGroupBox: TGroupBox;
SelectNoneButton: TBitBtn;
ProjectsGroupBox: TGroupBox;
procedure cbIncludeAllDirsClick(Sender: TObject);
procedure cgIncludedDirsItemClick(Sender: TObject; {%H-}Index: integer);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var {%H-}CloseAction: TCloseAction);
procedure BuildAllSelectedButtonClick(Sender: TObject);
procedure OpenSelectedButtonClick(Sender: TObject);
procedure ProjectFilterAfterFilter(Sender: TObject);
procedure ProjectsListBoxSelectionChange(Sender: TObject; {%H-}User: boolean);
procedure cbRelativePathClick(Sender: TObject);
procedure edRootDirectoryChange(Sender: TObject);
procedure SelectAllButtonClick(Sender: TObject);
procedure SelectNoneButtonClick(Sender: TObject);
private
fSelectedFilename: string;
fFirstSelectedIndex: Integer;
fChangingSelections: Boolean;
fIdleConnected: boolean;
procedure FillProjectsPending;
procedure SetIdleConnected(const AValue: boolean);
procedure OnIdle(Sender: TObject; var {%H-}Done: Boolean);
public
constructor Create(AnOwner: TComponent); override;
destructor Destroy; override;
property IdleConnected: boolean read fIdleConnected write SetIdleConnected;
end;
function ShowExampleManagerDlg: TModalResult;
implementation
{$R *.lfm}
const
DirectoryChoices: array[0..7] of string = (
'example', // 1st row
'sample',
'demo',
'test',
'examples', // 2nd row
'samples',
'demos',
'tests'
);
function ShowExampleManagerDlg: TModalResult;
var
theForm: TExampleManagerForm;
begin
Result:=mrCancel;
theForm:=TExampleManagerForm.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: TExampleManagerForm;
protected
procedure DoFileFound; override;
public
constructor Create(aForm: TExampleManagerForm);
end;
{ TListFileSearcher }
procedure TListFileSearcher.DoFileFound;
var
s: String;
begin
s:=FileName;
if fForm.cbRelativePath.Checked then
s:=CreateRelativePath(s, fForm.edRootDirectory.Text);
fForm.ProjectFilter.Items.Add(s);
end;
constructor TListFileSearcher.Create(aForm: TExampleManagerForm);
begin
inherited Create;
fForm:=aForm;
end;
{ TExampleManagerForm }
constructor TExampleManagerForm.Create(AnOwner: TComponent);
var
i: Integer;
begin
inherited Create(AnOwner);
fFirstSelectedIndex:=-1;
fChangingSelections:=False;
Caption:=lisKMExampleProjects;
lbRootDirectory.Caption:=lisRootDirectory;
cbIncludeAllDirs.Caption:=lisIncludeAllSubDirectories;
cgIncludedDirs.Caption:=lisIncludeSubDirectories;
// Add potential included directories to CheckGroup
cgIncludedDirs.Items.Clear;
for i := Low(DirectoryChoices) to High(DirectoryChoices) do
begin
cgIncludedDirs.Items.Add(DirectoryChoices[i]);
cgIncludedDirs.Checked[i]:=True;
end;
cbIncludeAllDirsClick(cbIncludeAllDirs);
lbProjectCount.Caption:='';
// Projects and their Actions
ProjectsGroupBox.Caption:=lisMEProjects;
ActionGroupBox.Caption:=lisMEAction;
cbRelativePath.Caption:=lisRelativePaths;
OpenSelectedButton.Caption:=lisExamplesOpenFirstSelected;
BuildAllSelectedButton.Caption:=lisExamplesBuildAllSelected;
SelectAllButton.Caption:=lisMenuSelectAll;
SelectNoneButton.Caption:=lisSAMSelectNone;
OpenSelectedButton.LoadGlyphFromResourceName(HInstance, 'laz_open');
BuildAllSelectedButton.LoadGlyphFromResourceName(HInstance, 'menu_build_all');
SelectAllButton.LoadGlyphFromResourceName(HInstance, 'menu_select_all');
SelectNoneButton.LoadGlyphFromResourceName(HInstance, 'ce_default');
edRootDirectory.Text:=EnvironmentOptions.GetParsedLazarusDirectory;
FillProjectsPending;
end;
destructor TExampleManagerForm.Destroy;
begin
inherited Destroy;
end;
procedure TExampleManagerForm.FormCreate(Sender: TObject);
begin
IDEDialogLayoutList.ApplyLayout(Self);
end;
procedure TExampleManagerForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
IDEDialogLayoutList.SaveLayout(Self);
end;
procedure TExampleManagerForm.FillProjectsPending;
begin
IdleConnected:=True;
end;
procedure TExampleManagerForm.SetIdleConnected(const AValue: boolean);
begin
if fIdleConnected=AValue then exit;
fIdleConnected:=AValue;
if fIdleConnected then
Application.AddOnIdleHandler(@OnIdle)
else
Application.RemoveOnIdleHandler(@OnIdle);
end;
procedure TExampleManagerForm.OnIdle(Sender: TObject; var Done: Boolean);
var
Searcher: TListFileSearcher;
AllDirs, IncludedDirs: TStringList;
i, j: Integer;
LastDir: String;
begin
Screen.Cursor:=crHourGlass;
Searcher:=TListFileSearcher.Create(Self);
IncludedDirs:=TStringList.Create;
AllDirs:=Nil;
try
if edRootDirectory.Text<>'' then
begin
if cbIncludeAllDirs.Checked then
// Add only the root directory name to list. Will find all projects in one go.
IncludedDirs.Add(edRootDirectory.Text)
else begin
// Collect each matching directory name to a list.
AllDirs:=FindAllDirectories(edRootDirectory.Text);
for i:=0 to AllDirs.Count-1 do
begin
LastDir:=ExtractFileName(AllDirs[i]);
for j:=Low(DirectoryChoices) to High(DirectoryChoices) do
begin
if cgIncludedDirs.Checked[j] and (LastDir=DirectoryChoices[j]) then
begin
IncludedDirs.Add(AllDirs[i]);
Break;
end;
end;
end;
end;
end;
ProjectFilter.Items.Clear;
// Find projects in all included directories.
for i:=0 to IncludedDirs.Count-1 do
Searcher.Search(IncludedDirs[i], '*.lpi');
ProjectFilter.InvalidateFilter;
DescriptionMemo.Clear;
IdleConnected:=false;
finally
AllDirs.Free;
IncludedDirs.Free;
Searcher.Free;
Screen.Cursor:=crDefault;
end;
end;
procedure TExampleManagerForm.edRootDirectoryChange(Sender: TObject);
begin
FillProjectsPending;
end;
procedure TExampleManagerForm.cbIncludeAllDirsClick(Sender: TObject);
begin
cgIncludedDirs.Enabled:=not (Sender as TCheckBox).Checked;
FillProjectsPending;
end;
procedure TExampleManagerForm.cgIncludedDirsItemClick(Sender: TObject; Index: integer);
begin
FillProjectsPending;
end;
procedure TExampleManagerForm.OpenSelectedButtonClick(Sender: TObject);
var
s: String;
begin
if fFirstSelectedIndex <> -1 then
begin
s:=ProjectsListBox.Items[fFirstSelectedIndex];
if cbRelativePath.Checked then
s:=CreateAbsolutePath(s, edRootDirectory.Text);
if FileExistsUTF8(s) then
begin
fSelectedFilename:=s;
ModalResult:=mrYes; // mrYes means the selected file will be opened.
end
else
ShowMessage(Format(lisFileNotFound2, [s]));
end;
end;
procedure TExampleManagerForm.ProjectFilterAfterFilter(Sender: TObject);
begin
lbProjectCount.Caption:=Format(lisProjectCount, [ProjectsListBox.Count]);
end;
procedure TExampleManagerForm.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 TExampleManagerForm.SelectAllButtonClick(Sender: TObject);
begin
fChangingSelections:=True;
ProjectsListBox.SelectAll;
fChangingSelections:=False;
ProjectsListBoxSelectionChange(ProjectsListBox, False); // In the end update buttons
end;
procedure TExampleManagerForm.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 TExampleManagerForm.cbRelativePathClick(Sender: TObject);
var
IsRelative: Boolean;
i: Integer;
s: String;
begin
IsRelative:=(Sender as TCheckBox).Checked;
for i:=0 to ProjectFilter.Items.Count-1 do
begin
s:=ProjectFilter.Items[i];
if IsRelative then
s:=CreateRelativePath(s, edRootDirectory.Text)
else
s:=CreateAbsolutePath(s, edRootDirectory.Text);
ProjectFilter.Items[i]:=s;
end;
ProjectFilter.InvalidateFilter;
end;
// Project list selection changes. Adjust buttons.
procedure TExampleManagerForm.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.