mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-30 13:03:45 +02:00
311 lines
8.3 KiB
ObjectPascal
311 lines
8.3 KiB
ObjectPascal
unit lazdialogs;
|
|
|
|
{$mode delphi}
|
|
|
|
interface
|
|
|
|
uses
|
|
// RTL
|
|
Classes, SysUtils,
|
|
// LCL
|
|
Forms, ShellCtrls, Buttons, StdCtrls, ExtCtrls, FileCtrl, ComCtrls,
|
|
Dialogs, ButtonPanel, lclstrconsts, FileUtil, Controls;
|
|
|
|
type
|
|
TLazFileDialogKind = (
|
|
ldkOpenDesktop, ldkSaveDesktop, ldkOpenPDA, ldkSavePDA, ldkSelectDirectory);
|
|
|
|
{ TLazarusFileDialogForm }
|
|
|
|
TLazarusFileDialogForm = class(TForm)
|
|
private
|
|
FKind: TLazFileDialogKind;
|
|
procedure SetFilter(AFilter: string);
|
|
public
|
|
// User interface
|
|
ButtonPanel: TButtonPanel;
|
|
ShellTreeView: TShellTreeView;
|
|
ShellListView: TShellListView;
|
|
SaveEdit: TEdit;
|
|
FilterComboBox: TFilterComboBox;
|
|
// input/output
|
|
FileName: string;
|
|
Filter: string;
|
|
InitialDir: string;
|
|
Title: string;
|
|
//
|
|
constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
|
|
procedure Initialize(AKind: TLazFileDialogKind);
|
|
procedure HandleOkClick(ASender: TObject);
|
|
procedure HandleCancelClick(ASender: TObject);
|
|
procedure HandleCloseQuery(Sender : TObject; var CanClose : boolean);
|
|
procedure HandleEditChange(ASender: TObject);
|
|
procedure HandleSelectItem(Sender: TObject;
|
|
Item: TListItem; Selected: Boolean);
|
|
procedure HandleTreeViewSelectionChanged(ASender: TObject);
|
|
end;
|
|
|
|
{ TLazOpenDialog }
|
|
|
|
TLazOpenDialog = class(TOpenDialog)
|
|
protected
|
|
FForm: TLazarusFileDialogForm;
|
|
class procedure WSRegisterClass; override;
|
|
function DoExecute: boolean; override;
|
|
procedure DoInitialize; virtual;
|
|
public
|
|
constructor Create(TheOwner: TComponent); override;
|
|
end;
|
|
|
|
{ TLazSaveDialog }
|
|
|
|
TLazSaveDialog = class(TLazOpenDialog)
|
|
protected
|
|
procedure DoInitialize; override;
|
|
end;
|
|
|
|
{ TLazSelectDirectoryDialog }
|
|
|
|
TLazSelectDirectoryDialog = class(TLazOpenDialog)
|
|
protected
|
|
procedure DoInitialize; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TLazarusFileDialogForm }
|
|
|
|
procedure TLazarusFileDialogForm.SetFilter(AFilter: string);
|
|
begin
|
|
if AFilter = '' then
|
|
FilterComboBox.Filter := Format(rsAllFiles,[GetAllFilesMask, GetAllFilesMask,''])
|
|
else
|
|
FilterComboBox.Filter := AFilter;
|
|
end;
|
|
|
|
{
|
|
The size of the window is determined only when creating the
|
|
handle, so any reference to TForm.Width and TForm.Height
|
|
here doesnt correspond to the final value.
|
|
}
|
|
constructor TLazarusFileDialogForm.CreateNew(AOwner: TComponent; Num: Integer = 0);
|
|
begin
|
|
inherited CreateNew(AOwner, Num);
|
|
|
|
Self.Position := poScreenCenter;
|
|
end;
|
|
|
|
procedure TLazarusFileDialogForm.Initialize(AKind: TLazFileDialogKind);
|
|
begin
|
|
FKind := AKind;
|
|
|
|
ButtonPanel := TButtonPanel.Create(Self);
|
|
ButtonPanel.Parent := Self;
|
|
ButtonPanel.Left := 0;
|
|
ButtonPanel.Height := 20;
|
|
ButtonPanel.Top := Height - ButtonPanel.Height;
|
|
ButtonPanel.Width := Width;
|
|
ButtonPanel.Align := alBottom;
|
|
ButtonPanel.ShowButtons := [pbOK, pbCancel];
|
|
ButtonPanel.OKButton.OnClick := HandleOkClick;
|
|
ButtonPanel.CancelButton.OnClick := HandleCancelClick;
|
|
|
|
if AKind in [ldkOpenDesktop, ldkSaveDesktop, ldkOpenPDA, ldkSavePDA] then
|
|
begin
|
|
// Add the ShellTreeView to the dialog
|
|
ShellTreeView := TShellTreeView.Create(Self);
|
|
ShellTreeView.Parent := Self;
|
|
ShellTreeView.Left := 0;
|
|
ShellTreeView.Top := 0;
|
|
ShellTreeView.Width := Width;
|
|
ShellTreeView.Height := 100;
|
|
ShellTreeView.Align := alTop;
|
|
|
|
// Add the ShellListView to the dialog
|
|
ShellListView := TShellListView.Create(Self);
|
|
ShellListView.Parent := Self;
|
|
ShellListView.Left := 0;
|
|
ShellListView.Top := ShellTreeView.Height;
|
|
ShellListView.Width := Width;
|
|
ShellListView.Height := Height - ShellTreeView.Height - ButtonPanel.Height;
|
|
ShellListView.Align := alClient;
|
|
ShellListView.ShellTreeView := ShellTreeView;
|
|
ShellListView.ScrollBars := ssVertical;
|
|
ShellListView.OnSelectItem := HandleSelectItem;
|
|
|
|
// TEdit for save dialog
|
|
if AKind in [ldkSaveDesktop, ldkSavePDA] then
|
|
begin
|
|
SaveEdit := TEdit.Create(Self);
|
|
SaveEdit.Parent := Self;
|
|
SaveEdit.Left := 0;
|
|
SaveEdit.Height := 20;
|
|
SaveEdit.Top := Height - ButtonPanel.Height - SaveEdit.Height;
|
|
SaveEdit.Width := Width;
|
|
SaveEdit.Align := alBottom;
|
|
SaveEdit.Text := SysUtils.ExtractFileName(FileName);
|
|
SaveEdit.OnChange := HandleEditChange;
|
|
end;
|
|
|
|
// TFilterComboBox
|
|
FilterComboBox := TFilterComboBox.Create(Self);
|
|
FilterComboBox.Parent := Self;
|
|
FilterComboBox.Left := 0;
|
|
FilterComboBox.Height := 20;
|
|
FilterComboBox.Top := Height - ButtonPanel.Height - FilterComboBox.Height;
|
|
if SaveEdit <> nil then
|
|
FilterComboBox.Top := FilterComboBox.Top - SaveEdit.Height;
|
|
FilterComboBox.Width := Width;
|
|
FilterComboBox.Align := alBottom;
|
|
SetFilter(Filter);
|
|
FilterComboBox.ShellListView := ShellListView;
|
|
|
|
// In the save dialog it is enabled when there is a text in the TEdit
|
|
if AKind in [ldkSaveDesktop, ldkSavePDA] then
|
|
ButtonPanel.OKButton.Enabled := SaveEdit.Text <> ''
|
|
// In a TOpenDialog the Ok button is only enabled when a file is selected
|
|
else
|
|
ButtonPanel.OkButton.Enabled := False;
|
|
end
|
|
else if FKind = ldkSelectDirectory then
|
|
begin
|
|
// Add the ShellTreeView to the dialog
|
|
ShellTreeView := TShellTreeView.Create(Self);
|
|
ShellTreeView.Parent := Self;
|
|
ShellTreeView.Left := 0;
|
|
ShellTreeView.Top := 0;
|
|
ShellTreeView.Align := alClient;
|
|
ShellTreeView.OnSelectionChanged := HandleTreeViewSelectionChanged;
|
|
|
|
ButtonPanel.OKButton.Enabled := False;
|
|
end;
|
|
|
|
// Form events
|
|
OnCloseQuery := HandleCloseQuery;
|
|
end;
|
|
|
|
// The Ok button code should be only a simple mrOk,
|
|
// because there is the dialog Ok button, which will
|
|
// always be active and will set the ModalResult to mrOk
|
|
// so the code needs to affect it too, and this can be
|
|
// done in CloseQuery
|
|
procedure TLazarusFileDialogForm.HandleOkClick(ASender: TObject);
|
|
begin
|
|
ModalResult := mrOk;
|
|
end;
|
|
|
|
procedure TLazarusFileDialogForm.HandleCancelClick(ASender: TObject);
|
|
begin
|
|
ModalResult := mrCancel;
|
|
end;
|
|
|
|
procedure TLazarusFileDialogForm.HandleCloseQuery(Sender: TObject;
|
|
var CanClose: boolean);
|
|
begin
|
|
if ModalResult = mrCancel then
|
|
begin
|
|
CanClose := True;
|
|
Exit;
|
|
end;
|
|
|
|
CanClose := False;
|
|
|
|
if FKind in [ldkSaveDesktop, ldkSavePDA] then
|
|
begin
|
|
if SaveEdit.Text = '' then Exit;
|
|
|
|
FileName := ShellTreeView.GetPathFromNode(ShellTreeView.Selected);
|
|
FileName := IncludeTrailingPathDelimiter(FileName);
|
|
FileName := FileName + SaveEdit.Text;
|
|
CanClose := True;
|
|
end
|
|
else if FKind in [ldkOpenDesktop, ldkOpenPDA] then
|
|
begin
|
|
if ShellListView.Selected = nil then Exit;
|
|
|
|
FileName := ShellListView.GetPathFromItem(ShellListView.Selected);
|
|
CanClose := True;
|
|
end
|
|
else
|
|
begin
|
|
if ShellTreeView.Selected = nil then Exit;
|
|
|
|
FileName := ShellTreeView.GetPathFromNode(ShellTreeView.Selected);
|
|
CanClose := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TLazarusFileDialogForm.HandleEditChange(ASender: TObject);
|
|
begin
|
|
ButtonPanel.OkButton.Enabled := SaveEdit.Text <> '';
|
|
end;
|
|
|
|
procedure TLazarusFileDialogForm.HandleSelectItem(Sender: TObject;
|
|
Item: TListItem; Selected: Boolean);
|
|
begin
|
|
// Selecting an item changes the filename in the TEdit
|
|
// in save dialogs
|
|
if (FKind in [ldkSaveDesktop, ldkSavePDA]) and Selected then
|
|
begin
|
|
SaveEdit.Text := Item.Caption;
|
|
end
|
|
// In the OpenDialog the state of the Ok button is dependent
|
|
// on the selection of an item
|
|
else
|
|
begin
|
|
ButtonPanel.OkButton.Enabled := Selected;
|
|
end;
|
|
end;
|
|
|
|
// Used only in the TLazSelectDirectoryDialog
|
|
procedure TLazarusFileDialogForm.HandleTreeViewSelectionChanged(ASender: TObject);
|
|
begin
|
|
ButtonPanel.OKButton.Enabled := True;
|
|
end;
|
|
|
|
{ TLazOpenDialog }
|
|
|
|
class procedure TLazOpenDialog.WSRegisterClass;
|
|
begin
|
|
// Do nothing, because this dialog doesn't require a WS implementation
|
|
end;
|
|
|
|
function TLazOpenDialog.DoExecute: boolean;
|
|
begin
|
|
Result := FForm.ShowModal <> mrCancel;
|
|
FileName := FForm.FileName;
|
|
end;
|
|
|
|
procedure TLazOpenDialog.DoInitialize;
|
|
begin
|
|
FForm.Initialize(ldkOpenDesktop);
|
|
end;
|
|
|
|
constructor TLazOpenDialog.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
FForm := TLazarusFileDialogForm.CreateNew(Self);
|
|
FForm.FileName := FileName;
|
|
FForm.Filter := Filter;
|
|
FForm.Title := Title;
|
|
DoInitialize;
|
|
FForm.Hide;
|
|
end;
|
|
|
|
{ TLazSaveDialog }
|
|
|
|
procedure TLazSaveDialog.DoInitialize;
|
|
begin
|
|
FForm.Initialize(ldkSaveDesktop);
|
|
end;
|
|
|
|
{ TLazSelectDirectoryDialog }
|
|
|
|
procedure TLazSelectDirectoryDialog.DoInitialize;
|
|
begin
|
|
FForm.Initialize(ldkSelectDirectory);
|
|
end;
|
|
|
|
end.
|
|
|