MG: started inputfiledialog

git-svn-id: trunk@1595 -
This commit is contained in:
lazarus 2002-04-05 17:20:17 +00:00
parent 6c0dd98469
commit 0ece6bc6a1
2 changed files with 572 additions and 0 deletions

1
.gitattributes vendored
View File

@ -149,6 +149,7 @@ ide/include/ide.inc svneol=native#text/pascal
ide/include/linux/lazconf.inc svneol=native#text/pascal
ide/include/netbsd/lazconf.inc svneol=native#text/pascal
ide/include/win32/lazconf.inc svneol=native#text/pascal
ide/inputfiledialog.pas svneol=native#text/pascal
ide/inputhistory.pas svneol=native#text/pascal
ide/insertwatch.lrs svneol=native#text/pascal
ide/keymapping.pp svneol=native#text/pascal

571
ide/inputfiledialog.pas Normal file
View File

@ -0,0 +1,571 @@
{ $Id$ }
{
/***************************************************************************
inputfiledialog.pas
-------------------
TInputFileDialog is a dialog to let the user set some filenames.
***************************************************************************/
Author: Mattias Gaertner
}
unit InputFileDialog;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Dialogs, Buttons, StdCtrls, IDEProcs,
LResources;
type
TInputFileFlag = (iftDirectory, iftFilename, iftNotEmpty);
TInputFileFlags = set of TInputFileFlag;
TInputFileDialog = class(TForm)
OkButton: TButton;
CancelButton: TButton;
OpenDialog: TOpenDialog;
procedure OkButtonClick(Sender: TObject);
procedure CancelButtonClick(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure InputFileDlgButtonClick(Sender: TObject);
private
FFileCount: integer;
FFileTitles: TStringList;
FFileDescs: TStringList;
FFileNames: TStringList;
FFileFlags: ^TInputFileFlags;
FInputGroupboxes: TList; // list TGroupBox
FInputLabels: TList; // list of list of TLabel
FInputDescs: TStringList;
FInputEdits: TList; // list of TEdit
FInputFileDlgButtons: TList; // list of TButton
FUpdateCount: integer;
FForceUpdate: boolean;
function GetFileDescriptions(Index: integer): string;
function GetFileTitles(Index: integer): string;
function GetFileFlags(Index: integer): TInputFileFlags;
function GetFilenames(Index: integer): string;
procedure SetFileCount(const AValue: integer);
procedure SetFileDescriptions(Index: integer; const AValue: string);
procedure SetFileTitles(Index: integer; const AValue: string);
procedure SetFileFlags(Index: integer; const AValue: TInputFileFlags);
procedure SetFilenames(Index: integer; const AValue: string);
function UpdateNeeded: boolean;
function GetInputEdit(Index: integer): TEdit;
function GetInputFileDlgButton(Index: integer): TButton;
function GetLabelList(Index: integer): TList;
function GetLabel(Index, Line: integer): TLabel;
function GetGroupBox(Index: integer): TGroupBox;
function LabelListCount(Index: integer): integer;
function FileIndexOfFileDlgBtn(Button: TButton): integer;
procedure CreateInputComponents;
procedure CreateGroupBoxes;
procedure CreateEditComponents;
procedure CreateFileDlgButtonComponents;
procedure CreateLabelComponents;
procedure DeleteLabelList(Index: integer);
procedure DeleteAllLabels;
procedure ResizeComponents;
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure BeginUpdate;
procedure EndUpdate;
procedure Update;
function FilenameIsValidForFileIndex(Filename: string;
Index: integer): boolean;
public
property FileCount: integer read FFileCount write SetFileCount;
property FileTitles[Index: integer]: string
read GetFileTitles write SetFileTitles;
property FileNames[Index: integer]: string
read GetFileNames write SetFileNames;
property FileDescs[Index: integer]: string
read GetFileDescriptions write SetFileDescriptions;
property FileFlags[Index: integer]: TInputFileFlags
read GetFileFlags write SetFileFlags;
end;
function GetInputFileDialog: TInputFileDialog;
implementation
uses
Math;
var InputFileDlg: TInputFileDialog;
function GetInputFileDialog: TInputFileDialog;
begin
if InputFileDlg=nil then
InputFileDlg:=TInputFileDialog.Create(Application);
Result:=InputFileDlg;
end;
{ TInputFileDialog }
procedure TInputFileDialog.OkButtonClick(Sender: TObject);
var i: integer;
CurEdit: TEdit;
begin
for i:=0 to FileCount-1 do begin
CurEdit:=GetInputEdit(i);
CurEdit.Text:=SetDirSeparators(CurEdit.Text);
if not FilenameIsValidForFileIndex(CurEdit.Text,i) then begin
if MessageDlg('Invalid file',
'The file "'+CurEdit.Text+'"'#13
+'is invalid for the '+GetGroupBox(i).Caption,mtInformation,
[mbCancel,mbAbort],0)=mrAbort
then
ModalResult:=mrCancel
else
exit;
end;
end;
ModalResult:=mrOk
end;
procedure TInputFileDialog.CancelButtonClick(Sender: TObject);
begin
ModalResult:=mrCancel;
end;
procedure TInputFileDialog.FormResize(Sender: TObject);
begin
ResizeComponents;
end;
procedure TInputFileDialog.InputFileDlgButtonClick(Sender: TObject);
var
FileIndex: integer;
AFilename: string;
begin
FileIndex:=FileIndexOfFileDlgBtn(TButton(Sender));
if FileIndex<0 then exit;
if OpenDialog=nil then OpenDialog:=TOpenDialog.Create(Self);
with OpenDialog do begin
Title:='Select '+GetGroupBox(FileIndex).Caption;
if (not Execute) then exit;
AFilename:=Filename;
if not FilenameIsValidForFileIndex(AFilename,FileIndex) then exit;
GetInputEdit(FileIndex).Text:=AFilename;
end;
end;
function TInputFileDialog.GetFileDescriptions(Index: integer): string;
begin
Result:=FFileDescs[Index];
end;
function TInputFileDialog.GetFileTitles(Index: integer): string;
begin
Result:=FFileTitles[Index];
end;
function TInputFileDialog.GetFileFlags(Index: integer): TInputFileFlags;
begin
Result:=FFileFlags[Index];
end;
function TInputFileDialog.GetFilenames(Index: integer): string;
begin
Result:=FFileNames[Index];
end;
procedure TInputFileDialog.SetFileCount(const AValue: integer);
procedure SetStringListCount(sl: TStringlist);
begin
while sl.Count>AValue do
sl.Delete(sl.Count-1);
while sl.Count<AValue do
sl.Add('');
end;
var i: integer;
begin
if FFileCount=AValue then exit;
BeginUpdate;
SetStringListCount(FFileNames);
SetStringListCount(FFileDescs);
SetStringListCount(FFileTitles);
if FFileFlags<>nil then begin
FreeMem(FFileFlags);
FFileTitles:=nil;
end;
if AValue>0 then begin
Getmem(FFileFlags,SizeOf(TInputFileFlags)*AValue);
for i:=0 to AValue-1 do FFileFlags[i]:=[iftDirectory,iftNotEmpty];
end;
FFileCount:=AValue;
EndUpdate;
end;
procedure TInputFileDialog.SetFileDescriptions(Index: integer;
const AValue: string);
begin
FFileDescs[Index]:=AValue;
Update;
end;
procedure TInputFileDialog.SetFileTitles(Index: integer; const AValue: string);
begin
FFileTitles[Index]:=AValue;
Update;
end;
procedure TInputFileDialog.SetFileFlags(Index: integer;
const AValue: TInputFileFlags);
begin
FFileFlags[Index]:=AValue;
Update;
end;
procedure TInputFileDialog.SetFilenames(Index: integer; const AValue: string);
begin
FFileNames[Index]:=AValue;
Update;
end;
procedure TInputFileDialog.Update;
begin
if (FUpdateCount<>0) or (not UpdateNeeded) then exit;
CreateInputComponents;
FormResize(Self);
end;
function TInputFileDialog.FilenameIsValidForFileIndex(Filename: string;
Index: integer): boolean;
var CurFileFlags: TInputFileFlags;
begin
Result:=false;
CurFileFlags:=FileFlags[Index];
if (not (iftDirectory in CurFileFlags))
and DirectoryExists(Filename)
then
exit;
if (not (iftFilename in CurFileFlags))
and FileExists(Filename)
then
exit;
Result:=true;
end;
function TInputFileDialog.UpdateNeeded: boolean;
var i: integer;
begin
Result:=true;
if FForceUpdate then exit;
FForceUpdate:=true;
// check file count
if FileCount<>FInputEdits.Count then exit;
// check files
for i:=0 to FileCount-1 do begin
if FFileTitles[i]<>GetGroupBox(I).Caption then exit;
if FFileNames[i]<>GetInputEdit(I).Text then exit;
if FFileDescs[i]<>FInputDescs[i] then exit;
end;
FForceUpdate:=false;
Result:=false;
end;
function TInputFileDialog.GetInputEdit(Index: integer): TEdit;
begin
Result:=TEdit(FInputEdits[Index]);
end;
function TInputFileDialog.GetInputFileDlgButton(Index: integer): TButton;
begin
Result:=TButton(FInputFileDlgButtons[Index]);
end;
function TInputFileDialog.GetLabelList(Index: integer): TList;
begin
Result:=TList(FInputLabels[Index]);
end;
function TInputFileDialog.GetLabel(Index, Line: integer): TLabel;
begin
Result:=TLabel(GetLabelList(Index)[Line]);
end;
function TInputFileDialog.GetGroupBox(Index: integer): TGroupBox;
begin
Result:=TGroupBox(FInputGroupboxes[Index]);
end;
function TInputFileDialog.LabelListCount(Index: integer): integer;
begin
Result:=GetLabelList(Index).Count;
end;
function TInputFileDialog.FileIndexOfFileDlgBtn(Button: TButton): integer;
begin
for Result:=0 to FInputFileDlgButtons.Count-1 do
if GetInputFileDlgButton(Result)=Button then exit;
Result:=-1;
end;
procedure TInputFileDialog.CreateInputComponents;
begin
CreateGroupBoxes;
CreateEditComponents;
CreateFileDlgButtonComponents;
CreateLabelComponents;
end;
procedure TInputFileDialog.CreateGroupBoxes;
var
NewGroupBox: TGroupBox;
i: integer;
begin
// add new TGroupBoxes
while FInputGroupboxes.Count<FFileCount do begin
NewGroupBox:=TGroupBox.Create(Self);
with NewGroupBox do begin
Name:='InputGroupBox'+IntToStr(FInputGroupboxes.Count);
Parent:=Self;
Visible:=true;
end;
FInputGroupboxes.Add(NewGroupBox);
end;
// remove old unused TGroupBoxes
while FInputGroupboxes.Count>FFileCount do begin
GetGroupBox(FInputGroupboxes.Count-1).Free;
FInputGroupboxes.Delete(FInputGroupboxes.Count-1);
end;
// upadte existing TGroupBoxes
for i:=0 to FInputGroupboxes.Count-1 do
GetGroupBox(i).Caption:=FFileTitles[i];
end;
procedure TInputFileDialog.CreateEditComponents;
var
NewEdit: TEdit;
i: integer;
begin
// add new TEdits
while FInputEdits.Count<FFileCount do begin
NewEdit:=TEdit.Create(Self);
with NewEdit do begin
Name:='InputEdit'+IntToStr(FInputEdits.Count);
Parent:=Self;
Visible:=true;
end;
FInputEdits.Add(NewEdit);
end;
// remove old unused TEdits
while FInputEdits.Count>FFileCount do begin
GetInputEdit(FInputEdits.Count-1).Free;
FInputEdits.Delete(FInputEdits.Count-1);
end;
// upadte existing TEdits
for i:=0 to FInputEdits.Count-1 do
GetInputEdit(i).Text:=FFileNames[i];
end;
procedure TInputFileDialog.CreateFileDlgButtonComponents;
var NewButton: TButton;
begin
// add new TButtons
while FInputFileDlgButtons.Count<FFileCount do begin
NewButton:=TButton.Create(Self);
with NewButton do begin
Name:='InputFileDlgButtin'+IntToStr(FInputFileDlgButtons.Count);
Parent:=Self;
Caption:='...';
OnClick:=@InputFileDlgButtonClick;
Visible:=true;
end;
FInputFileDlgButtons.Add(NewButton);
end;
// remove unused TButtons
while FInputFileDlgButtons.Count>FFileCount do begin
GetInputFileDlgButton(FInputFileDlgButtons.Count-1).Free;
FInputFileDlgButtons.Delete(FInputFileDlgButtons.Count-1);
end;
end;
procedure TInputFileDialog.CreateLabelComponents;
var
NewLabelList: TList;
LabelsAsText: TStringList;
ListIndex, i: integer;
NewLabel: TLabel;
begin
// add new TLabels
while FInputLabels.Count<FFileCount do begin
ListIndex:=FInputLabels.Count;
// create TLabel list
NewLabelList:=TList.Create;
// create one TLabel for every line
for i:=0 to LabelsAsText.Count-1 do begin
NewLabel:=TLabel.Create(Self);
with NewLabel do begin
Name:='NewLabel';
Parent:=Self;
Visible:=true;
end;
NewLabelList.Add(NewLabel);
end;
FInputLabels.Add(NewLabelList);
end;
// remove unused TLabels
while FInputLabels.Count>FFileCount do begin
DeleteLabelList(FInputLabels.Count-1);
end;
// update label text
LabelsAsText:=TStringList.Create;
for ListIndex:=0 to FInputLabels.Count-1 do begin
// split description into lines
LabelsAsText.Text:=FFileDescs[ListIndex];
for i:=0 to LabelListCount(ListIndex)-1 do begin
GetLabel(ListIndex,i).Text:=LabelsAsText[i];
end;
end;
LabelsAsText.Free;
end;
procedure TInputFileDialog.DeleteLabelList(Index: integer);
var i: integer;
LabelList: TList;
begin
LabelList:=GetLabelList(Index);
for i:=LabelList.Count-1 downto 0 do begin
GetLabel(Index,i).Free;
LabelList.Delete(i);
end;
LabelList.Free;
FInputLabels.Delete(Index);
end;
procedure TInputFileDialog.ResizeComponents;
var
y, GroupBoxWidth, GroupBoxLeft, GroupBoxHeight, FileIndex,
LabelIndex, LabelLeft, LabelHeight, GroupBoxSpacing, LabelTop, LabelWidth,
ButtonWidth, ButtonHeight: integer;
CurLabel: TLabel;
CurEdit: TEdit;
CurButton: TButton;
begin
GroupBoxSpacing:=5;
GroupBoxLeft:=GroupBoxSpacing;
GroupBoxWidth:=ClientWidth-GroupBoxLeft*2;
y:=GroupBoxSpacing;
LabelHeight:=25;
// resize input components
for FileIndex:=0 to FileCount-1 do begin
GroupBoxHeight:=60+LabelListCount(FileIndex)*LabelHeight;
GetGroupBox(FileIndex).SetBounds(
GroupBoxLeft,y,GroupBoxWidth,y+GroupBoxHeight);
LabelTop:=2;
LabelLeft:=5;
LabelWidth:=GroupBoxWidth-LabelLeft*2;
for LabelIndex:=0 to LabelListCount(FileIndex)-1 do begin
CurLabel:=GetLabel(FileIndex,LabelIndex);
CurLabel.SetBounds(LabelLeft,LabelTop,LabelWidth,CurLabel.Height);
inc(LabelTop,LabelHeight);
end;
CurButton:=GetInputFileDlgButton(FileIndex);
ButtonWidth:=CurButton.Height;
ButtonHeight:=CurButton.Height;
CurEdit:=GetInputEdit(FileIndex);
CurEdit.SetBounds(LabelLeft,LabelTop,
LabelWidth-10-ButtonWidth,CurEdit.Height);
CurButton.SetBounds(CurEdit.Left+CurEdit.Width+3,LabelTop,
ButtonWidth,ButtonHeight);
inc(y,GroupBoxHeight+GroupBoxSpacing);
end;
inc(y,GroupBoxSpacing);
// resize ok and cancel button
OkButton.SetBounds(Max(GroupBoxLeft,GroupBoxLeft+GroupBoxWidth-250),y,
120,OkButton.Height);
CancelButton.SetBounds(OkButton.Left+OkButton.Width+10,OkButton.Top,
OkButton.Width,OkButton.Height);
inc(y,OkButton.Height+GroupBoxSpacing);
Height:=y;
end;
procedure TInputFileDialog.DeleteAllLabels;
var i: integer;
begin
for i:=FInputLabels.Count-1 downto 0 do
DeleteLabelList(i);
end;
constructor TInputFileDialog.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
Position:=poScreenCenter;
Width:=500;
OnResize:=@FormResize;
with OkButton do begin
Name:='OkButton';
Parent:=Self;
Caption:='OK';
OnClick:=@OkButtonClick;
Visible:=true;
end;
with CancelButton do begin
Name:='CancelButton';
Parent:=Self;
Caption:='Cancel';
OnClick:=@CancelButtonClick;
Visible:=true;
end;
FFileCount:=0;
FFileTitles:=TStringList.Create;
FFileDescs:=TStringList.Create;
FFileNames:=TStringList.Create;
FInputGroupboxes:=TList.Create;
FInputLabels:=TList.Create;
FInputDescs:=TStringList.Create;
FInputEdits:=TList.Create;
FInputFileDlgButtons:=TList.Create;
FUpdateCount:=0;
end;
destructor TInputFileDialog.Destroy;
begin
DeleteAllLabels;
FFileTitles.Free;
FFileDescs.Free;
FFileNames.Free;
if FFileFlags<>nil then FreeMem(FFileFlags);
FInputGroupboxes.Free;
FInputLabels.Free;
FInputDescs.Free;
FInputEdits.Free;
FInputFileDlgButtons.Free;
inherited Destroy;
end;
procedure TInputFileDialog.BeginUpdate;
begin
inc(FUpdateCount);
end;
procedure TInputFileDialog.EndUpdate;
begin
if FUpdateCount<=0 then exit;
dec(FUpdateCount);
if FUpdateCount=0 then
Update;
end;
end.