procedure TMainForm.ListKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
{ Handling of various key-combos when on the list.
Maybe should use actions instead.}
var
Max, NewIndex, NewCurrent: Integer;
AList: TStringList;
function NoShift : Boolean; begin Result := Shift = []; end;
function WithAlt : Boolean; begin Result := Shift = [ssAlt]; end;
function WithCtrl : Boolean; begin Result := Shift = [ssCtrl]; end;
function WithShift: Boolean; begin Result := Shift = [ssShift]; end;
function IsCopyCombo: Boolean;
begin
Result := (Key in [VK_C, VK_INSERT]) and WithCtrl;
end;
function IsCutCombo: Boolean;
begin
Result := ((Key = VK_X) and WithCtrl) or
((Key = VK_DELETE) and WithShift)
end;
function IsAndCanPaste: Boolean;
begin
Result := Clipboard.HasFormat(CF_Text) and (
((Key = VK_V) and WithCtrl) or
((Key = VK_INSERT) and WithShift));
end;
procedure DeleteSelection;
var i: Integer;
begin
{ Adjusts ItemIndex to keep it on the same or next file.}
NewIndex := FileList.ItemIndex;
for i := FileList.ItemIndex downto 0 do begin
if (FileList.Selected[i]) and (NewIndex >= 0) then
Dec(NewIndex);
end;
{Adjust Current too, else list-play will skip}
NewCurrent := Current;
for i := Current downto 0 do begin
if (FileList.Selected[i]) and (NewCurrent >= 0) then
Dec(NewCurrent);
end;
{ Now do the deed }
FileList.DeleteSelected;
FileList.AdjustScrollWidth;
Current := NewCurrent;
{Must be after: SetCurrent also sets ItemIndex}
FileList.ItemIndex := NewIndex;
end;
procedure DoCopy;
var i: Integer;
begin
AList := TStringList.Create;
try
if FileList.SelCount = 0 then
AList.AddStrings(FileList.Items)
else begin
for i := 0 to FileList.Count-1 do
if FileList.Selected[i] then
AList.Add(
TrimAndExpandFilename(FileList.Items[i],GetCurrentDir));
end;
if AList.Count > 0 then
Clipboard.AsText := AList.Text;
finally
AList.Free;
end;
end;
procedure DoCutDel;
begin
if FileList.SelCount > 0 then
DeleteSelection
else
FileList.Clear;
FileList.AdjustScrollWidth;
end;
procedure DoPaste;
begin
NewIndex := FileList.ItemIndex;
AList := TStringList.Create;
try
AList.Text := Clipboard.AsText;
if ParseList(AList, @NameParsed) then begin
CleanList(AList);
FileList.InsertItems(NewIndex, AList);
end;
finally
AList.Free;
end;
end;
procedure ZeroKey; inline;
begin
Key := 0;
end;
begin
Max := FileList.Count - 1;
case Key of
{ Enter as alternative to "Play" button }
VK_RETURN: begin
if NoShift then ListDblClick(Sender);
ZeroKey;
end;
{ List management }
{Alt+Down/Up do nothing unless there is at least one item below/above}
VK_DOWN: {Moves an item one position down the list}
if WithAlt then
if (Max > 0) and InRange(FileList.ItemIndex, 0, Max-1) then begin
FileList.Items.Exchange(FileList.ItemIndex, FileList.ItemIndex+1);
FileList.ItemIndex := FileList.ItemIndex + 1;
FListSaved := False;
ZeroKey;
end;
VK_UP : {Moves an item one position up the list}
if WithAlt then
if (Max > 0) and InRange(FileList.ItemIndex, 1, Max) then begin
FileList.Items.Exchange(FileList.ItemIndex, FileList.ItemIndex-1);
FileList.ItemIndex := FileList.ItemIndex - 1;
FListSaved := False;
ZeroKey;
end;
VK_DELETE: {Delete/cut selected item(s)}
begin
if NoShift and (FileList.SelCount > 0) then begin
DeleteSelection;
FListSaved := False;
end else if WithShift then begin {Shift+Del = Cut}
DoCopy;
DoCutDel;
FListSaved := False;
end;
{ List might be empty now, so }
UpdateButtons();
ZeroKey;
end;
{ Clipboard ops. }
VK_INSERT, VK_V:
if IsCopyCombo then begin
DoCopy;
ZeroKey;
end else if IsAndCanPaste then begin
DoPaste;
FListSaved := False;
ZeroKey;
UpdateButtons();{< list might have been empty.}
end;
VK_C, VK_X: {Copy to clipboard; if "X", do cut op.}
if IsCopyCombo or IsCutCombo then begin
DoCopy;
if IsCutCombo then begin
DoCutDel;
UpdateButtons();{< because list might be empty now.}
FListSaved := False;
end;
ZeroKey;
end;
end;{case Key of}
end;