mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-28 10:02:14 +00:00
UPD: Range selecting cannot only depend on Shift state and focused file change because it would select also on hotkeys and quick search. Move it back down to controls and select only on proper keys.
UPD: Preserve range select starting point when Shift is depressed but focused file doesn't change.
This commit is contained in:
parent
1e39fdb75c
commit
129ef040c7
5 changed files with 124 additions and 31 deletions
|
|
@ -103,7 +103,8 @@ uses
|
|||
fColumnsSetConf,
|
||||
uKeyboard,
|
||||
uFileSourceUtil,
|
||||
uFileFunctions;
|
||||
uFileFunctions,
|
||||
uOrderedFileView;
|
||||
|
||||
{ TBriefDrawGrid }
|
||||
|
||||
|
|
@ -321,7 +322,16 @@ begin
|
|||
end;
|
||||
|
||||
procedure TBriefDrawGrid.KeyDown(var Key: Word; Shift: TShiftState);
|
||||
var
|
||||
SavedKey: Word;
|
||||
FileIndex: Integer;
|
||||
begin
|
||||
SavedKey := Key;
|
||||
// Set RangeSelecting before cursor is moved.
|
||||
BriefView.FRangeSelecting :=
|
||||
(ssShift in Shift) and
|
||||
(SavedKey in [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_HOME, VK_END, VK_PRIOR, VK_NEXT]);
|
||||
|
||||
case Key of
|
||||
VK_RIGHT:
|
||||
begin
|
||||
|
|
@ -355,6 +365,13 @@ begin
|
|||
end;
|
||||
end;
|
||||
inherited KeyDown(Key, Shift);
|
||||
|
||||
if ssShift in Shift then
|
||||
begin
|
||||
FileIndex := CellToIndex(Col, Row);
|
||||
if FileIndex <> InvalidFileIndex then
|
||||
BriefView.Selection(SavedKey, FileIndex);
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TBriefDrawGrid.Create(AOwner: TComponent; AParent: TWinControl);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ type
|
|||
procedure SetGridVertLine(const AValue: Boolean);
|
||||
|
||||
protected
|
||||
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
||||
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,Y: Integer); override;
|
||||
procedure MouseUp(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
|
||||
|
||||
|
|
@ -1793,6 +1794,22 @@ begin
|
|||
Result:= (Top<=aRow)and(aRow<=Bottom);
|
||||
end;
|
||||
|
||||
procedure TDrawGridEx.KeyDown(var Key: Word; Shift: TShiftState);
|
||||
var
|
||||
SavedKey: Word;
|
||||
begin
|
||||
SavedKey := Key;
|
||||
// Set RangeSelecting before cursor is moved.
|
||||
ColumnsView.FRangeSelecting :=
|
||||
(ssShift in Shift) and
|
||||
(SavedKey in [VK_UP, VK_DOWN, VK_HOME, VK_END, VK_PRIOR, VK_NEXT]);
|
||||
|
||||
inherited KeyDown(Key, Shift);
|
||||
|
||||
if (ssShift in Shift) and (Row >= FixedRows) then
|
||||
ColumnsView.Selection(SavedKey, Row - FixedRows);
|
||||
end;
|
||||
|
||||
procedure TDrawGridEx.ScrollHorizontally(ForwardDirection: Boolean);
|
||||
function TryMove(ACol: Integer): Boolean;
|
||||
begin
|
||||
|
|
|
|||
|
|
@ -1570,9 +1570,18 @@ procedure TColumnsDrawTree.WMKeyDown(var Message: TLMKeyDown);
|
|||
var
|
||||
Node, Temp: PVirtualNode;
|
||||
Offset: Integer;
|
||||
SavedKey: Word;
|
||||
Shift: TShiftState;
|
||||
begin
|
||||
Shift := KeyDataToShiftState(Message.KeyData);
|
||||
SavedKey := Message.CharCode;
|
||||
// Set RangeSelecting before cursor is moved.
|
||||
ColumnsView.FRangeSelecting :=
|
||||
(ssShift in Shift) and
|
||||
(SavedKey in [VK_UP, VK_DOWN, VK_HOME, VK_END, VK_PRIOR, VK_NEXT]);
|
||||
|
||||
// Override scrolling with PageUp, PageDown because VirtualTreeView scrolls too much.
|
||||
case Message.CharCode of
|
||||
case SavedKey of
|
||||
VK_PRIOR:
|
||||
begin
|
||||
Offset := 0;
|
||||
|
|
@ -1625,6 +1634,9 @@ begin
|
|||
end;
|
||||
|
||||
inherited WMKeyDown(Message);
|
||||
|
||||
if (ssShift in Shift) and Assigned(FocusedNode) then
|
||||
ColumnsView.Selection(SavedKey, FocusedNode^.Index);
|
||||
end;
|
||||
|
||||
procedure TColumnsDrawTree.InitializeWnd;
|
||||
|
|
|
|||
|
|
@ -435,6 +435,7 @@ end;
|
|||
procedure TFileViewWithMainCtrl.MainControlExit(Sender: TObject);
|
||||
begin
|
||||
SetActive(False);
|
||||
FRangeSelecting := False;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
|
|
@ -469,12 +470,7 @@ end;
|
|||
|
||||
procedure TFileViewWithMainCtrl.MainControlKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||
begin
|
||||
case Key of
|
||||
VK_SHIFT:
|
||||
begin
|
||||
FRangeSelectionStartIndex := -1;
|
||||
end;
|
||||
end;
|
||||
FRangeSelecting := False;
|
||||
end;
|
||||
|
||||
procedure TFileViewWithMainCtrl.MainControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
|
|
@ -541,6 +537,7 @@ begin
|
|||
end
|
||||
else if ssShift in Shift then
|
||||
begin
|
||||
FRangeSelecting := True;
|
||||
SelectRange(FileIndex);
|
||||
end
|
||||
else if (gMouseSelectionButton = 0) then
|
||||
|
|
@ -693,6 +690,7 @@ end;
|
|||
procedure TFileViewWithMainCtrl.MainControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
begin
|
||||
FStartDrag := False;
|
||||
FRangeSelecting := False;
|
||||
|
||||
// Handle only if button-up was not lifted to finish drag&drop operation.
|
||||
if not FMainControlMouseDown then
|
||||
|
|
|
|||
|
|
@ -49,11 +49,13 @@ type
|
|||
procedure quickSearchChangeFilter(Sender: TObject; AFilterText: UTF8String; const AFilterOptions: TQuickSearchOptions);
|
||||
procedure quickSearchExecute(Sender: TObject);
|
||||
procedure quickSearchHide(Sender: TObject);
|
||||
procedure UpdateRangeSelectionState;
|
||||
|
||||
protected
|
||||
lblFilter: TLabel;
|
||||
quickSearch: TfrmQuickSearch;
|
||||
FLastActiveFileIndex: Integer;
|
||||
FRangeSelecting: Boolean;
|
||||
FRangeSelectionStartIndex: Integer;
|
||||
FRangeSelectionEndIndex: Integer;
|
||||
FRangeSelectionState: Boolean;
|
||||
|
|
@ -84,6 +86,7 @@ type
|
|||
procedure SearchFile(SearchTerm: UTF8String;
|
||||
SearchOptions: TQuickSearchOptions;
|
||||
SearchDirection: TQuickSearchDirection = qsdNone);
|
||||
procedure Selection(Key: Word; CurIndex: PtrInt);
|
||||
procedure SelectRange(FileIndex: PtrInt);
|
||||
procedure SetActiveFile(FileIndex: PtrInt); overload; virtual; abstract;
|
||||
procedure SetLastActiveFile(FileIndex: PtrInt);
|
||||
|
|
@ -196,15 +199,20 @@ procedure TOrderedFileView.DoFileIndexChanged(NewFileIndex: PtrInt);
|
|||
begin
|
||||
if FLastActiveFileIndex <> NewFileIndex then
|
||||
begin
|
||||
if not FRangeSelecting then
|
||||
begin
|
||||
// Set range selection starting point.
|
||||
FRangeSelectionStartIndex := NewFileIndex;
|
||||
FRangeSelectionEndIndex := NewFileIndex;
|
||||
UpdateRangeSelectionState;
|
||||
end;
|
||||
|
||||
if not FUpdatingActiveFile then
|
||||
begin
|
||||
SetLastActiveFile(NewFileIndex);
|
||||
|
||||
if Assigned(OnChangeActiveFile) then
|
||||
OnChangeActiveFile(Self, FFiles[NewFileIndex].FSFile);
|
||||
|
||||
if (ssShift in GetKeyShiftState) and (NewFileIndex <> InvalidFileIndex) then
|
||||
SelectRange(NewFileIndex);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
|
@ -212,7 +220,6 @@ end;
|
|||
procedure TOrderedFileView.DoHandleKeyDown(var Key: Word; Shift: TShiftState);
|
||||
var
|
||||
mi: TMenuItem;
|
||||
FileIndex: PtrInt;
|
||||
begin
|
||||
// check if ShiftState is equal to quick search / filter modes
|
||||
if quickSearch.CheckSearchOrFilter(Key) then
|
||||
|
|
@ -252,19 +259,6 @@ begin
|
|||
Key := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
VK_SHIFT:
|
||||
begin
|
||||
if FRangeSelectionStartIndex = -1 then
|
||||
begin
|
||||
FileIndex := GetActiveFileIndex;
|
||||
FRangeSelectionStartIndex := FileIndex;
|
||||
FRangeSelectionEndIndex := FileIndex;
|
||||
FRangeSelectionState := (FileIndex <> InvalidFileIndex) and
|
||||
not FFiles[FileIndex].Selected;
|
||||
end;
|
||||
// Key := 0; not needed
|
||||
end;
|
||||
end;
|
||||
|
||||
inherited DoHandleKeyDown(Key, Shift);
|
||||
|
|
@ -274,6 +268,7 @@ procedure TOrderedFileView.DoSelectionChanged;
|
|||
begin
|
||||
inherited DoSelectionChanged;
|
||||
RedrawFiles;
|
||||
UpdateRangeSelectionState;
|
||||
end;
|
||||
|
||||
procedure TOrderedFileView.DoSelectionChanged(FileIndex: PtrInt);
|
||||
|
|
@ -281,6 +276,7 @@ begin
|
|||
inherited DoSelectionChanged;
|
||||
if IsFileIndexInRange(FileIndex) then
|
||||
RedrawFile(FileIndex);
|
||||
UpdateRangeSelectionState;
|
||||
end;
|
||||
|
||||
procedure TOrderedFileView.EnsureDisplayProperties;
|
||||
|
|
@ -379,10 +375,7 @@ begin
|
|||
if FromIndex = ToIndex then
|
||||
begin
|
||||
MarkFile(FFiles[FromIndex], bSelect, False);
|
||||
if (FromIndex = 0) or (FromIndex = FFiles.Count - 1) then
|
||||
DoSelectionChanged(FromIndex)
|
||||
else
|
||||
DoSelectionChanged(-1);
|
||||
DoSelectionChanged(FromIndex);
|
||||
end
|
||||
else
|
||||
MarkFiles(FromIndex, ToIndex, bSelect);
|
||||
|
|
@ -541,8 +534,38 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TOrderedFileView.Selection(Key: Word; CurIndex: PtrInt);
|
||||
procedure OneLess;
|
||||
begin
|
||||
if CurIndex > FRangeSelectionStartIndex then
|
||||
Dec(CurIndex)
|
||||
else if CurIndex < FRangeSelectionStartIndex then
|
||||
Inc(CurIndex);
|
||||
end;
|
||||
begin
|
||||
// Key value doesn't neccessarily matter.
|
||||
// It just needs to correspond to scroll positions (similar to TScrollCode).
|
||||
case Key of
|
||||
VK_HOME, VK_END: ;
|
||||
VK_PRIOR, VK_UP, VK_LEFT:
|
||||
if CurIndex > 0 then
|
||||
OneLess;
|
||||
VK_NEXT, VK_DOWN, VK_RIGHT:
|
||||
if CurIndex < FFiles.Count - 1 then
|
||||
OneLess;
|
||||
else
|
||||
Exit;
|
||||
end;
|
||||
|
||||
SelectRange(CurIndex);
|
||||
end;
|
||||
|
||||
procedure TOrderedFileView.SelectRange(FileIndex: PtrInt);
|
||||
begin
|
||||
// Initially select file at starting point.
|
||||
if FRangeSelectionStartIndex = FRangeSelectionEndIndex then
|
||||
MarkFilesWithCheck(FRangeSelectionStartIndex, FRangeSelectionEndIndex, FRangeSelectionState);
|
||||
|
||||
if FileIndex <> FRangeSelectionEndIndex then
|
||||
begin
|
||||
if FileIndex < FRangeSelectionStartIndex then
|
||||
|
|
@ -560,7 +583,7 @@ begin
|
|||
MarkFilesWithCheck(FRangeSelectionEndIndex, FileIndex - 1, not FRangeSelectionState)
|
||||
else if FileIndex < FRangeSelectionEndIndex then
|
||||
// Increase selection range.
|
||||
MarkFilesWithCheck(FileIndex, FRangeSelectionEndIndex, FRangeSelectionState);
|
||||
MarkFilesWithCheck(FileIndex, FRangeSelectionEndIndex - 1, FRangeSelectionState);
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
|
@ -574,7 +597,7 @@ begin
|
|||
|
||||
if FileIndex > FRangeSelectionEndIndex then
|
||||
// Increase selection range.
|
||||
MarkFilesWithCheck(FRangeSelectionEndIndex, FileIndex, FRangeSelectionState)
|
||||
MarkFilesWithCheck(FRangeSelectionEndIndex + 1, FileIndex, FRangeSelectionState)
|
||||
else if FileIndex < FRangeSelectionEndIndex then
|
||||
// Decrease selection range.
|
||||
MarkFilesWithCheck(FileIndex + 1, FRangeSelectionEndIndex, not FRangeSelectionState);
|
||||
|
|
@ -649,5 +672,31 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TOrderedFileView.UpdateRangeSelectionState;
|
||||
var
|
||||
NewSelectionState: Boolean;
|
||||
begin
|
||||
if not FRangeSelecting then
|
||||
begin
|
||||
if FRangeSelectionStartIndex <> InvalidFileIndex then
|
||||
begin
|
||||
NewSelectionState := not FFiles[FRangeSelectionStartIndex].Selected;
|
||||
if (FRangeSelectionState <> NewSelectionState) and
|
||||
(FRangeSelectionStartIndex = FRangeSelectionEndIndex) then
|
||||
begin
|
||||
// Selection of starting point has changed.
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Update was called but selection of starting point didn't change.
|
||||
// That means some other file's selection changed - reset starting point.
|
||||
FRangeSelectionStartIndex := GetActiveFileIndex;
|
||||
FRangeSelectionEndIndex := FRangeSelectionStartIndex;
|
||||
end;
|
||||
FRangeSelectionState := NewSelectionState;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue