mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-07 09:38:05 +02:00
376 lines
10 KiB
ObjectPascal
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.
|
|
|