fix #264, Mini explorer, add virtual root nodes

This commit is contained in:
Basile Burg 2018-03-17 04:21:32 +01:00
parent 903c85c8f7
commit 5c00c05b4b
3 changed files with 323 additions and 314 deletions

View File

@ -5,7 +5,7 @@ unit ce_lcldragdrop;
interface interface
uses uses
Classes, SysUtils, Controls, ComCtrls, Classes, SysUtils, Controls, ComCtrls, ShellCtrls,
ce_common, ce_ceproject, ce_dubproject, ce_interfaces, ce_common, ce_ceproject, ce_dubproject, ce_interfaces,
ce_dialogs, ce_projutils; ce_dialogs, ce_projutils;
@ -89,17 +89,17 @@ end;
function TDDHandler.getFilename(src: TObject): string; function TDDHandler.getFilename(src: TObject): string;
var var
lst: TListView; lst: TShellListView;
trv: TTreeView; trv: TTreeView;
begin begin
result := ''; result := '';
if src.isNil then exit; if src.isNil then exit;
// from mini-explorer // from mini-explorer
if src is TListView then if src is TShellListView then
begin begin
lst := TListView(src); lst := TShellListView(src);
if lst.Selected.isNotNil and lst.Selected.Data.isNotNil then if lst.Selected.isNotNil then
result := PString(lst.Selected.Data)^; result := lst.GetPathFromItem(lst.Selected);
end end
// from CE/DUB project inspector // from CE/DUB project inspector
else if src is TTreeView then else if src is TTreeView then

View File

@ -1,31 +1,30 @@
inherited CEMiniExplorerWidget: TCEMiniExplorerWidget inherited CEMiniExplorerWidget: TCEMiniExplorerWidget
Left = 1558 Left = 1367
Height = 598 Height = 654
Top = 110 Top = 3
Width = 343 Width = 530
ActiveControl = lstFav ActiveControl = lstFav
Caption = 'Mini explorer' Caption = 'Mini explorer'
ClientHeight = 598 ClientHeight = 654
ClientWidth = 343 ClientWidth = 530
inherited Back: TPanel inherited Back: TPanel
Height = 598 Height = 654
Width = 343 Width = 530
AutoSize = True AutoSize = True
ClientHeight = 598 ClientHeight = 654
ClientWidth = 343 ClientWidth = 530
inherited Content: TPanel inherited Content: TPanel
Left = 4 Left = 4
Height = 558 Height = 612
Top = 36 Width = 522
Width = 335
BorderSpacing.Around = 4 BorderSpacing.Around = 4
ClientHeight = 558 ClientHeight = 612
ClientWidth = 335 ClientWidth = 522
object lstFav: TListView[0] object lstFav: TListView[0]
Left = 0 Left = 0
Height = 131 Height = 131
Top = 0 Top = 0
Width = 335 Width = 522
Align = alTop Align = alTop
Columns = < Columns = <
item item
@ -36,6 +35,8 @@ inherited CEMiniExplorerWidget: TCEMiniExplorerWidget
ShowColumnHeaders = False ShowColumnHeaders = False
TabOrder = 0 TabOrder = 0
ViewStyle = vsReport ViewStyle = vsReport
OnDeletion = lstFavDeletion
OnEdited = lstFavEdited
OnEnter = lstFavEnter OnEnter = lstFavEnter
end end
object Splitter1: TSplitter[1] object Splitter1: TSplitter[1]
@ -43,71 +44,71 @@ inherited CEMiniExplorerWidget: TCEMiniExplorerWidget
Left = 0 Left = 0
Height = 6 Height = 6
Top = 131 Top = 131
Width = 335 Width = 522
Align = alTop Align = alTop
ResizeAnchor = akTop ResizeAnchor = akTop
end end
object Panel2: TPanel[2] object Panel2: TPanel[2]
Left = 0 Left = 0
Height = 421 Height = 475
Top = 137 Top = 137
Width = 335 Width = 522
Align = alClient Align = alClient
AutoSize = True AutoSize = True
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 421 ClientHeight = 475
ClientWidth = 335 ClientWidth = 522
TabOrder = 2 TabOrder = 2
object Tree: TTreeView
Left = 0
Height = 171
Top = 0
Width = 335
Align = alTop
ReadOnly = True
ScrollBars = ssAutoBoth
TabOrder = 0
OnEnter = TreeEnter
Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
TreeLinePenStyle = psClear
end
object Splitter2: TSplitter object Splitter2: TSplitter
Cursor = crVSplit Cursor = crVSplit
Left = 0 Left = 0
Height = 6 Height = 6
Top = 171 Top = 218
Width = 335 Width = 522
Align = alTop Align = alTop
ResizeAnchor = akTop ResizeAnchor = akTop
end end
object lstFiles: TListView object treeFolders: TShellTreeView
Left = 0 Left = 0
Height = 244 Height = 218
Top = 177 Top = 0
Width = 335 Width = 522
Align = alTop
FileSortType = fstAlphabet
ReadOnly = True
ScrollBars = ssAutoBoth
TabOrder = 1
OnChange = treeFoldersChange
OnDblClick = treeFoldersDblClick
OnEnter = TreeEnter
OnGetImageIndex = treeFoldersGetImageIndex
OnGetSelectedIndex = treeFoldersGetSelectedIndex
Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
ObjectTypes = [otFolders]
ShellListView = lstFiles
end
object lstFiles: TShellListView
Left = 0
Height = 251
Top = 224
Width = 522
Align = alClient Align = alClient
AutoSort = False Color = clDefault
Columns = <
item
Width = 333
end>
DragMode = dmAutomatic DragMode = dmAutomatic
ReadOnly = True ReadOnly = True
ScrollBars = ssAutoBoth ScrollBars = ssAutoBoth
ShowColumnHeaders = False SortType = stText
TabOrder = 2 TabOrder = 2
ViewStyle = vsReport
OnDblClick = lstFilesDblClick OnDblClick = lstFilesDblClick
OnEnter = lstFilesEnter ObjectTypes = [otNonFolders, otHidden]
OnStartDrag = lstFilesStartDrag ShellTreeView = treeFolders
end end
end end
end end
inherited toolbar: TCEToolBar inherited toolbar: TCEToolBar
Height = 28 Width = 522
Width = 335
object btnEdit: TCEToolButton[0] object btnEdit: TCEToolButton[0]
Left = 85 Left = 153
Hint = 'open the selected file in an editor or as a new project' Hint = 'open the selected file in an editor or as a new project'
Top = 0 Top = 0
AutoSize = True AutoSize = True
@ -117,7 +118,7 @@ inherited CEMiniExplorerWidget: TCEMiniExplorerWidget
scaledSeparator = False scaledSeparator = False
end end
object btnShellOpen: TCEToolButton[1] object btnShellOpen: TCEToolButton[1]
Left = 57 Left = 125
Hint = 'open the selected folder or the selected file using the shell' Hint = 'open the selected folder or the selected file using the shell'
Top = 0 Top = 0
AutoSize = True AutoSize = True
@ -127,7 +128,7 @@ inherited CEMiniExplorerWidget: TCEMiniExplorerWidget
scaledSeparator = False scaledSeparator = False
end end
object btnRemFav: TCEToolButton[2] object btnRemFav: TCEToolButton[2]
Left = 29 Left = 97
Hint = 'remove selected favorite folder' Hint = 'remove selected favorite folder'
Top = 0 Top = 0
AutoSize = True AutoSize = True
@ -137,7 +138,7 @@ inherited CEMiniExplorerWidget: TCEMiniExplorerWidget
scaledSeparator = False scaledSeparator = False
end end
object btnAddFav: TCEToolButton[3] object btnAddFav: TCEToolButton[3]
Left = 1 Left = 69
Hint = 'add selected folder to the favorites' Hint = 'add selected folder to the favorites'
Top = 0 Top = 0
AutoSize = True AutoSize = True
@ -146,25 +147,54 @@ inherited CEMiniExplorerWidget: TCEMiniExplorerWidget
resourceName = 'FOLDER_ADD' resourceName = 'FOLDER_ADD'
scaledSeparator = False scaledSeparator = False
end end
object lstFilter: TListFilterEdit[4] object btnDrive: TCEToolButton[4]
Left = 119 Left = 1
Hint = 'select a drive or a custom folder'
Top = 0
AutoSize = True
Caption = 'btnDrive'
DropdownMenu = mnuDrives
OnClick = btnDriveClick
Style = tbsDropDown
resourceName = 'FOLDER_GO'
scaledSeparator = False
end
object btnParentFolder: TCEToolButton[5]
Left = 41
Hint = 'select parent folder'
Top = 0
AutoSize = True
Caption = 'btnParentFolder'
OnClick = btnParentFolderClick
resourceName = 'GO_PREVIOUS'
scaledSeparator = False
end
object lstFilter: TListViewFilterEdit[6]
Left = 183
Height = 24 Height = 24
Hint = 'filter the file names that contain the text typed here'
Top = 2 Top = 2
Width = 214 Width = 337
ButtonWidth = 28 ButtonWidth = 23
NumGlyphs = 1 NumGlyphs = 1
Flat = True
Align = alClient Align = alClient
Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 180
BorderSpacing.Left = 116 BorderSpacing.Bottom = 2
BorderSpacing.Around = 2 BorderSpacing.Around = 2
MaxLength = 0 MaxLength = 0
TabOrder = 0 TabOrder = 0
OnButtonClick = lstFilterButtonClick
OnKeyUp = lstFilterKeyUp
TextHint = '(filter)'
end end
end end
end end
inherited contextMenu: TPopupMenu inherited contextMenu: TPopupMenu
left = 72 left = 40
top = 56 top = 48
end
object mnuDrives: TPopupMenu[2]
left = 8
top = 48
end end
end end

View File

@ -5,10 +5,11 @@ unit ce_miniexplorer;
interface interface
uses uses
Classes, SysUtils, FileUtil, ListFilterEdit, Forms, Controls, Graphics, Classes, SysUtils, FileUtil, ListViewFilterEdit, Forms, strutils ,
ExtCtrls, Menus, ComCtrls, Buttons, lcltype, strutils, ce_widget, ce_sharedres, Controls, Graphics, ExtCtrls, Menus, ComCtrls, Buttons, lcltype, dialogs,
ce_common, ce_interfaces, ce_observer, ce_writableComponent, ce_dubproject, ce_widget, ce_sharedres, ce_common, ce_interfaces, ce_observer,
ce_ceproject, EditBtn, ce_dialogs, ce_synmemo, ce_projutils, ce_dsgncontrols; ce_writableComponent, ce_dubproject, ce_ceproject, EditBtn, ShellCtrls,
ce_dialogs, ce_synmemo, ce_projutils, ce_dsgncontrols;
type type
@ -20,6 +21,7 @@ type
private private
fDblClick: TExplorerDoubleClick; fDblClick: TExplorerDoubleClick;
fContextExpand: boolean; fContextExpand: boolean;
fShowHidden: boolean;
fExplorer: TCEMiniExplorerWidget; fExplorer: TCEMiniExplorerWidget;
function optionedWantCategory(): string; function optionedWantCategory(): string;
function optionedWantEditorKind: TOptionEditorKind; function optionedWantEditorKind: TOptionEditorKind;
@ -30,6 +32,7 @@ type
published published
property doubleClick: TExplorerDoubleClick read fDblClick write fDblClick; property doubleClick: TExplorerDoubleClick read fDblClick write fDblClick;
property contextExpand: boolean read fContextExpand write fContextExpand; property contextExpand: boolean read fContextExpand write fContextExpand;
property showHidden: boolean read fShowHidden write fShowHidden default true;
public public
constructor create(miniexpl: TCEMiniExplorerWidget); constructor create(miniexpl: TCEMiniExplorerWidget);
destructor destroy; override; destructor destroy; override;
@ -43,6 +46,7 @@ type
fLastFolder: string; fLastFolder: string;
fDblClick: TExplorerDoubleClick; fDblClick: TExplorerDoubleClick;
fContextExpand: boolean; fContextExpand: boolean;
fShowHidden: boolean;
procedure setFavoriteFolders(value: TStringList); procedure setFavoriteFolders(value: TStringList);
published published
property splitter1Position: integer read fSplitter1Position write fSplitter1Position; property splitter1Position: integer read fSplitter1Position write fSplitter1Position;
@ -51,6 +55,7 @@ type
property favoriteFolders: TStringList read fFavoriteFolders write setFavoriteFolders; property favoriteFolders: TStringList read fFavoriteFolders write setFavoriteFolders;
property doubleClick: TExplorerDoubleClick read fDblClick write fDblClick; property doubleClick: TExplorerDoubleClick read fDblClick write fDblClick;
property contextExpand: boolean read fContextExpand write fContextExpand; property contextExpand: boolean read fContextExpand write fContextExpand;
property showHidden: boolean read fShowHidden write fShowHidden default true;
public public
constructor create(aOwner: TComponent); override; constructor create(aOwner: TComponent); override;
destructor destroy; override; destructor destroy; override;
@ -62,25 +67,38 @@ type
TCEMiniExplorerWidget = class(TCEWidget, ICEProjectObserver, ICEDocumentObserver, ICEExplorer) TCEMiniExplorerWidget = class(TCEWidget, ICEProjectObserver, ICEDocumentObserver, ICEExplorer)
btnAddFav: TCEToolButton; btnAddFav: TCEToolButton;
btnDrive: TCEToolButton;
btnEdit: TCEToolButton; btnEdit: TCEToolButton;
btnParentFolder: TCEToolButton;
btnRemFav: TCEToolButton; btnRemFav: TCEToolButton;
btnShellOpen: TCEToolButton; btnShellOpen: TCEToolButton;
lstFilter: TListFilterEdit; lstFilter: TListViewFilterEdit;
lstFiles: TListView;
lstFav: TListView; lstFav: TListView;
Panel2: TPanel; Panel2: TPanel;
lstFiles: TShellListView;
mnuDrives: TPopupMenu;
treeFolders: TShellTreeView;
Splitter1: TSplitter; Splitter1: TSplitter;
Splitter2: TSplitter; Splitter2: TSplitter;
Tree: TTreeView; procedure btnDriveClick(Sender: TObject);
procedure btnEditClick(Sender: TObject); procedure btnEditClick(Sender: TObject);
procedure btnParentFolderClick(Sender: TObject);
procedure btnShellOpenClick(Sender: TObject); procedure btnShellOpenClick(Sender: TObject);
procedure btnAddFavClick(Sender: TObject); procedure btnAddFavClick(Sender: TObject);
procedure btnRemFavClick(Sender: TObject); procedure btnRemFavClick(Sender: TObject);
procedure lstFavDeletion(Sender: TObject; Item: TListItem);
procedure lstFavEdited(Sender: TObject; Item: TListItem; var AValue: string);
procedure lstFavEnter(Sender: TObject); procedure lstFavEnter(Sender: TObject);
procedure lstFilesDblClick(Sender: TObject); procedure lstFilesDblClick(Sender: TObject);
procedure lstFilesEnter(Sender: TObject); procedure lstFilesEnter(Sender: TObject);
procedure lstFilesStartDrag(Sender: TObject; var DragObject: TDragObject); procedure lstFilesStartDrag(Sender: TObject; var DragObject: TDragObject);
procedure lstFilterButtonClick(Sender: TObject);
procedure lstFilterKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure TreeEnter(Sender: TObject); procedure TreeEnter(Sender: TObject);
procedure treeFoldersChange(Sender: TObject; Node: TTreeNode);
procedure treeFoldersDblClick(Sender: TObject);
procedure treeFoldersGetImageIndex(Sender: TObject; Node: TTreeNode);
procedure treeFoldersGetSelectedIndex(Sender: TObject; Node: TTreeNode);
private private
fProj: ICECommonProject; fProj: ICECommonProject;
fFreeProj: ICECommonProject; fFreeProj: ICECommonProject;
@ -91,22 +109,15 @@ type
fContextExpand: boolean; fContextExpand: boolean;
fEditableOptions: TCEMiniExplorerEditableOptions; fEditableOptions: TCEMiniExplorerEditableOptions;
fImages: TImageList; fImages: TImageList;
procedure filterFiles;
procedure lstFavDblClick(Sender: TObject); procedure lstFavDblClick(Sender: TObject);
procedure updateFavorites; procedure updateFavorites;
procedure treeSetRoots; procedure treeSetRoots;
procedure lstFilesFromTree;
procedure treeScanSubFolders(aRoot: TTreeNode);
procedure treeClick(sender: TObject);
procedure treeChanged(Sender: TObject; Node: TTreeNode);
procedure treeExpanding(Sender: TObject; Node: TTreeNode; var allow: boolean);
procedure treeDeletion(Sender: TObject; Item: TTreeNode);
procedure treeSelectionChanged(sender: TObject);
procedure favStringsChange(sender: TObject); procedure favStringsChange(sender: TObject);
procedure fillLstFiles(const aList: TStrings);
procedure lstDeletion(Sender: TObject; Item: TListItem);
procedure lstFavSelect(Sender: TObject; Item: TListItem; Selected: Boolean); procedure lstFavSelect(Sender: TObject; Item: TListItem; Selected: Boolean);
procedure shellOpenSelected; procedure shellOpenSelected;
procedure lstFilterChange(sender: TObject); procedure mnuDriveItemClick(sender: TObject);
procedure mnuDriveSelect(sender: TObject);
// //
procedure projNew(project: ICECommonProject); procedure projNew(project: ICECommonProject);
procedure projChanged(project: ICECommonProject); procedure projChanged(project: ICECommonProject);
@ -128,8 +139,6 @@ type
public public
constructor create(aOwner: TComponent); override; constructor create(aOwner: TComponent); override;
destructor destroy; override; destructor destroy; override;
//
procedure expandPath(aPath: string);
end; end;
implementation implementation
@ -143,6 +152,7 @@ const
constructor TCEMiniExplorerEditableOptions.create(miniexpl: TCEMiniExplorerWidget); constructor TCEMiniExplorerEditableOptions.create(miniexpl: TCEMiniExplorerWidget);
begin begin
fExplorer := miniexpl; fExplorer := miniexpl;
fShowHidden:=true;
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
end; end;
@ -156,6 +166,17 @@ procedure TCEMiniExplorerEditableOptions.apply;
begin begin
fExplorer.fContextExpand:= fContextExpand; fExplorer.fContextExpand:= fContextExpand;
fExplorer.fDblClick:= fDblClick; fExplorer.fDblClick:= fDblClick;
if fShowHidden then
begin
fExplorer.treeFolders.ObjectTypes := fExplorer.treeFolders.ObjectTypes + [otHidden];
fExplorer.lstFiles.ObjectTypes := fExplorer.lstFiles.ObjectTypes + [otHidden];
end
else
begin
fExplorer.treeFolders.ObjectTypes := fExplorer.treeFolders.ObjectTypes - [otHidden];
fExplorer.lstFiles.ObjectTypes := fExplorer.lstFiles.ObjectTypes - [otHidden];
end;
fExplorer.treeFolders.Refresh;
end; end;
function TCEMiniExplorerEditableOptions.optionedWantCategory(): string; function TCEMiniExplorerEditableOptions.optionedWantCategory(): string;
@ -189,6 +210,7 @@ constructor TCEMiniExplorerOptions.create(aOwner: TComponent);
begin begin
inherited; inherited;
fFavoriteFolders := TStringList.Create; fFavoriteFolders := TStringList.Create;
fShowHidden:=true;
end; end;
destructor TCEMiniExplorerOptions.destroy; destructor TCEMiniExplorerOptions.destroy;
@ -210,6 +232,7 @@ begin
fSplitter2Position := widg.Splitter2.GetSplitterPosition; fSplitter2Position := widg.Splitter2.GetSplitterPosition;
fDblClick:= widg.fDblClick; fDblClick:= widg.fDblClick;
fContextExpand:=widg.fContextExpand; fContextExpand:=widg.fContextExpand;
fShowHidden:= otHidden in widg.lstFiles.ObjectTypes;
end end
else inherited; else inherited;
end; end;
@ -230,8 +253,18 @@ begin
widg.fContextExpand := fContextExpand; widg.fContextExpand := fContextExpand;
widg.fEditableOptions.fContextExpand := fContextExpand; widg.fEditableOptions.fContextExpand := fContextExpand;
widg.updateFavorites; widg.updateFavorites;
if widg.fLastFold.dirExists then if fShowHidden then
widg.expandPath(fLastFolder); begin
widg.treeFolders.ObjectTypes := widg.treeFolders.ObjectTypes + [otHidden];
widg.lstFiles.ObjectTypes := widg.lstFiles.ObjectTypes + [otHidden];
end
else
begin
widg.treeFolders.ObjectTypes := widg.treeFolders.ObjectTypes - [otHidden];
widg.lstFiles.ObjectTypes := widg.lstFiles.ObjectTypes -[otHidden];
end;
if widg.fLastFold.dirExists then
widg.browse(fLastFolder);
end end
else inherited; else inherited;
end; end;
@ -255,7 +288,7 @@ begin
begin begin
fImages.Width := 16; fImages.Width := 16;
fImages.Height := 16; fImages.Height := 16;
Tree.Indent := 16; treeFolders.Indent := 16;
fImages.AddResourceName(HINSTANCE, 'DOCUMENT'); fImages.AddResourceName(HINSTANCE, 'DOCUMENT');
fImages.AddResourceName(HINSTANCE, 'FOLDER'); fImages.AddResourceName(HINSTANCE, 'FOLDER');
fImages.AddResourceName(HINSTANCE, 'FOLDER_STAR'); fImages.AddResourceName(HINSTANCE, 'FOLDER_STAR');
@ -267,7 +300,7 @@ begin
begin begin
fImages.Width := 24; fImages.Width := 24;
fImages.Height := 24; fImages.Height := 24;
Tree.Indent := 24; treeFolders.Indent := 24;
fImages.AddResourceName(HINSTANCE, 'DOCUMENT24'); fImages.AddResourceName(HINSTANCE, 'DOCUMENT24');
fImages.AddResourceName(HINSTANCE, 'FOLDER24'); fImages.AddResourceName(HINSTANCE, 'FOLDER24');
fImages.AddResourceName(HINSTANCE, 'FOLDER_STAR24'); fImages.AddResourceName(HINSTANCE, 'FOLDER_STAR24');
@ -279,7 +312,7 @@ begin
begin begin
fImages.Width := 24; fImages.Width := 24;
fImages.Height := 24; fImages.Height := 24;
Tree.Indent := 24; treeFolders.Indent := 24;
fImages.AddResourceName(HINSTANCE, 'DOCUMENT32'); fImages.AddResourceName(HINSTANCE, 'DOCUMENT32');
fImages.AddResourceName(HINSTANCE, 'FOLDER32'); fImages.AddResourceName(HINSTANCE, 'FOLDER32');
fImages.AddResourceName(HINSTANCE, 'FOLDER_STAR32'); fImages.AddResourceName(HINSTANCE, 'FOLDER_STAR32');
@ -289,27 +322,22 @@ begin
end; end;
end; end;
lstFav.SmallImages := fImages; lstFav.SmallImages := fImages;
tree.Images := fImages;
treeFolders.Images := fImages;
treeFolders.StateImages := fImages;
lstFiles.SmallImages := fImages; lstFiles.SmallImages := fImages;
lstFiles.StateImages := fImages;
lstFiles.OnEnter:=@lstFilesEnter;
fEditableOptions:= TCEMiniExplorerEditableOptions.create(self); fEditableOptions:= TCEMiniExplorerEditableOptions.create(self);
fFavorites := TStringList.Create; fFavorites := TStringList.Create;
fFavorites.onChange := @favStringsChange; fFavorites.onChange := @favStringsChange;
lstFiles.OnDeletion := @lstDeletion;
lstFav.OnDeletion := @lstDeletion;
lstFav.OnSelectItem := @lstFavSelect; lstFav.OnSelectItem := @lstFavSelect;
lstFav.OnDblClick := @lstFavDblClick; lstFav.OnDblClick := @lstFavDblClick;
Tree.OnClick := @treeClick; lstFilter.BorderSpacing.Left := ScaleX(182, 96);
Tree.OnChange := @treeChanged;
Tree.OnDeletion := @treeDeletion;
Tree.OnSelectionChanged := @treeSelectionChanged;
Tree.OnExpanding := @treeExpanding;
lstFilter.FilteredListbox := nil;
lstFilter.onChange := @lstFilterChange;
lstFilter.BorderSpacing.Left := ScaleX(116, 96);
treeSetRoots; treeSetRoots;
@ -337,18 +365,12 @@ begin
finally finally
free; free;
end; end;
//
fEditableOptions.Free; fEditableOptions.Free;
fFavorites.Free; fFavorites.Free;
inherited; inherited;
end; end;
procedure TCEMiniExplorerWidget.lstDeletion(Sender: TObject; Item: TListItem);
begin
if Item.Data.isNotNil then
DisposeStr(PString(Item.Data));
end;
procedure TCEMiniExplorerWidget.setToolBarFlat(value: boolean); procedure TCEMiniExplorerWidget.setToolBarFlat(value: boolean);
begin begin
inherited setToolBarFlat(value); inherited setToolBarFlat(value);
@ -383,7 +405,7 @@ begin
else if fFreeProj = project then else if fFreeProj = project then
fFreeProj := nil; fFreeProj := nil;
if visible and project.fileName.fileExists and fContextExpand then if visible and project.fileName.fileExists and fContextExpand then
expandPath(project.fileName.extractFilePath); browse(project.fileName);
end; end;
procedure TCEMiniExplorerWidget.projCompiling(project: ICECommonProject); procedure TCEMiniExplorerWidget.projCompiling(project: ICECommonProject);
@ -403,7 +425,7 @@ end;
procedure TCEMiniExplorerWidget.docFocused(document: TCESynMemo); procedure TCEMiniExplorerWidget.docFocused(document: TCESynMemo);
begin begin
if visible and document.fileName.fileExists and fContextExpand then if visible and document.fileName.fileExists and fContextExpand then
expandPath(document.fileName.extractFilePath); browse(document.fileName);
end; end;
procedure TCEMiniExplorerWidget.docChanged(document: TCESynMemo); procedure TCEMiniExplorerWidget.docChanged(document: TCESynMemo);
@ -440,18 +462,17 @@ end;
procedure TCEMiniExplorerWidget.lstFavSelect(Sender: TObject; Item: TListItem; Selected: Boolean); procedure TCEMiniExplorerWidget.lstFavSelect(Sender: TObject; Item: TListItem; Selected: Boolean);
var var
lst: TStringList; d: string;
begin begin
if not Selected then exit; if not Selected or Item.Data.isNil then
// exit;
fLastFold := PString(Item.Data)^; d := PString(Item.Data)^;
lst := TStringList.Create; if d.dirExists then
try browse(d)
lstFiles.Items.Clear; else if dlgYesNo('The favorite folder `' + d + '` does not exist. ' +
listFiles(lst, fLastFold); 'Remove from the list ?') = mrYes then
fillLstFiles(lst); begin
finally fFavorites.Delete(item.Index);
lst.Free;
end; end;
end; end;
@ -459,12 +480,25 @@ procedure TCEMiniExplorerWidget.btnRemFavClick(Sender: TObject);
var var
i: Integer; i: Integer;
begin begin
if lstFav.Selected.isNil then exit; if lstFav.Selected.isNil then
exit;
i := fFavorites.IndexOf(PString(lstFav.Selected.Data)^); i := fFavorites.IndexOf(PString(lstFav.Selected.Data)^);
if i <> -1 then fFavorites.Delete(i); if i <> -1 then
fFavorites.Delete(i);
lstFiles.Clear; lstFiles.Clear;
end; end;
procedure TCEMiniExplorerWidget.lstFavDeletion(Sender: TObject; Item: TListItem);
begin
if Item.isNotNil and item.Data.isNotNil then
dispose(PString(item.Data));
end;
procedure TCEMiniExplorerWidget.lstFavEdited(Sender: TObject; Item: TListItem;
var AValue: string);
begin
end;
procedure TCEMiniExplorerWidget.lstFavEnter(Sender: TObject); procedure TCEMiniExplorerWidget.lstFavEnter(Sender: TObject);
begin begin
fLastListOrTree := lstFav; fLastListOrTree := lstFav;
@ -472,45 +506,45 @@ end;
procedure TCEMiniExplorerWidget.btnAddFavClick(Sender: TObject); procedure TCEMiniExplorerWidget.btnAddFavClick(Sender: TObject);
begin begin
if Tree.Selected.isNil then exit; if treeFolders.Selected.isNil then
fFavorites.Add(PString(Tree.Selected.Data)^); exit;
fFavorites.Add(treeFolders.GetPathFromNode(treeFolders.Selected).extractFileDir);
end; end;
procedure TCEMiniExplorerWidget.lstFavDblClick(Sender: TObject); procedure TCEMiniExplorerWidget.lstFavDblClick(Sender: TObject);
begin begin
if lstFav.Selected.isNil then exit; if lstFav.Selected.isNil then
lstFiles.Items.Clear; exit;
expandPath(lstFav.Selected.Caption); treeFolders.Root := lstFav.Selected.Caption;
tree.MakeSelectionVisible;
end; end;
{$ENDREGION}
{$REGION Files -----------------------------------------------------------------} procedure TCEMiniExplorerWidget.filterFiles;
procedure TCEMiniExplorerWidget.fillLstFiles(const aList: TStrings);
var var
itm: TListItem; s: string;
fname, itemText: string; i: integer;
dat: PString;
noFilter: boolean;
begin begin
noFilter := lstFilter.Filter = '';
lstFiles.Clear; // getting the full list is not possible once no item anymore
// e.g after filtering failed
treeFolders.BeginUpdate;
s := treeFolders.Root;
treeFolders.Root:= '';
treeFolders.Root:= s;
treeFolders.EndUpdate;
if lstFilter.filter.isEmpty then
exit;
lstFiles.BeginUpdate; lstFiles.BeginUpdate;
for fname in aList do for i:= lstFiles.Items.Count-1 downto 0 do
begin if not AnsicontainsText(lstfiles.Items[i].Caption,lstFilter.Filter) then
itemText := fname.extractFileName; lstfiles.Items.Delete(i);
if noFilter or AnsiContainsText(itemText,lstFilter.Filter) then
begin
itm := lstFiles.Items.Add;
itm.Caption := itemText;
dat := NewStr(fname);
itm.Data := dat;
itm.ImageIndex := 0;
end;
end;
lstFiles.EndUpdate; lstFiles.EndUpdate;
end; end;
{$ENDREGION}
{$REGION Files -----------------------------------------------------------------}
procedure TCEMiniExplorerWidget.btnShellOpenClick(Sender: TObject); procedure TCEMiniExplorerWidget.btnShellOpenClick(Sender: TObject);
begin begin
shellOpenSelected; shellOpenSelected;
@ -521,13 +555,11 @@ var
fname: string; fname: string;
fmt: TCEProjectFileFormat; fmt: TCEProjectFileFormat;
begin begin
if lstFiles.Selected.isNil then exit; if lstFiles.Selected.isNil then
if lstFiles.Selected.Data.isNil then exit; exit;
fname := PString(lstFiles.Selected.Data)^; fname := lstFiles.GetPathFromItem(lstFiles.Selected);
if not fname.fileExists then exit; if not fname.fileExists then
{$IFNDEF WINDOWS} exit;
fname := fname[2..fname.length];
{$ENDIF}
fmt := projectFormat(fname); fmt := projectFormat(fname);
if fmt in [pffCe, pffDub] then if fmt in [pffCe, pffDub] then
begin begin
@ -547,6 +579,20 @@ begin
else getMultiDocHandler.openDocument(fname); else getMultiDocHandler.openDocument(fname);
end; end;
procedure TCEMiniExplorerWidget.btnDriveClick(Sender: TObject);
begin
mnuDriveSelect(nil);
end;
procedure TCEMiniExplorerWidget.btnParentFolderClick(Sender: TObject);
var
p: string;
begin
p := treeFolders.Root.extractFileDir;
if p.dirExists then
treeFolders.Root := p;
end;
procedure TCEMiniExplorerWidget.lstFilesDblClick(Sender: TObject); procedure TCEMiniExplorerWidget.lstFilesDblClick(Sender: TObject);
begin begin
case fDblClick of case fDblClick of
@ -566,191 +612,121 @@ begin
end; end;
procedure TCEMiniExplorerWidget.lstFilterButtonClick(Sender: TObject);
var
s: string;
begin
s := treeFolders.Root;
treeFolders.Root:= '';
treeFolders.Root:= s;
end;
procedure TCEMiniExplorerWidget.lstFilterKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
filterFiles;
end;
procedure TCEMiniExplorerWidget.shellOpenSelected; procedure TCEMiniExplorerWidget.shellOpenSelected;
var var
fname: string = ''; fname: string = '';
begin begin
if fLastListOrTree = lstFiles then if fLastListOrTree = lstFiles then
begin begin
if lstFiles.Selected.isNil then exit; if lstFiles.Selected.isNil then
if lstFiles.Selected.data.isNil then exit; exit;
fname := PString(lstFiles.Selected.Data)^; fname := lstFiles.GetPathFromItem(lstFiles.Selected);
end else if fLastListOrTree = Tree then end else if fLastListOrTree = treeFolders then
begin begin
if tree.Selected.isNil then exit; if treeFolders.Selected.isNil then
if tree.Selected.Data.isNil then exit; exit;
fname := PString(tree.Selected.Data)^; fname := treeFolders.GetPathFromNode(treeFolders.Selected).extractFileDir;
end end
else if fLastListOrTree = lstFav then else if fLastListOrTree = lstFav then
begin begin
if lstFav.Selected.isNil then exit; if lstFav.Selected.isNil or lstFav.Selected.Data.isNil then
if lstFav.Selected.Data.isNil then exit; exit;
fname := PString(lstFav.Selected.Data)^; fname := PString(lstFav.Selected.Data)^;
end; end;
if (fname.fileExists or fname.dirExists) and not shellOpen(fname) then if (fname.fileExists or fname.dirExists) and not shellOpen(fname) then
getMessageDisplay.message((format('the shell failed to open "%s"', getMessageDisplay.message((format('the shell failed to open "%s"',
[shortenPath(fname, 25)])), nil, amcMisc, amkErr); [shortenPath(fname, 25)])), nil, amcMisc, amkErr);
end; end;
procedure TCEMiniExplorerWidget.lstFilterChange(sender: TObject);
begin
lstFilesFromTree;
end;
{$ENDREGION} {$ENDREGION}
{$REGION Tree ------------------------------------------------------------------} {$REGION Tree ------------------------------------------------------------------}
procedure TCEMiniExplorerWidget.TreeEnter(Sender: TObject); procedure TCEMiniExplorerWidget.TreeEnter(Sender: TObject);
begin begin
fLastListOrTree := Tree; fLastListOrTree := treeFolders;
end; end;
procedure TCEMiniExplorerWidget.treeDeletion(Sender: TObject; Item: TTreeNode); procedure TCEMiniExplorerWidget.treeFoldersChange(Sender: TObject;
Node: TTreeNode);
begin begin
if Item.Data.isNotNil then if treeFolders.Selected.isNil then
DisposeStr(PString(Item.Data)); exit;
fLastFold := treeFolders.Path.extractFileDir; // trailing path sep
end;
procedure TCEMiniExplorerWidget.treeFoldersDblClick(Sender: TObject);
begin
if treeFolders.Selected.isNil then
exit;
treeFolders.Root := treeFolders.GetPathFromNode(treeFolders.Selected)
.extractFileDir; // trailing path sep
end;
procedure TCEMiniExplorerWidget.treeFoldersGetImageIndex(Sender: TObject;
Node: TTreeNode);
begin
Node.ImageIndex:=1;
Node.SelectedIndex:=1;
end;
procedure TCEMiniExplorerWidget.treeFoldersGetSelectedIndex(Sender: TObject;
Node: TTreeNode);
begin
Node.ImageIndex:=1;
end; end;
procedure TCEMiniExplorerWidget.treeSetRoots; procedure TCEMiniExplorerWidget.treeSetRoots;
var var
drv: string; m: TMenuItem;
itm: TTreeNode; d: TStringList;
lst: TStringList; i: integer;
begin begin
Tree.Items.Clear; d := TStringList.Create;
lst := TStringList.Create;
try try
listDrives(lst); listDrives(d);
for drv in lst do for i := 0 to d.Count-1 do
begin begin
itm := Tree.Items.Add(nil, drv); m := TMenuItem.Create(self);
itm.Data := NewStr(drv[1..drv.length-1]); m.Caption := d[i];
treeScanSubFolders(itm); m.OnClick := @mnuDriveItemClick;
mnuDrives.Items.Add(m);
if i = 0 then
treeFolders.Root:= m.Caption;
end; end;
m := Tmenuitem.Create(self);
m.Caption:= 'Select a custom location...';
m.OnClick:=@mnuDriveSelect;
mnuDrives.Items.Add(m);
finally finally
lst.Free; d.Free;
end; end;
end; end;
procedure TCEMiniExplorerWidget.lstFilesFromTree; procedure TCEMiniExplorerWidget.mnuDriveItemClick(sender: TObject);
begin
treeFolders.Root := TMenuItem(sender).Caption;
end;
procedure TCEMiniExplorerWidget.mnuDriveSelect(sender: TObject);
var var
lst: TStringList; d: string;
pth: string;
begin begin
if Tree.Selected.isNil then exit; if SelectDirectory('Select the new tree root', '', d) then
// treeFolders.Root:=d;
lst := TStringList.Create;
try
pth := PString(Tree.Selected.Data)^;
fLastFold := pth;
listFiles(lst, pth);
lst.Sort;
fillLstFiles(lst);
finally
lst.Free;
end;
end;
procedure TCEMiniExplorerWidget.treeScanSubFolders(aRoot: TTreeNode);
var
lst: TStringList;
fold: string;
itm: TTreeNode;
begin
aRoot.DeleteChildren; // delete the fake item...
lst := TStringList.Create;
try
listFolders(lst, PString(aRoot.Data)^ + directorySeparator);
lst.Sort;
for fold in lst do
begin
itm := Tree.Items.AddChild(aRoot, fold.extractFileName);
itm.Data := NewStr(fold);
itm.ImageIndex := 1;
itm.SelectedIndex := 1;
//
if hasFolder(fold) then
Tree.Items.AddChild(itm, ''); //...created here to show the expander glyph
end;
finally
lst.Free;
end;
end;
procedure TCEMiniExplorerWidget.treeExpanding(Sender: TObject; Node: TTreeNode; var allow: boolean);
begin
if Node.isNotNil then
treeScanSubFolders(Node);
allow := true;
end;
procedure TCEMiniExplorerWidget.treeChanged(Sender: TObject; Node: TTreeNode);
begin
if Node.isNil then exit;
Node.DeleteChildren;
treeScanSubFolders(Node);
lstFilesFromTree;
end;
procedure TCEMiniExplorerWidget.treeSelectionChanged(sender: TObject);
begin
lstFilesFromTree;
end;
procedure TCEMiniExplorerWidget.treeClick(sender: TObject);
begin
if Tree.Selected.isNil then exit;
if Tree.Selected.Expanded then exit;
treeScanSubFolders(Tree.Selected);
end;
procedure TCEMiniExplorerWidget.expandPath(aPath: string);
var
i: NativeInt;
node : TTreeNode;
function dig(const aRoot: TTreenode): boolean;
var
i: NativeInt;
str: string;
begin
result := false;
{$IFNDEF WINDOWS}
if (aPath.length >= 2) and (aPath[2] <> '/') then
aPath := '/' + aPath;
{$ENDIF}
for i := 0 to aRoot.Count-1 do
begin
if aRoot.Items[i].Data.isNil then
continue;
str := PString(aRoot.Items[i].Data)^;
if SameText(LeftStr(aPath, str.length), str) then
begin
result := true;
Tree.Selected := aRoot.Items[i];
Tree.Selected.Expand(false);
//
if str = aPath then
break
else if dig(Tree.Selected) then
begin
Tree.Selected.MakeVisible;
break;
end;
end;
end;
end;
begin
for i := 0 to Tree.Items.Count-1 do
begin
node := Tree.Items[i];
if node.Level = 0 then
begin
node.Selected := true;
node.Expand(false);
end;
if dig(node) then break;
end;
fLastListOrTree := Tree;
showWidget;
end; end;
{$ENDREGION} {$ENDREGION}
@ -762,15 +738,18 @@ end;
procedure TCEMiniExplorerWidget.browse(const location: string); procedure TCEMiniExplorerWidget.browse(const location: string);
begin begin
expandPath(location); if location.EndsWith('\') or location.EndsWith('/') then
treeFolders.Root := location[1..location.length]
else if location.fileExists then
treeFolders.Root := location.extractFileDir
else if location.dirExists then
treeFolders.Root := location;
fLastFold:=treeFolders.Root;
end; end;
function TCEMiniExplorerWidget.currentLocation: string; function TCEMiniExplorerWidget.currentLocation: string;
begin begin
if Tree.Selected.isNil then result := treeFolders.path.extractFilePath;
result := ''
else
result := PString(tree.Selected.Data)^;
end; end;
{$ENDREGION} {$ENDREGION}