LCL: Several fixes for DirSel dialog (#9077) from Graeme

* fixed duplicate path delimiters
 * Removed hardcoded english captions with resource strings instead
 * fixed issue where dot directories (considered hidden in unix OS's)
   are not processed correctly with ShowHidden property
 * Sometimes nodes reported subdirectories when they didn't
   actually have (linux)
 * Minor code formatting changes (code cleanup)
 * Removed empty methods (more code cleanup)

git-svn-id: trunk@11351 -
This commit is contained in:
vincents 2007-06-21 12:16:25 +00:00
parent 237301a1ba
commit e128307175
4 changed files with 191 additions and 161 deletions

View File

@ -1,113 +1,124 @@
object DirSelDlg: TDirSelDlg
ActiveControl = TV
BorderStyle = BSDIALOG
Caption = 'Select Directory'
ClientHeight = 330
ClientWidth = 335
FormStyle = FSSTAYONTOP
OnCreate = FormCreate
OnShow = FormShow
Position = POSCREENCENTER
HorzScrollBar.Page = 336
HorzScrollBar.Range = 14
VertScrollBar.Page = 331
VertScrollBar.Range = 63
Left = 432
Height = 330
Top = 234
Width = 335
HorzScrollBar.Page = 334
HorzScrollBar.Range = 14
VertScrollBar.Page = 329
VertScrollBar.Range = 63
ActiveControl = TV
BorderStyle = bsDialog
Caption = 'Select Directory'
ClientHeight = 330
ClientWidth = 335
FormStyle = fsStayOnTop
OnShow = FormShow
Position = poScreenCenter
object Panel1: TPanel
Align = ALBOTTOM
BevelOuter = BVNONE
ClientHeight = 41
ClientWidth = 335
TabOrder = 0
TabStop = True
Height = 41
Top = 289
Width = 335
object Button1: TButton
Anchors = [AKRIGHT, AKBOTTOM]
Align = alBottom
BevelOuter = bvNone
ClientHeight = 41
ClientWidth = 335
TabOrder = 4
TabStop = True
object btnOK: TButton
AnchorSideRight.Control = btnCancel
AnchorSideBottom.Control = btnCancel
AnchorSideBottom.Side = asrBottom
Left = 161
Height = 25
Top = 10
Width = 75
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.InnerBorder = 4
Caption = 'btnOK'
Constraints.MaxHeight = 25
Constraints.MinHeight = 25
Constraints.MinWidth = 75
ModalResult = 1
Caption = 'OK'
TabStop = True
TabOrder = 0
Left = 169
Height = 25
Top = 9
Width = 75
end
object Button2: TButton
Anchors = [AKRIGHT, AKBOTTOM]
ModalResult = 2
Cancel = True
Caption = 'Cancel'
TabStop = True
TabOrder = 1
Left = 253
object btnCancel: TButton
AnchorSideRight.Control = Panel1
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Panel1
AnchorSideBottom.Side = asrBottom
Left = 242
Height = 25
Top = 9
Width = 75
Top = 10
Width = 87
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Around = 6
BorderSpacing.InnerBorder = 4
Cancel = True
Caption = 'btnCancel'
Constraints.MaxHeight = 25
Constraints.MinHeight = 25
Constraints.MinWidth = 75
ModalResult = 2
TabOrder = 1
end
end
object Panel2: TPanel
Align = ALLEFT
BevelOuter = BVNONE
ClientHeight = 265
ClientWidth = 7
TabOrder = 1
TabStop = True
Height = 265
Top = 24
Width = 7
Align = alLeft
BevelOuter = bvNone
TabOrder = 1
TabStop = True
end
object Panel3: TPanel
Align = ALTOP
BevelOuter = BVNONE
Height = 24
Width = 335
Align = alTop
BevelOuter = bvNone
ClientHeight = 24
ClientWidth = 335
TabOrder = 2
TabStop = True
Height = 24
Width = 335
object Label1: TLabel
Caption = '&Directory'
FocusControl = TV
Layout = TLCENTER
object lblDirectory: TLabel
Left = 140
Height = 15
Height = 17
Top = 4
Width = 54
Width = 76
Caption = '&Directory'
Color = clNone
FocusControl = TV
Layout = tlCenter
ParentColor = False
end
end
object Panel4: TPanel
Align = ALRIGHT
BevelOuter = BVNONE
ClientHeight = 265
ClientWidth = 7
TabOrder = 3
TabStop = True
Left = 328
Height = 265
Top = 24
Width = 7
Align = alRight
BevelOuter = bvNone
TabOrder = 3
TabStop = True
end
object TV: TTreeView
Align = ALCLIENT
Constraints.MinHeight = 100
Constraints.MinWidth = 100
DefaultItemHeight = 17
DragCursor = 65524
ParentColor = True
ParentCtl3D = False
ParentFont = True
ScrollBars = SSVERTICAL
TabOrder = 4
OnDblClick = TVItemDoubleClick
OnExpanded = TVExpanded
Left = 7
Height = 265
Top = 24
Width = 321
Align = alClient
Constraints.MinHeight = 100
Constraints.MinWidth = 100
DefaultItemHeight = 18
ParentColor = True
ParentCtl3D = False
ParentFont = True
ScrollBars = ssVertical
TabOrder = 0
OnExpanded = TVExpanded
end
end

View File

@ -1,31 +1,39 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TDirSelDlg','FORMDATA',[
'TPF0'#10'TDirSelDlg'#9'DirSelDlg'#13'ActiveControl'#7#2'TV'#11'BorderStyle'#7
+#8'BSDIALOG'#7'Caption'#6#16'Select Directory'#12'ClientHeight'#3'J'#1#11'Cl'
+'ientWidth'#3'O'#1#9'FormStyle'#7#11'FSSTAYONTOP'#8'OnCreate'#7#10'FormCreat'
+'e'#6'OnShow'#7#8'FormShow'#8'Position'#7#14'POSCREENCENTER'#18'HorzScrollBa'
+'r.Page'#3'P'#1#19'HorzScrollBar.Range'#2#14#18'VertScrollBar.Page'#3'K'#1#19
+'VertScrollBar.Range'#2'?'#4'Left'#3#176#1#6'Height'#3'J'#1#3'Top'#3#234#0#5
+'Width'#3'O'#1#0#6'TPanel'#6'Panel1'#5'Align'#7#8'ALBOTTOM'#10'BevelOuter'#7
+#6'BVNONE'#12'ClientHeight'#2')'#11'ClientWidth'#3'O'#1#8'TabOrder'#2#0#7'Ta'
+'bStop'#9#6'Height'#2')'#3'Top'#3'!'#1#5'Width'#3'O'#1#0#7'TButton'#7'Button'
+'1'#7'Anchors'#11#7'AKRIGHT'#8'AKBOTTOM'#0#11'ModalResult'#2#1#7'Caption'#6#2
+'OK'#7'TabStop'#9#8'TabOrder'#2#0#4'Left'#3#169#0#6'Height'#2#25#3'Top'#2#9#5
+'Width'#2'K'#0#0#7'TButton'#7'Button2'#7'Anchors'#11#7'AKRIGHT'#8'AKBOTTOM'#0
+#11'ModalResult'#2#2#6'Cancel'#9#7'Caption'#6#6'Cancel'#7'TabStop'#9#8'TabOr'
+'der'#2#1#4'Left'#3#253#0#6'Height'#2#25#3'Top'#2#9#5'Width'#2'K'#0#0#0#6'TP'
+'anel'#6'Panel2'#5'Align'#7#6'ALLEFT'#10'BevelOuter'#7#6'BVNONE'#12'ClientHe'
+'ight'#3#9#1#11'ClientWidth'#2#7#8'TabOrder'#2#1#7'TabStop'#9#6'Height'#3#9#1
+#3'Top'#2#24#5'Width'#2#7#0#0#6'TPanel'#6'Panel3'#5'Align'#7#5'ALTOP'#10'Bev'
+'elOuter'#7#6'BVNONE'#12'ClientHeight'#2#24#11'ClientWidth'#3'O'#1#8'TabOrde'
+'r'#2#2#7'TabStop'#9#6'Height'#2#24#5'Width'#3'O'#1#0#6'TLabel'#6'Label1'#7
+'Caption'#6#10'&Directory'#12'FocusControl'#7#2'TV'#6'Layout'#7#8'TLCENTER'#4
+'Left'#3#140#0#6'Height'#2#15#3'Top'#2#4#5'Width'#2'6'#0#0#0#6'TPanel'#6'Pan'
+'el4'#5'Align'#7#7'ALRIGHT'#10'BevelOuter'#7#6'BVNONE'#12'ClientHeight'#3#9#1
+#11'ClientWidth'#2#7#8'TabOrder'#2#3#7'TabStop'#9#4'Left'#3'H'#1#6'Height'#3
+#9#1#3'Top'#2#24#5'Width'#2#7#0#0#9'TTreeView'#2'TV'#5'Align'#7#8'ALCLIENT'
+#21'Constraints.MinHeight'#2'd'#20'Constraints.MinWidth'#2'd'#17'DefaultItem'
+'Height'#2#17#10'DragCursor'#4#244#255#0#0#11'ParentColor'#9#11'ParentCtl3D'
+#8#10'ParentFont'#9#10'ScrollBars'#7#10'SSVERTICAL'#8'TabOrder'#2#4#10'OnDbl'
+'Click'#7#17'TVItemDoubleClick'#10'OnExpanded'#7#10'TVExpanded'#4'Left'#2#7#6
+'Height'#3#9#1#3'Top'#2#24#5'Width'#3'A'#1#0#0#0
'TPF0'#10'TDirSelDlg'#9'DirSelDlg'#4'Left'#3#176#1#6'Height'#3'J'#1#3'Top'#3
+#234#0#5'Width'#3'O'#1#18'HorzScrollBar.Page'#3'N'#1#19'HorzScrollBar.Range'
+#2#14#18'VertScrollBar.Page'#3'I'#1#19'VertScrollBar.Range'#2'?'#13'ActiveCo'
+'ntrol'#7#2'TV'#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#16'Select Directo'
+'ry'#12'ClientHeight'#3'J'#1#11'ClientWidth'#3'O'#1#9'FormStyle'#7#11'fsStay'
+'OnTop'#6'OnShow'#7#8'FormShow'#8'Position'#7#14'poScreenCenter'#0#6'TPanel'
+#6'Panel1'#6'Height'#2')'#3'Top'#3'!'#1#5'Width'#3'O'#1#5'Align'#7#8'alBotto'
+'m'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2')'#11'ClientWidth'#3'O'#1#8
+'TabOrder'#2#4#7'TabStop'#9#0#7'TButton'#5'btnOK'#23'AnchorSideRight.Control'
+#7#9'btnCancel'#24'AnchorSideBottom.Control'#7#9'btnCancel'#21'AnchorSideBot'
+'tom.Side'#7#9'asrBottom'#4'Left'#3#161#0#6'Height'#2#25#3'Top'#2#10#5'Width'
+#2'K'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9#25'BorderSpacing.'
+'InnerBorder'#2#4#7'Caption'#6#5'btnOK'#21'Constraints.MaxHeight'#2#25#21'Co'
+'nstraints.MinHeight'#2#25#20'Constraints.MinWidth'#2'K'#11'ModalResult'#2#1
+#8'TabOrder'#2#0#0#0#7'TButton'#9'btnCancel'#23'AnchorSideRight.Control'#7#6
+'Panel1'#20'AnchorSideRight.Side'#7#9'asrBottom'#24'AnchorSideBottom.Control'
+#7#6'Panel1'#21'AnchorSideBottom.Side'#7#9'asrBottom'#4'Left'#3#242#0#6'Heig'
+'ht'#2#25#3'Top'#2#10#5'Width'#2'W'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8
+'AutoSize'#9#20'BorderSpacing.Around'#2#6#25'BorderSpacing.InnerBorder'#2#4#6
+'Cancel'#9#7'Caption'#6#9'btnCancel'#21'Constraints.MaxHeight'#2#25#21'Const'
+'raints.MinHeight'#2#25#20'Constraints.MinWidth'#2'K'#11'ModalResult'#2#2#8
+'TabOrder'#2#1#0#0#0#6'TPanel'#6'Panel2'#6'Height'#3#9#1#3'Top'#2#24#5'Width'
+#2#7#5'Align'#7#6'alLeft'#10'BevelOuter'#7#6'bvNone'#8'TabOrder'#2#1#7'TabSt'
+'op'#9#0#0#6'TPanel'#6'Panel3'#6'Height'#2#24#5'Width'#3'O'#1#5'Align'#7#5'a'
+'lTop'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2#24#11'ClientWidth'#3'O'
+#1#8'TabOrder'#2#2#7'TabStop'#9#0#6'TLabel'#12'lblDirectory'#4'Left'#3#140#0
+#6'Height'#2#17#3'Top'#2#4#5'Width'#2'L'#7'Caption'#6#10'&Directory'#5'Color'
+#7#6'clNone'#12'FocusControl'#7#2'TV'#6'Layout'#7#8'tlCenter'#11'ParentColor'
+#8#0#0#0#6'TPanel'#6'Panel4'#4'Left'#3'H'#1#6'Height'#3#9#1#3'Top'#2#24#5'Wi'
+'dth'#2#7#5'Align'#7#7'alRight'#10'BevelOuter'#7#6'bvNone'#8'TabOrder'#2#3#7
+'TabStop'#9#0#0#9'TTreeView'#2'TV'#4'Left'#2#7#6'Height'#3#9#1#3'Top'#2#24#5
+'Width'#3'A'#1#5'Align'#7#8'alClient'#21'Constraints.MinHeight'#2'd'#20'Cons'
+'traints.MinWidth'#2'd'#17'DefaultItemHeight'#2#18#11'ParentColor'#9#11'Pare'
+'ntCtl3D'#8#10'ParentFont'#9#10'ScrollBars'#7#10'ssVertical'#8'TabOrder'#2#0
+#10'OnExpanded'#7#10'TVExpanded'#0#0#0
]);

View File

@ -28,25 +28,21 @@ interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
StdCtrls, ComCtrls, ExtCtrls, FileCtrl;
StdCtrls, ComCtrls, ExtCtrls;
type
TDirSelDlg = class(TForm)
Button1: TBUTTON;
Button2: TBUTTON;
Label1: TLABEL;
Panel1: TPANEL;
Panel2: TPANEL;
Panel3: TPANEL;
Panel4: TPANEL;
TV: TTREEVIEW;
procedure FormCreate(Sender: TObject);
//procedure Create(AOwner: TComponent);
btnOK: TButton;
btnCancel: TButton;
lblDirectory: TLabel;
Panel1: TPanel;
Panel2: TPanel;
Panel3: TPanel;
Panel4: TPanel;
TV: TTreeview;
procedure FormShow(Sender: TObject);
procedure TVExpanded(Sender: TObject; Node: TTreeNode);
procedure TVItemDoubleClick(Sender: TObject);
private
{ private declarations }
FRootDir: string;
FDir: string;
FShowHidden: Boolean;
@ -55,8 +51,8 @@ type
function GetAbsolutePath(Node: TTreeNode): string;
procedure SetDir(const Value: string);
procedure SetRootDir(const Value: string);
procedure SetupCaptions;
public
{ public declarations }
function SelectedDir: string;
property Directory: string read FDir write SetDir;
property RootDirectory: string read FRootDir write SetRootDir;
@ -69,39 +65,49 @@ var
implementation
{ TDirSelDlg }
uses
FileUtil, LCLStrConsts;
{Function HasSubDirs returns True if the directory passed has subdirectories}
function HasSubDirs(const Dir: string; IgnoreHidden: boolean): Boolean;
function HasSubDirs(const Dir: string; AShowHidden: boolean): Boolean;
var
//Result of FindFirst, FindNext
FileInfo: TSearchRec;
FCurrentDir: string;
begin
//Assume No
Result:= False;
if Dir <> '' then
begin
FCurrentDir:= Dir;
FileCtrl.AppendPathDelim(FCurrentDir);
FCurrentDir:= Dir + GetAllFilesMask;
Try
if SysUtils.FindFirst(FCurrentDir, (faAnyFile),FileInfo)=0 then
begin
repeat
// check if special file
if ((FileInfo.Name='.') or (FileInfo.Name='..')) or (FileInfo.Name='')
(((faHidden and FileInfo.Attr)>0) and
IgnoreHidden) then continue;
Result:= ((faDirectory and FileInfo.Attr)>0);
//We found at least one non special dir, that's all we need.
if Result then break;
until SysUtils.FindNext(FileInfo)<>0;
end;//if
finally
SysUtils.FindClose(FileInfo);
end;//Try-Finally
end;//if
//Assume No
Result := False;
if Dir <> '' then
begin
FCurrentDir := AppendPathDelim(Dir);
FCurrentDir := FCurrentDir + GetAllFilesMask;
// writeln('FCurrentDir=' + FCurrentDir);
try
if SysUtils.FindFirst(FCurrentDir, faAnyFile, FileInfo)=0 then
begin
repeat
if FileInfo.Name = '' then
Continue;
// check if special file
if ((FileInfo.Name='.') or (FileInfo.Name='..')) or
// unix dot directories (aka hidden directories)
((FileInfo.Name[1] in ['.']) and AShowHidden) or
// check Hidden attribute
(((faHidden and FileInfo.Attr)>0) and AShowHidden) then
Continue;
Result := ((faDirectory and FileInfo.Attr)>0);
//We found at least one non special dir, that's all we need.
if Result then
break;
until SysUtils.FindNext(FileInfo)<>0;
end;//if
finally
SysUtils.FindClose(FileInfo);
end;//Try-Finally
end;//if
end;//HasSubDirs
@ -118,10 +124,10 @@ begin
if Dir <> '' then
begin
FCurrentDir:= Dir;
FileCtrl.AppendPathDelim(FCurrentDir);
AppendPathDelim(FCurrentDir);
i:= length(FCurrentDir);
FCurrentDir:= Dir + GetAllFilesMask;
Try
try
if SysUtils.FindFirst(FCurrentDir, faAnyFile,FileInfo)=0 then
begin
Try
@ -129,16 +135,22 @@ begin
SortList.Sorted:= True;
repeat
// check if special file
if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='')
then
continue;
if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='') then
Continue;
// if hidden files or directories must be filtered, we test for
// dot files, considered hidden under unix type OS's.
if not FShowHidden then
if (FileInfo.Name[1] in ['.']) then
Continue;
// if this is a directory then add it to the tree.
if ((faDirectory and FileInfo.Attr)>0) then
begin
//if this is a hidden file and we have not been requested to show
//hidder files then do not add it to the list.
if ((faHidden and FileInfo.Attr)>0)
and not (FShowHidden) then continue;
//hidden files then do not add it to the list.
if ((faHidden and FileInfo.Attr)>0) and not FShowHidden then
continue;
SortList.Add(FileInfo.Name);
end;//if
until SysUtils.FindNext(FileInfo)<>0;
@ -146,7 +158,7 @@ begin
begin
NewNode:= TV.Items.AddChild(Node,SortList[i]);
//if subdirectories then indicate so.
NewNode.HasChildren:= HasSubDirs(Dir + PathDelim + NewNode.Text, FShowHidden);
NewNode.HasChildren := HasSubDirs(AppendPathDelim(Dir) + NewNode.Text, FShowHidden);
end;//for
finally
SortList.free;
@ -180,6 +192,14 @@ begin
TV.Selected:= RootNode;
end;//SetRootDir
procedure TDirSelDlg.SetupCaptions;
begin
Caption := rsfdSelectDirectory;
btnOK.Caption := rsMbOK;
btnCancel.Caption := rsMbCancel;
lblDirectory.Caption := rsDirectory;
end;
{Returns the absolute path to a node.}
function TDirSelDlg.GetAbsolutePath(Node: TTreeNode): string;
begin
@ -194,14 +214,9 @@ begin
end;//while
end;//GetAbsolutePath
procedure TDirSelDlg.FormCreate(Sender: TObject);
begin
end;
procedure TDirSelDlg.FormShow(Sender: TObject);
begin
SetupCaptions;
if TV.Selected <> nil then
TV.Selected.Expand(false);
end;//FormShow
@ -212,11 +227,6 @@ begin
AddDirectories(Node, GetAbsolutePath(Node));
end;//TVExpanded
procedure TDirSelDlg.TVItemDoubleClick(Sender: TObject);
begin
end;
procedure TDirSelDlg.SetDir(const Value: string);
var
StartDir: string;

View File

@ -67,6 +67,7 @@ ResourceString
rsfdFileSaveAs = 'Save file as';
rsAllFiles = 'All files (%s)|%s|%s';
rsfdSelectDirectory = 'Select Directory';
rsDirectory = '&Directory';
// Select color dialog
rsSelectcolorTitle = 'Select color';