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:
cobines 2012-05-04 15:11:19 +00:00
commit 129ef040c7
5 changed files with 124 additions and 31 deletions

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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.