mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-28 10:02:14 +00:00
UPD: Move some common code to separate class for views that have a main control with a filelist.
This commit is contained in:
parent
fbfa3f0b37
commit
4fff67e5fb
6 changed files with 1501 additions and 2375 deletions
|
|
@ -7,9 +7,9 @@ interface
|
|||
uses
|
||||
LMessages, Grids, uFileView, uFileSource, Graphics,
|
||||
Classes, SysUtils, Controls, ExtCtrls, ComCtrls, contnrs, fgl,
|
||||
uFile, uDisplayFile, uFormCommands, uDragDropEx, DCXmlConfig,
|
||||
uFile, uDisplayFile, uFormCommands, DCXmlConfig,
|
||||
DCClassesUtf8, uFileSorting, uFileViewHistory, uFileProperty, uFileViewWorker,
|
||||
uFunctionThread, uFileSystemWatcher, fQuickSearch, uTypes, uOrderedFileView,
|
||||
uFunctionThread, uFileSystemWatcher, uTypes, uFileViewWithMainCtrl,
|
||||
uFileViewHeader;
|
||||
|
||||
type
|
||||
|
|
@ -29,6 +29,8 @@ type
|
|||
procedure Resize; override;
|
||||
procedure RowHeightsChanged; override;
|
||||
procedure ColWidthsChanged; override;
|
||||
procedure FinalizeWnd; override;
|
||||
procedure InitializeWnd; override;
|
||||
function MouseOnGrid(X, Y: LongInt): Boolean;
|
||||
function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
|
||||
function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
|
||||
|
|
@ -43,7 +45,7 @@ type
|
|||
|
||||
{ TBriefFileView }
|
||||
|
||||
TBriefFileView = class (TOrderedFileView)
|
||||
TBriefFileView = class (TFileViewWithMainCtrl)
|
||||
private
|
||||
TabHeader: THeaderControl;
|
||||
dgPanel: TBriefDrawGrid;
|
||||
|
|
@ -51,9 +53,6 @@ type
|
|||
procedure MakeColumnsStrings(AFile: TDisplayFile);
|
||||
procedure SetFilesDisplayItems;
|
||||
|
||||
procedure dgPanelEnter(Sender: TObject);
|
||||
procedure dgPanelExit(Sender: TObject);
|
||||
procedure dgPanelDblClick(Sender: TObject);
|
||||
procedure dgPanelTopLeftChanged(Sender: TObject);
|
||||
procedure TabHeaderSectionClick(HeaderControl: TCustomHeaderControl;
|
||||
Section: THeaderSection);
|
||||
|
|
@ -62,7 +61,10 @@ type
|
|||
procedure BeforeMakeFileList; override;
|
||||
procedure AfterMakeFileList; override;
|
||||
procedure AfterChangePath; override;
|
||||
procedure DoMainControlShowHint(FileIndex: PtrInt; X, Y: Integer); override;
|
||||
function GetActiveFileIndex: PtrInt; override;
|
||||
function GetFileIndexFromCursor(X, Y: Integer; out AtFileList: Boolean): PtrInt; override;
|
||||
function GetFileRect(FileIndex: PtrInt): TRect; override;
|
||||
function GetVisibleFilesIndexes: TRange; override;
|
||||
procedure RedrawFile(FileIndex: PtrInt); override;
|
||||
procedure RedrawFile(DisplayFile: TDisplayFile); override;
|
||||
|
|
@ -78,39 +80,21 @@ type
|
|||
procedure AddFileSource(aFileSource: IFileSource; aPath: String); override;
|
||||
|
||||
procedure SaveConfiguration(AConfig: TXmlConfig; ANode: TXmlNode); override;
|
||||
|
||||
{en
|
||||
Handles drag&drop operations onto the file view.
|
||||
Does any graphic work and executes operations with dropped files if allowed.
|
||||
Handles freeing DropParams.
|
||||
}
|
||||
procedure DoDragDropOperation(Operation: TDragDropOperation;
|
||||
var DropParams: TDropParams); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
LCLIntf, LCLType, Forms,
|
||||
LCLProc, uMasks, Clipbrd, uLng, uShowMsg, uGlobs, uPixmapManager, uDebug,
|
||||
LCLProc, Clipbrd, uLng, uShowMsg, uGlobs, uPixmapManager, uDebug,
|
||||
uDCUtils, uOSUtils, math, fMain, fMaskInputDlg, uSearchTemplate,
|
||||
uInfoToolTip, dmCommonData,
|
||||
dmCommonData,
|
||||
uFileSourceProperty,
|
||||
uFileSourceOperationTypes,
|
||||
uFileSystemFileSource,
|
||||
fColumnsSetConf,
|
||||
uKeyboard,
|
||||
uFileSourceUtil,
|
||||
uFileFunctions
|
||||
{$IF DEFINED(LCLGTK)}
|
||||
, GtkProc // for ReleaseMouseCapture
|
||||
, GTKGlobals // for DblClickTime
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(LCLGTK2)}
|
||||
, Gtk2Proc // for ReleaseMouseCapture
|
||||
, GTK2Globals // for DblClickTime
|
||||
{$ENDIF}
|
||||
;
|
||||
uFileFunctions;
|
||||
|
||||
{ TBriefDrawGrid }
|
||||
|
||||
|
|
@ -157,6 +141,12 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TBriefDrawGrid.InitializeWnd;
|
||||
begin
|
||||
inherited InitializeWnd;
|
||||
BriefView.InitializeDragDropEx(Self);
|
||||
end;
|
||||
|
||||
procedure TBriefDrawGrid.UpdateView;
|
||||
|
||||
function CalculateDefaultRowHeight: Integer;
|
||||
|
|
@ -193,8 +183,6 @@ var
|
|||
TempRowHeight: Integer;
|
||||
begin
|
||||
Flat := gInterfaceFlat;
|
||||
Color := BriefView.DimColor(gBackColor);
|
||||
ShowHint:= (gShowToolTipMode <> []);
|
||||
|
||||
// Calculate row height.
|
||||
TempRowHeight := CalculateDefaultRowHeight;
|
||||
|
|
@ -290,7 +278,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
end;
|
||||
BriefView.DoHandleKeyDown(Key, Shift);
|
||||
inherited KeyDown(Key, Shift);
|
||||
end;
|
||||
|
||||
|
|
@ -480,6 +467,12 @@ begin
|
|||
DrawLines;
|
||||
end;
|
||||
|
||||
procedure TBriefDrawGrid.FinalizeWnd;
|
||||
begin
|
||||
BriefView.FinalizeDragDropEx(Self);
|
||||
inherited FinalizeWnd;
|
||||
end;
|
||||
|
||||
{ TBriefFileView }
|
||||
|
||||
function TBriefFileView.GetVisibleFilesIndexes: TRange; {Done}
|
||||
|
|
@ -517,40 +510,6 @@ begin
|
|||
dgPanel.InvalidateCell(ACol, ARow);
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.dgPanelEnter(Sender: TObject);
|
||||
begin
|
||||
SetActive(True);
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.dgPanelExit(Sender: TObject);
|
||||
begin
|
||||
SetActive(False);
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.dgPanelDblClick(Sender: TObject);
|
||||
var
|
||||
Point : TPoint;
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
// Workaround for two doubleclicks being sent on GTK.
|
||||
// if dgPanel.TooManyDoubleClicks then Exit;
|
||||
{$ENDIF}
|
||||
|
||||
// dgPanel.StartDrag:= False; // don't start drag on double click
|
||||
Point:= dgPanel.ScreenToClient(Mouse.CursorPos);
|
||||
|
||||
// If on a file/directory then choose it.
|
||||
if (Point.Y >= 0) and
|
||||
(Point.Y < dgPanel.GridHeight) then
|
||||
begin
|
||||
ChooseFile(GetActiveDisplayFile);
|
||||
end;
|
||||
|
||||
{$IFDEF LCLGTK2}
|
||||
// dgPanel.fLastDoubleClickTime := Now;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.dgPanelTopLeftChanged(Sender: TObject);
|
||||
begin
|
||||
EnsureDisplayProperties;
|
||||
|
|
@ -566,10 +525,7 @@ procedure TBriefFileView.CreateDefault(AOwner: TWinControl);
|
|||
begin
|
||||
inherited CreateDefault(AOwner);
|
||||
dgPanel:= TBriefDrawGrid.Create(Self, Self);
|
||||
|
||||
HotMan.Register(dgPanel, 'Files Panel');
|
||||
|
||||
Align:= alClient;
|
||||
MainControl := dgPanel;
|
||||
|
||||
TabHeader:= TBriefHeaderControl.Create(Self);
|
||||
TabHeader.Parent:= Self;
|
||||
|
|
@ -582,9 +538,6 @@ begin
|
|||
TabHeader.OnSectionClick:= @TabHeaderSectionClick;
|
||||
|
||||
dgPanel.OnTopLeftChanged:= @dgPanelTopLeftChanged;
|
||||
dgPanel.OnDblClick:=@dgPanelDblClick;
|
||||
dgPanel.OnEnter:=@dgPanelEnter;
|
||||
dgPanel.OnExit:=@dgPanelExit;
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.BeforeMakeFileList;
|
||||
|
|
@ -614,6 +567,30 @@ begin
|
|||
Result := dgPanel.CellToIndex(dgPanel.Col, dgPanel.Row);
|
||||
end;
|
||||
|
||||
function TBriefFileView.GetFileIndexFromCursor(X, Y: Integer; out AtFileList: Boolean): PtrInt;
|
||||
var
|
||||
bTemp: Boolean;
|
||||
iRow, iCol: LongInt;
|
||||
begin
|
||||
with dgPanel do
|
||||
begin
|
||||
bTemp:= AllowOutboundEvents;
|
||||
AllowOutboundEvents:= False;
|
||||
MouseToCell(X, Y, iCol, iRow);
|
||||
AllowOutboundEvents:= bTemp;
|
||||
Result:= CellToIndex(iCol, iRow);
|
||||
AtFileList := True; // Always at file list because header in dgPanel not used
|
||||
end;
|
||||
end;
|
||||
|
||||
function TBriefFileView.GetFileRect(FileIndex: PtrInt): TRect;
|
||||
var
|
||||
ACol, ARow: Integer;
|
||||
begin
|
||||
dgPanel.IndexToCell(FileIndex, ACol, ARow);
|
||||
Result := dgPanel.CellRect(ACol, ARow);
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.Resize;
|
||||
var
|
||||
I: Integer;
|
||||
|
|
@ -637,9 +614,6 @@ end;
|
|||
|
||||
destructor TBriefFileView.Destroy;
|
||||
begin
|
||||
if Assigned(HotMan) then
|
||||
HotMan.UnRegister(dgPanel);
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
|
@ -677,17 +651,31 @@ begin
|
|||
dgPanel.UpdateView;
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.DoDragDropOperation(Operation: TDragDropOperation;
|
||||
var DropParams: TDropParams);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.DoFileUpdated(AFile: TDisplayFile; UpdatedProperties: TFilePropertiesTypes);
|
||||
begin
|
||||
MakeColumnsStrings(AFile);
|
||||
inherited DoFileUpdated(AFile, UpdatedProperties);
|
||||
end;
|
||||
|
||||
procedure TBriefFileView.DoMainControlShowHint(FileIndex: PtrInt; X, Y: Integer);
|
||||
var
|
||||
aRect: TRect;
|
||||
ACol, ARow, iCol: Integer;
|
||||
AFile: TDisplayFile;
|
||||
begin
|
||||
AFile := FFiles[FileIndex];
|
||||
dgPanel.IndexToCell(FileIndex, ACol, ARow);
|
||||
aRect:= dgPanel.CellRect(ACol, ARow);
|
||||
iCol:= aRect.Right - aRect.Left - 8;
|
||||
if gShowIcons <> sim_none then
|
||||
Dec(iCol, gIconsSize);
|
||||
if iCol < dgPanel.Canvas.TextWidth(AFile.FSFile.Name) then // with file name
|
||||
dgPanel.Hint:= AFile.FSFile.Name
|
||||
else if (stm_only_large_name in gShowToolTipMode) then // don't show
|
||||
Exit
|
||||
else if not AFile.FSFile.IsDirectory then // without name
|
||||
dgPanel.Hint:= #32;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -564,7 +564,9 @@ begin
|
|||
FReloadTimer.Enabled := False;
|
||||
FReloadTimer.OnTimer := @ReloadTimerEvent;
|
||||
|
||||
BorderStyle := bsNone; // Before Create or the window handle may be recreated
|
||||
inherited Create(AOwner);
|
||||
Align := alClient;
|
||||
Parent := AOwner;
|
||||
|
||||
if Parent is TFileViewPage then
|
||||
|
|
|
|||
985
src/newdesign/ufileviewwithmainctrl.pas
Normal file
985
src/newdesign/ufileviewwithmainctrl.pas
Normal file
|
|
@ -0,0 +1,985 @@
|
|||
{
|
||||
Double Commander
|
||||
-------------------------------------------------------------------------
|
||||
Base class for file views which have a main control with a list of files.
|
||||
|
||||
Copyright (C) 2012 Przemyslaw Nagay (cobines@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
}
|
||||
|
||||
unit uFileViewWithMainCtrl;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Controls, ExtCtrls, LCLType,
|
||||
uFileViewWorker,
|
||||
uOrderedFileView,
|
||||
uFileView,
|
||||
uDragDropEx;
|
||||
|
||||
type
|
||||
|
||||
{ TFileViewWithMainCtrl }
|
||||
|
||||
TFileViewWithMainCtrl = class(TOrderedFileView)
|
||||
private
|
||||
FMainControl: TWinControl;
|
||||
{$IFDEF LCLGTK2}
|
||||
FLastDoubleClickTime : TDateTime;
|
||||
function TooManyDoubleClicks: Boolean;
|
||||
{$ENDIF}
|
||||
|
||||
{ Events for drag&drop from external applications }
|
||||
function OnExDragBegin: Boolean;
|
||||
function OnExDragEnd: Boolean;
|
||||
function OnExDragEnter(var DropEffect: TDropEffect; ScreenPoint: TPoint): Boolean;
|
||||
function OnExDragOver(var DropEffect: TDropEffect; ScreenPoint: TPoint): Boolean;
|
||||
function OnExDrop(const FileNamesList: TStringList; DropEffect: TDropEffect; ScreenPoint: TPoint): Boolean;
|
||||
function OnExDragLeave: Boolean;
|
||||
|
||||
procedure SetMainControl(AValue: TWinControl);
|
||||
procedure tmContextMenuTimer(Sender: TObject);
|
||||
// If internal dragging is currently in effect, this function
|
||||
// stops internal dragging and starts external.
|
||||
procedure TransformDraggingToExternal(ScreenPoint: TPoint);
|
||||
|
||||
protected
|
||||
// Used to register as a drag and drop source and target.
|
||||
FDragDropSource: uDragDropEx.TDragDropSource;
|
||||
FDragDropTarget: uDragDropEx.TDragDropTarget;
|
||||
FHintFileIndex: PtrInt;
|
||||
FMainControlLastMouseButton: TMouseButton; // Mouse button that initiated dragging
|
||||
{en
|
||||
Used to check if button-up was received after button-down
|
||||
or after dropping something after dragging with right mouse button.
|
||||
}
|
||||
FMainControlMouseDown: Boolean;
|
||||
FMouseSelectionStartIndex: Integer;
|
||||
FDragStartPoint: TPoint;
|
||||
FDragFileIndex: PtrInt;
|
||||
FDropFileIndex: PtrInt;
|
||||
FStartDrag: Boolean;
|
||||
tmContextMenu: TTimer;
|
||||
// Simulates releasing mouse button that started a dragging operation,
|
||||
// but was released in another window or another application.
|
||||
procedure ClearAfterDragDrop; virtual;
|
||||
procedure CreateDefault(AOwner: TWinControl); override;
|
||||
procedure DoMainControlShowHint(FileIndex: PtrInt; X, Y: Integer); virtual; abstract;
|
||||
procedure DoUpdateView; override;
|
||||
procedure FinalizeDragDropEx(AControl: TWinControl);
|
||||
{en
|
||||
Retrieves file index under mouse cursor.
|
||||
@param(X, Y
|
||||
Should be client coordinates of MainControl.)
|
||||
@param(AtFileList
|
||||
Whether X, Y point to the filelist, not at specific file but at empty space.
|
||||
If AtFileList is @false then X, Y point somewhere outside the file list.)
|
||||
}
|
||||
function GetFileIndexFromCursor(X, Y: Integer; out AtFileList: Boolean): PtrInt; virtual; abstract;
|
||||
procedure InitializeDragDropEx(AControl: TWinControl);
|
||||
procedure MainControlDblClick(Sender: TObject);
|
||||
procedure MainControlDragDrop(Sender, Source: TObject; X, Y: Integer);
|
||||
procedure MainControlDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
||||
procedure MainControlEndDrag(Sender, Target: TObject; X, Y: Integer);
|
||||
procedure MainControlEnter(Sender: TObject);
|
||||
procedure MainControlExit(Sender: TObject);
|
||||
procedure MainControlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure MainControlKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
procedure MainControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
procedure MainControlMouseLeave(Sender: TObject);
|
||||
procedure MainControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
|
||||
procedure MainControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
procedure MainControlShowHint(Sender: TObject; HintInfo: PHintInfo);
|
||||
procedure MainControlUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
|
||||
{en
|
||||
Changes drawing colors depending on if this panel is active.
|
||||
}
|
||||
procedure SetActive(bActive: Boolean); override;
|
||||
{en
|
||||
Updates the drop row index, which is used to draw a rectangle
|
||||
on directories during drag&drop operations.
|
||||
}
|
||||
procedure SetDropFileIndex(NewFileIndex: PtrInt);
|
||||
procedure WorkerStarting(const Worker: TFileViewWorker); override;
|
||||
procedure WorkerFinished(const Worker: TFileViewWorker); override;
|
||||
property MainControl: TWinControl read FMainControl write SetMainControl;
|
||||
|
||||
public
|
||||
destructor Destroy; override;
|
||||
procedure DoDragDropOperation(Operation: TDragDropOperation;
|
||||
var DropParams: TDropParams); override;
|
||||
function Focused: Boolean; override;
|
||||
procedure SetFocus; override;
|
||||
|
||||
published
|
||||
procedure cm_ContextMenu(const Params: array of string);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
{$IF DEFINED(LCLGTK2)}
|
||||
Gtk2Proc, // for ReleaseMouseCapture
|
||||
GTK2Globals, // for DblClickTime
|
||||
{$ENDIF}
|
||||
{$IFDEF MSWINDOWS}
|
||||
LCLIntf,
|
||||
{$ENDIF}
|
||||
Forms,
|
||||
fMain,
|
||||
uGlobs, uInfoToolTip, uDisplayFile, uFile, uFileSystemFileSource;
|
||||
|
||||
type
|
||||
TControlHandlersHack = class(TWinControl)
|
||||
end;
|
||||
|
||||
{ TFileViewWithMainCtrl }
|
||||
|
||||
procedure TFileViewWithMainCtrl.ClearAfterDragDrop;
|
||||
begin
|
||||
// Clear some control specific flags.
|
||||
MainControl.ControlState := MainControl.ControlState - [csClicked, csLButtonDown];
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.cm_ContextMenu(const Params: array of string);
|
||||
var
|
||||
Rect: TRect;
|
||||
Point: TPoint;
|
||||
begin
|
||||
Rect := GetFileRect(GetActiveFileIndex);
|
||||
Point.X := Rect.Left + ((Rect.Right - Rect.Left) div 2);
|
||||
Point.Y := Rect.Top + ((Rect.Bottom - Rect.Top) div 2);
|
||||
Point := MainControl.ClientToScreen(Point);
|
||||
frmMain.Commands.DoContextMenu(Self, Point.X, Point.Y, False);
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.CreateDefault(AOwner: TWinControl);
|
||||
begin
|
||||
FDropFileIndex := -1;
|
||||
FHintFileIndex := -1;
|
||||
{$IFDEF LCLGTK2}
|
||||
FLastDoubleClickTime := Now;
|
||||
{$ENDIF}
|
||||
FStartDrag := False;
|
||||
|
||||
inherited CreateDefault(AOwner);
|
||||
|
||||
tmContextMenu := TTimer.Create(Self);
|
||||
tmContextMenu.Enabled := False;
|
||||
tmContextMenu.Interval := 500;
|
||||
tmContextMenu.OnTimer := @tmContextMenuTimer;
|
||||
end;
|
||||
|
||||
destructor TFileViewWithMainCtrl.Destroy;
|
||||
begin
|
||||
if Assigned(HotMan) then
|
||||
HotMan.UnRegister(MainControl);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.DoDragDropOperation(Operation: TDragDropOperation; var DropParams: TDropParams);
|
||||
var
|
||||
AFile: TDisplayFile;
|
||||
ClientDropPoint: TPoint;
|
||||
FileIndex: PtrInt;
|
||||
AtFileList: Boolean;
|
||||
begin
|
||||
try
|
||||
with DropParams do
|
||||
begin
|
||||
if Files.Count > 0 then
|
||||
begin
|
||||
ClientDropPoint := MainControl.ScreenToClient(ScreenDropPoint);
|
||||
FileIndex := GetFileIndexFromCursor(ClientDropPoint.X, ClientDropPoint.Y, AtFileList);
|
||||
|
||||
// default to current active directory in the destination panel
|
||||
TargetPath := Self.CurrentPath;
|
||||
|
||||
if (DropIntoDirectories = True) and IsFileIndexInRange(FileIndex) then
|
||||
begin
|
||||
AFile := FFiles[FileIndex];
|
||||
|
||||
// If dropped into a directory modify destination path accordingly.
|
||||
if Assigned(AFile) and
|
||||
(AFile.FSFile.IsDirectory or AFile.FSFile.IsLinkToDirectory) then
|
||||
begin
|
||||
if AFile.FSFile.Name = '..' then
|
||||
// remove the last subdirectory in the path
|
||||
TargetPath := TargetPanel.FileSource.GetParentDir(TargetPath)
|
||||
else
|
||||
TargetPath := TargetPath + AFile.FSFile.Name + DirectorySeparator;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Execute the operation.
|
||||
frmMain.DoDragDropOperation(Operation, DropParams);
|
||||
|
||||
finally
|
||||
FreeAndNil(DropParams);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.DoUpdateView;
|
||||
begin
|
||||
inherited DoUpdateView;
|
||||
MainControl.Color := DimColor(gBackColor);
|
||||
MainControl.ShowHint := (gShowToolTipMode <> []);
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.FinalizeDragDropEx(AControl: TWinControl);
|
||||
begin
|
||||
FreeAndNil(FDragDropSource);
|
||||
FreeAndNil(FDragDropTarget);
|
||||
end;
|
||||
|
||||
function TFileViewWithMainCtrl.Focused: Boolean;
|
||||
begin
|
||||
Result := Assigned(MainControl) and MainControl.Focused;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.InitializeDragDropEx(AControl: TWinControl);
|
||||
begin
|
||||
// Register as drag&drop source and target.
|
||||
FDragDropSource := uDragDropEx.CreateDragDropSource(AControl);
|
||||
if Assigned(FDragDropSource) then
|
||||
FDragDropSource.RegisterEvents(nil, nil, @OnExDragEnd);
|
||||
|
||||
FDragDropTarget := uDragDropEx.CreateDragDropTarget(AControl);
|
||||
if Assigned(FDragDropTarget) then
|
||||
FDragDropTarget.RegisterEvents(@OnExDragEnter, @OnExDragOver,
|
||||
@OnExDrop, @OnExDragLeave);
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlDblClick(Sender: TObject);
|
||||
var
|
||||
Point : TPoint;
|
||||
FileIndex : PtrInt;
|
||||
AtFileList: Boolean;
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
// Workaround for two doubleclicks being sent on GTK.
|
||||
if TooManyDoubleClicks then Exit;
|
||||
{$ENDIF}
|
||||
|
||||
FStartDrag := False; // don't start drag on double click
|
||||
Point := MainControl.ScreenToClient(Mouse.CursorPos);
|
||||
|
||||
// If on a file/directory then choose it.
|
||||
FileIndex := GetFileIndexFromCursor(Point.x, Point.y, AtFileList);
|
||||
if IsFileIndexInRange(FileIndex) then
|
||||
ChooseFile(FFiles[FileIndex]);
|
||||
|
||||
{$IFDEF LCLGTK2}
|
||||
FLastDoubleClickTime := Now;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlDragDrop(Sender, Source: TObject; X, Y: Integer);
|
||||
var
|
||||
SourcePanel: TFileViewWithMainCtrl;
|
||||
SourceFiles: TFiles;
|
||||
DropParams: TDropParams;
|
||||
begin
|
||||
if not (Source is TWinControl) or
|
||||
not (TWinControl(Source).Parent is TFileViewWithMainCtrl) then
|
||||
Exit;
|
||||
|
||||
SourcePanel := ((Source as TWinControl).Parent) as TFileViewWithMainCtrl;
|
||||
|
||||
// Get file names from source panel.
|
||||
SourceFiles := SourcePanel.CloneSelectedFiles;
|
||||
try
|
||||
// Drop onto target panel.
|
||||
DropParams := TDropParams.Create(
|
||||
SourceFiles, // Will be freed automatically.
|
||||
GetDropEffectByKeyAndMouse(GetKeyShiftState,
|
||||
SourcePanel.FMainControlLastMouseButton),
|
||||
MainControl.ClientToScreen(Classes.Point(X, Y)),
|
||||
True,
|
||||
SourcePanel,
|
||||
Self, Self.CurrentPath);
|
||||
|
||||
frmMain.DropFiles(DropParams);
|
||||
SetDropFileIndex(-1);
|
||||
except
|
||||
FreeAndNil(SourceFiles);
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
||||
var
|
||||
AFile: TDisplayFile;
|
||||
SourcePanel: TFileView;
|
||||
TargetPanel: TFileView;
|
||||
SourceDir, TargetDir: String;
|
||||
FileIndex: PtrInt;
|
||||
AtFileList: Boolean;
|
||||
begin
|
||||
Accept := False;
|
||||
|
||||
if not (Source is TWinControl) or
|
||||
not (TWinControl(Source).Parent is TFileView) then
|
||||
Exit;
|
||||
|
||||
SourcePanel := ((Source as TWinControl).Parent) as TFileView;
|
||||
TargetPanel := Self;
|
||||
|
||||
FileIndex := GetFileIndexFromCursor(X, Y, AtFileList);
|
||||
|
||||
// Always allow dropping into an empty panel.
|
||||
// And it is also allowed to drop onto header in case all visible items
|
||||
// are directories and the user wants to drop into panel's current directory.
|
||||
if FileIndex = InvalidFileIndex then
|
||||
begin
|
||||
SetDropFileIndex(-1);
|
||||
Accept := True;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
SourceDir := SourcePanel.CurrentPath;
|
||||
TargetDir := TargetPanel.CurrentPath;
|
||||
|
||||
AFile := FFiles[FileIndex];
|
||||
|
||||
if (AFile.FSFile.IsDirectory or AFile.FSFile.IsLinkToDirectory) then
|
||||
begin
|
||||
if State = dsDragLeave then
|
||||
// Mouse is leaving the control or drop will occur immediately.
|
||||
// Don't draw DropRow rectangle.
|
||||
SetDropFileIndex(-1)
|
||||
else
|
||||
SetDropFileIndex(FileIndex);
|
||||
|
||||
if Sender = Source then
|
||||
begin
|
||||
if not ((FileIndex = FDragFileIndex) or (AFile.Selected = True)) then
|
||||
Accept := True;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if Assigned(SourcePanel) and Assigned(TargetPanel) then
|
||||
begin
|
||||
if AFile.FSFile.Name = '..' then
|
||||
TargetDir := TargetPanel.FileSource.GetParentDir(TargetDir)
|
||||
else
|
||||
TargetDir := TargetDir + AFile.FSFile.Name + DirectorySeparator;
|
||||
|
||||
if SourceDir <> TargetDir then Accept := True;
|
||||
end
|
||||
else
|
||||
Accept := True;
|
||||
end;
|
||||
end
|
||||
else if (Sender <> Source) then
|
||||
begin
|
||||
SetDropFileIndex(-1);
|
||||
|
||||
if Assigned(SourcePanel) then
|
||||
begin
|
||||
if SourcePanel.CurrentPath <> TargetPanel.CurrentPath then
|
||||
Accept := True;
|
||||
end
|
||||
else
|
||||
Accept := True;
|
||||
end
|
||||
else
|
||||
begin
|
||||
SetDropFileIndex(-1);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlEndDrag(Sender, Target: TObject; X, Y: Integer);
|
||||
procedure ClearDropNode(aFileView: TFileView);
|
||||
begin
|
||||
if aFileView is TFileViewWithMainCtrl then
|
||||
TFileViewWithMainCtrl(aFileView).SetDropFileIndex(-1);
|
||||
end;
|
||||
begin
|
||||
// If cancelled by the user, DragManager does not send drag-leave event
|
||||
// to the target, so we must clear the DropRow in both panels.
|
||||
|
||||
ClearDropNode(frmMain.FrameLeft);
|
||||
ClearDropNode(frmMain.FrameRight);
|
||||
|
||||
if uDragDropEx.TransformDragging = False then
|
||||
ClearAfterDragDrop;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlEnter(Sender: TObject);
|
||||
begin
|
||||
SetActive(True);
|
||||
if Assigned(OnActivate) then
|
||||
OnActivate(Self);
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlExit(Sender: TObject);
|
||||
begin
|
||||
SetActive(False);
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
var
|
||||
ScreenPoint: TPoint;
|
||||
begin
|
||||
case Key of
|
||||
|
||||
VK_APPS:
|
||||
begin
|
||||
cm_ContextMenu([]);
|
||||
Key := 0;
|
||||
end;
|
||||
|
||||
VK_MENU: // Alt key
|
||||
if MainControl.Dragging then
|
||||
begin
|
||||
// Force transform to external dragging in anticipation of user
|
||||
// pressing Alt+Tab to change active application window.
|
||||
|
||||
// Disable flag, so that dragging isn't immediately transformed
|
||||
// back to internal before the other application window is shown.
|
||||
uDragDropEx.AllowTransformToInternal := False;
|
||||
|
||||
GetCursorPos(ScreenPoint);
|
||||
TransformDraggingToExternal(ScreenPoint);
|
||||
end;
|
||||
end;
|
||||
|
||||
DoHandleKeyDown(Key, Shift);
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
begin
|
||||
case Key of
|
||||
VK_SHIFT:
|
||||
FLastSelectionStartIndex := -1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
var
|
||||
FileIndex: PtrInt;
|
||||
AtFileList: Boolean;
|
||||
AFile, APreviousFile: TDisplayFile;
|
||||
begin
|
||||
FileIndex := GetFileIndexFromCursor(X, Y, AtFileList);
|
||||
if not AtFileList then
|
||||
Exit;
|
||||
|
||||
SetFocus;
|
||||
|
||||
// history navigation for mice with extra buttons
|
||||
case Button of
|
||||
mbExtra1:
|
||||
begin
|
||||
GoToPrevHistory;
|
||||
Exit;
|
||||
end;
|
||||
mbExtra2:
|
||||
begin
|
||||
GoToNextHistory;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if IsFileIndexInRange(FileIndex) then
|
||||
begin
|
||||
AFile := FFiles[FileIndex];
|
||||
FMainControlLastMouseButton := Button;
|
||||
|
||||
case Button of
|
||||
mbRight:
|
||||
begin
|
||||
SetActiveFile(FileIndex);
|
||||
|
||||
if gMouseSelectionEnabled and (gMouseSelectionButton = 1) then
|
||||
begin
|
||||
FMouseSelectionStartIndex := FileIndex;
|
||||
tmContextMenu.Enabled:= True; // start context menu timer
|
||||
FLastSelectionState:= not AFile.Selected;
|
||||
MarkFile(AFile, FLastSelectionState, False);
|
||||
DoSelectionChanged(FileIndex);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
mbLeft:
|
||||
begin
|
||||
if gMouseSelectionEnabled then
|
||||
begin
|
||||
if ssCtrl in Shift then
|
||||
begin
|
||||
// if there is no selected files then select also previous file
|
||||
if not HasSelectedFiles then
|
||||
begin
|
||||
APreviousFile := GetActiveDisplayFile;
|
||||
if Assigned(APreviousFile) then
|
||||
MarkFile(APreviousFile, True, False);
|
||||
end;
|
||||
InvertFileSelection(AFile, False);
|
||||
DoSelectionChanged(FileIndex);
|
||||
end
|
||||
else if ssShift in Shift then
|
||||
begin
|
||||
SelectRange(FileIndex);
|
||||
end
|
||||
else if (gMouseSelectionButton = 0) then
|
||||
begin
|
||||
if not AFile.Selected then
|
||||
MarkFiles(False);
|
||||
end;
|
||||
end;//of mouse selection handler
|
||||
end;
|
||||
else
|
||||
SetActiveFile(FileIndex);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
{ Dragging }
|
||||
|
||||
if not MainControl.Dragging then // we could be in dragging mode already (started by a different button)
|
||||
begin
|
||||
// indicate that drag start at next mouse move event
|
||||
FStartDrag := True;
|
||||
FDragStartPoint.X := X;
|
||||
FDragStartPoint.Y := Y;
|
||||
FDragFileIndex := FileIndex;
|
||||
uDragDropEx.TransformDragging := False;
|
||||
uDragDropEx.AllowTransformToInternal := True;
|
||||
end;
|
||||
end
|
||||
else // if mouse on empty space
|
||||
begin
|
||||
if (Button = mbRight) and (gMouseSelectionEnabled) and (gMouseSelectionButton = 1) then
|
||||
tmContextMenu.Enabled:= True; // start context menu timer
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlMouseLeave(Sender: TObject);
|
||||
begin
|
||||
if (gMouseSelectionEnabled) and (gMouseSelectionButton = 1) then
|
||||
FMainControlMouseDown:= False;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
|
||||
var
|
||||
Point: TPoint;
|
||||
AFile: TDisplayFile;
|
||||
ExpectedButton: TShiftStateEnum;
|
||||
FileIndex: PtrInt;
|
||||
AtFileList: Boolean;
|
||||
i, SelStartIndex, SelEndIndex: Integer;
|
||||
begin
|
||||
if FMainControlMouseDown and MainControl.Dragging then
|
||||
begin
|
||||
// If dragging has started then clear MouseDown flag.
|
||||
if (Abs(FDragStartPoint.X - X) > DragManager.DragThreshold) or
|
||||
(Abs(FDragStartPoint.Y - Y) > DragManager.DragThreshold) then
|
||||
begin
|
||||
FMainControlMouseDown := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
// If dragging is currently in effect, the window has mouse capture and
|
||||
// we can retrieve the window over which the mouse cursor currently is.
|
||||
if MainControl.Dragging and uDragDropEx.IsExternalDraggingSupported then
|
||||
begin
|
||||
Point := MainControl.ClientToScreen(Classes.Point(X, Y));
|
||||
|
||||
// use specifically LCLIntf.WindowFromPoint to avoid confusion with Windows.WindowFromPoint
|
||||
if LCLIntf.WindowFromPoint(Point) = 0 then
|
||||
begin
|
||||
// If result is 0 then the window belongs to another process
|
||||
// and we transform intra-process dragging into inter-process dragging.
|
||||
|
||||
TransformDraggingToExternal(Point);
|
||||
end;
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
// if we are about to start dragging
|
||||
if FStartDrag then
|
||||
begin
|
||||
FStartDrag := False;
|
||||
|
||||
case FMainControlLastMouseButton of
|
||||
mbLeft : ExpectedButton := ssLeft;
|
||||
mbMiddle : ExpectedButton := ssMiddle;
|
||||
mbRight : ExpectedButton := ssRight;
|
||||
else Exit;
|
||||
end;
|
||||
|
||||
// Make sure the same mouse button is still pressed.
|
||||
if not (ExpectedButton in Shift) then
|
||||
begin
|
||||
ClearAfterDragDrop;
|
||||
end
|
||||
else if IsFileIndexInRange(FDragFileIndex) then
|
||||
begin
|
||||
AFile := FFiles[FDragFileIndex];
|
||||
// Check if valid item is being dragged.
|
||||
if IsItemValid(AFile) then
|
||||
begin
|
||||
MainControl.BeginDrag(False);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Show file info tooltip.
|
||||
if ShowHint and
|
||||
not MainControl.Dragging and ([ssLeft, ssMiddle, ssRight] * Shift = []) then
|
||||
begin
|
||||
FileIndex := GetFileIndexFromCursor(X, Y, AtFileList);
|
||||
if FileIndex <> FHintFileIndex then
|
||||
begin
|
||||
FHintFileIndex := FileIndex;
|
||||
Application.CancelHint;
|
||||
MainControl.Hint:= EmptyStr; // don't show by default
|
||||
|
||||
if IsFileIndexInRange(FileIndex) then
|
||||
DoMainControlShowHint(FHintFileIndex, X, Y);
|
||||
end;
|
||||
end;
|
||||
|
||||
// Selection with right mouse button, if enabled.
|
||||
if FMainControlMouseDown and (FMainControlLastMouseButton = mbRight) and
|
||||
gMouseSelectionEnabled and (gMouseSelectionButton = 1) then
|
||||
begin
|
||||
FileIndex := GetFileIndexFromCursor(X, Y, AtFileList);
|
||||
if IsFileIndexInRange(FileIndex) and
|
||||
(GetActiveFileIndex <> FileIndex) then
|
||||
begin
|
||||
tmContextMenu.Enabled:= False; // stop context menu timer
|
||||
if FMouseSelectionStartIndex < FileIndex then
|
||||
begin
|
||||
SelStartIndex := FMouseSelectionStartIndex;
|
||||
SelEndIndex := FileIndex;
|
||||
end
|
||||
else
|
||||
begin
|
||||
SelStartIndex := FileIndex;
|
||||
SelEndIndex := FMouseSelectionStartIndex;
|
||||
end;
|
||||
|
||||
SetActiveFile(FileIndex);
|
||||
|
||||
BeginUpdate;
|
||||
try
|
||||
for i := SelStartIndex to SelEndIndex do
|
||||
MarkFile(FFiles[i], FLastSelectionState);
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
begin
|
||||
FStartDrag := False;
|
||||
|
||||
// Handle only if button-up was not lifted to finish drag&drop operation.
|
||||
if not FMainControlMouseDown then
|
||||
Exit;
|
||||
|
||||
FMainControlMouseDown := False;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlShowHint(Sender: TObject; HintInfo: PHintInfo);
|
||||
var
|
||||
AFile: TDisplayFile;
|
||||
sHint: UTF8String;
|
||||
begin
|
||||
if (HintInfo^.HintStr = EmptyStr) or not IsFileIndexInRange(FHintFileIndex) then
|
||||
Exit; // don't show
|
||||
|
||||
AFile := FFiles[FHintFileIndex];
|
||||
if not AFile.FSFile.IsDirectory then
|
||||
begin
|
||||
sHint:= GetFileInfoToolTip(FileSource, AFile.FSFile);
|
||||
with HintInfo^ do
|
||||
begin
|
||||
if (sHint = EmptyStr) and (HintStr = #32) then // no tooltip
|
||||
HintStr:= EmptyStr
|
||||
else if (sHint <> EmptyStr) then // has tooltip
|
||||
begin
|
||||
if HintStr = #32 then // without name
|
||||
HintStr:= sHint
|
||||
else
|
||||
HintStr:= HintStr + LineEnding + sHint;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
|
||||
begin
|
||||
// check if ShiftState is equal to quick search / filter modes
|
||||
if quickSearch.CheckSearchOrFilter(UTF8Key) then
|
||||
Exit;
|
||||
end;
|
||||
|
||||
function TFileViewWithMainCtrl.OnExDragBegin: Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TFileViewWithMainCtrl.OnExDragEnd: Boolean;
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
var
|
||||
startPoint: TPoint;
|
||||
currentPoint: TPoint;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
// On windows dragging can be transformed back into internal.
|
||||
// Check if drag was aborted due to mouse moving back into
|
||||
// the application window or the user just cancelled it.
|
||||
if TransformDragging and (FDragDropSource.GetLastStatus = DragDropAborted) then
|
||||
begin
|
||||
// Transform to internal dragging again.
|
||||
|
||||
// Save current mouse position.
|
||||
GetCursorPos(currentPoint);
|
||||
|
||||
// Temporarily set cursor position to the point where the drag was started
|
||||
// so that DragManager can properly read the control being dragged.
|
||||
startPoint := MainControl.ClientToScreen(FDragStartPoint);
|
||||
SetCursorPos(startPoint.X, startPoint.Y);
|
||||
|
||||
// Begin internal dragging.
|
||||
MainControl.BeginDrag(True);
|
||||
|
||||
// Move cursor back.
|
||||
SetCursorPos(currentPoint.X, currentPoint.Y);
|
||||
|
||||
// Clear flag.
|
||||
TransformDragging := False;
|
||||
|
||||
Exit(True);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
ClearAfterDragDrop;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TFileViewWithMainCtrl.OnExDragEnter(var DropEffect: TDropEffect; ScreenPoint: TPoint): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TFileViewWithMainCtrl.OnExDragLeave: Boolean;
|
||||
begin
|
||||
SetDropFileIndex(-1);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TFileViewWithMainCtrl.OnExDragOver(var DropEffect: TDropEffect; ScreenPoint: TPoint): Boolean;
|
||||
var
|
||||
ClientPoint: TPoint;
|
||||
AFile: TDisplayFile;
|
||||
FileIndex: PtrInt;
|
||||
AtFileList: Boolean;
|
||||
begin
|
||||
// Dropping into empty panel allowed.
|
||||
Result := True;
|
||||
|
||||
ClientPoint := MainControl.ScreenToClient(ScreenPoint);
|
||||
FileIndex := GetFileIndexFromCursor(ClientPoint.x, ClientPoint.y, AtFileList);
|
||||
|
||||
if IsFileIndexInRange(FileIndex) then
|
||||
begin
|
||||
// Get the file over which there is something dragged.
|
||||
AFile := FFiles[FileIndex];
|
||||
|
||||
// If it is a directory or link mark possibility of drop.
|
||||
if (AFile.FSFile.IsDirectory or AFile.FSFile.IsLinkToDirectory) then
|
||||
SetDropFileIndex(FileIndex)
|
||||
else
|
||||
SetDropFileIndex(-1);
|
||||
end
|
||||
else
|
||||
SetDropFileIndex(-1);
|
||||
end;
|
||||
|
||||
function TFileViewWithMainCtrl.OnExDrop(const FileNamesList: TStringList; DropEffect: TDropEffect; ScreenPoint: TPoint): Boolean;
|
||||
var
|
||||
AFiles: TFiles;
|
||||
DropParams: TDropParams;
|
||||
begin
|
||||
if FileNamesList.Count > 0 then
|
||||
begin
|
||||
AFiles := TFileSystemFileSource.CreateFilesFromFileList(
|
||||
ExtractFilePath(FileNamesList[0]), FileNamesList);
|
||||
try
|
||||
DropParams := TDropParams.Create(
|
||||
AFiles, DropEffect, ScreenPoint, True,
|
||||
nil, Self, Self.CurrentPath);
|
||||
|
||||
frmMain.DropFiles(DropParams);
|
||||
except
|
||||
FreeAndNil(AFiles);
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
|
||||
SetDropFileIndex(-1);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.SetActive(bActive: Boolean);
|
||||
begin
|
||||
inherited SetActive(bActive);
|
||||
MainControl.Color := DimColor(gBackColor);
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.SetDropFileIndex(NewFileIndex: PtrInt);
|
||||
var
|
||||
OldDropIndex: PtrInt;
|
||||
begin
|
||||
if FDropFileIndex <> NewFileIndex then
|
||||
begin
|
||||
OldDropIndex := FDropFileIndex;
|
||||
|
||||
// Set new index before redrawing.
|
||||
FDropFileIndex := NewFileIndex;
|
||||
|
||||
if IsFileIndexInRange(OldDropIndex) then
|
||||
RedrawFile(OldDropIndex);
|
||||
if IsFileIndexInRange(NewFileIndex) then
|
||||
RedrawFile(NewFileIndex);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.SetFocus;
|
||||
begin
|
||||
// CanFocus checks parent controls, but not parent form.
|
||||
if GetParentForm(Self).CanFocus and MainControl.CanFocus then
|
||||
MainControl.SetFocus;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.SetMainControl(AValue: TWinControl);
|
||||
begin
|
||||
if FMainControl = AValue then Exit;
|
||||
FMainControl := AValue;
|
||||
|
||||
FMainControl.OnEnter := @MainControlEnter;
|
||||
FMainControl.OnExit := @MainControlExit;
|
||||
FMainControl.OnKeyDown := @MainControlKeyDown;
|
||||
FMainControl.OnKeyUp := @MainControlKeyUp;
|
||||
FMainControl.OnShowHint := @MainControlShowHint;
|
||||
FMainControl.OnUTF8KeyPress := @MainControlUTF8KeyPress;
|
||||
|
||||
TControlHandlersHack(FMainControl).OnDblClick := @MainControlDblClick;
|
||||
TControlHandlersHack(FMainControl).OnDragDrop := @MainControlDragDrop;
|
||||
TControlHandlersHack(FMainControl).OnDragOver := @MainControlDragOver;
|
||||
TControlHandlersHack(FMainControl).OnEndDrag := @MainControlEndDrag;
|
||||
TControlHandlersHack(FMainControl).OnMouseDown := @MainControlMouseDown;
|
||||
TControlHandlersHack(FMainControl).OnMouseLeave := @MainControlMouseLeave;
|
||||
TControlHandlersHack(FMainControl).OnMouseMove := @MainControlMouseMove;
|
||||
TControlHandlersHack(FMainControl).OnMouseUp := @MainControlMouseUp;
|
||||
|
||||
HotMan.Register(MainControl, 'Files Panel');
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.tmContextMenuTimer(Sender: TObject);
|
||||
var
|
||||
AFile: TDisplayFile;
|
||||
ClientPoint, MousePoint: TPoint;
|
||||
Background: Boolean;
|
||||
FileIndex: PtrInt;
|
||||
AtFileList: Boolean;
|
||||
begin
|
||||
FMainControlMouseDown:= False;
|
||||
tmContextMenu.Enabled:= False; // stop context menu timer
|
||||
|
||||
MousePoint := Mouse.CursorPos;
|
||||
ClientPoint := MainControl.ScreenToClient(MousePoint);
|
||||
FileIndex := GetFileIndexFromCursor(ClientPoint.x, ClientPoint.y, AtFileList);
|
||||
Background := not IsFileIndexInRange(FileIndex);
|
||||
|
||||
if not Background then
|
||||
begin
|
||||
AFile := FFiles[FileIndex];
|
||||
MarkFile(AFile, not FLastSelectionState, False);
|
||||
DoSelectionChanged(FileIndex);
|
||||
end;
|
||||
|
||||
frmMain.Commands.DoContextMenu(Self, MousePoint.x, MousePoint.y, Background);
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.TransformDraggingToExternal(ScreenPoint: TPoint);
|
||||
begin
|
||||
// Set flag temporarily before stopping internal dragging,
|
||||
// so that triggered events will know that dragging is transforming.
|
||||
TransformDragging := True;
|
||||
|
||||
// Stop internal dragging
|
||||
DragManager.DragStop(False);
|
||||
|
||||
{$IF DEFINED(LCLGTK) or DEFINED(LCLGTK2)}
|
||||
// Under GTK, DragManager does not release it's mouse capture on
|
||||
// DragStop(). We must release it here manually or LCL will get confused
|
||||
// with who "owns" the capture after the GTK drag&drop finishes.
|
||||
ReleaseMouseCapture;
|
||||
{$ENDIF}
|
||||
|
||||
// Clear flag before starting external dragging.
|
||||
TransformDragging := False;
|
||||
|
||||
// Start external dragging.
|
||||
// On Windows it does not return until dragging is finished.
|
||||
|
||||
if IsFileIndexInRange(FDragFileIndex) then
|
||||
begin
|
||||
BeginDragExternal(FFiles[FDragFileIndex],
|
||||
FDragDropSource,
|
||||
FMainControlLastMouseButton,
|
||||
ScreenPoint);
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF LCLGTK2}
|
||||
function TFileViewWithMainCtrl.TooManyDoubleClicks: Boolean;
|
||||
begin
|
||||
Result := ((Now - FLastDoubleClickTime) <= ((1/86400)*(DblClickTime/1000)));
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TFileViewWithMainCtrl.WorkerFinished(const Worker: TFileViewWorker);
|
||||
begin
|
||||
inherited WorkerFinished(Worker);
|
||||
MainControl.Cursor := crDefault;
|
||||
UpdateInfoPanel; // Update status line only
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.WorkerStarting(const Worker: TFileViewWorker);
|
||||
begin
|
||||
inherited WorkerStarting(Worker);
|
||||
MainControl.Cursor := crHourGlass;
|
||||
UpdateInfoPanel; // Update status line only
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
@ -49,23 +49,26 @@ type
|
|||
procedure quickSearchChangeFilter(Sender: TObject; AFilterText: UTF8String; const AFilterOptions: TQuickSearchOptions);
|
||||
procedure quickSearchExecute(Sender: TObject);
|
||||
procedure quickSearchHide(Sender: TObject);
|
||||
function IsFileIndexInRange(FileIndex: PtrInt): Boolean;
|
||||
|
||||
protected
|
||||
lblFilter: TLabel;
|
||||
quickSearch: TfrmQuickSearch;
|
||||
FLastActiveFileIndex: Integer;
|
||||
FLastSelectionStartIndex: Integer;
|
||||
FLastSelectionState: Boolean;
|
||||
FUpdatingActiveFile: Boolean;
|
||||
procedure AfterChangePath; override;
|
||||
procedure CreateDefault(AOwner: TWinControl); override;
|
||||
procedure DoFileIndexChanged(NewFileIndex: PtrInt);
|
||||
procedure DoHandleKeyDown(var Key: Word; Shift: TShiftState); override;
|
||||
procedure DoSelectionChanged; override;
|
||||
procedure DoSelectionChanged(FileIndex: PtrInt);
|
||||
procedure EnsureDisplayProperties;
|
||||
function GetActiveDisplayFile: TDisplayFile; override;
|
||||
function GetActiveFileIndex: PtrInt; virtual; abstract;
|
||||
function GetFileRect(FileIndex: PtrInt): TRect; virtual; abstract;
|
||||
function GetVisibleFilesIndexes: TRange; virtual; abstract;
|
||||
function IsFileIndexInRange(FileIndex: PtrInt): Boolean;
|
||||
procedure RedrawFile(FileIndex: PtrInt); overload; virtual; abstract;
|
||||
procedure RedrawFiles; virtual; abstract;
|
||||
{en
|
||||
|
|
@ -180,6 +183,17 @@ begin
|
|||
pmOperationsCancel.Parent := Self;
|
||||
end;
|
||||
|
||||
procedure TOrderedFileView.DoFileIndexChanged(NewFileIndex: PtrInt);
|
||||
begin
|
||||
if (FLastActiveFileIndex <> NewFileIndex) and (not FUpdatingActiveFile) then
|
||||
begin
|
||||
SetLastActiveFile(NewFileIndex);
|
||||
|
||||
if Assigned(OnChangeActiveFile) then
|
||||
OnChangeActiveFile(Self, FFiles[NewFileIndex].FSFile);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TOrderedFileView.DoHandleKeyDown(var Key: Word; Shift: TShiftState);
|
||||
var
|
||||
mi: TMenuItem;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue