lazarus/lcl/lazdialogs.pas
2011-11-20 21:19:29 +00:00

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.