mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Issue 2400 – Pasting cut files from the clipboard into a local panel copies them instead of moving them
https://winscp.net/tracker/2400 Source commit: 1611bbe26e4d713795c2b07e1f17146a31f4461b
This commit is contained in:
@@ -467,18 +467,19 @@ bool __fastcall TUnixDirView::PasteFromClipBoard(UnicodeString TargetPath)
|
||||
{
|
||||
DragDropFilesEx->FileList->Clear();
|
||||
bool Result = false;
|
||||
int Effect;
|
||||
if (CanPasteFromClipBoard() &&
|
||||
DragDropFilesEx->GetFromClipboard())
|
||||
DragDropFilesEx->GetFromClipboard(Effect))
|
||||
{
|
||||
if (TargetPath.IsEmpty())
|
||||
{
|
||||
TargetPath = PathName;
|
||||
}
|
||||
|
||||
PerformItemDragDropOperation(NULL, DROPEFFECT_COPY, true);
|
||||
PerformItemDragDropOperation(NULL, Effect, true);
|
||||
if (OnDDExecuted != NULL)
|
||||
{
|
||||
OnDDExecuted(this, DROPEFFECT_COPY);
|
||||
OnDDExecuted(this, Effect);
|
||||
}
|
||||
Result = true;
|
||||
}
|
||||
|
||||
52
source/packages/dragndrop/DragDrop.pas
vendored
52
source/packages/dragndrop/DragDrop.pas
vendored
@@ -192,6 +192,7 @@ type
|
||||
procedure SuggestDropEffect(grfKeyState: LongInt; var dwEffect: LongInt); virtual;
|
||||
procedure AcceptDataObject(DataObj: IDataObject; var Accept:Boolean); virtual;
|
||||
procedure RenderDropped(DataObj: IDataObject; grfKeyState: LongInt; pt: TPoint; var dwEffect: LongInt); virtual;
|
||||
function GetPreferredDropEffect(const DataObj: IDataObject): LongInt;
|
||||
public
|
||||
constructor Create(AOwner: TDragDrop);
|
||||
destructor Destroy; override;
|
||||
@@ -338,7 +339,7 @@ type
|
||||
function ExecuteOperation(DataObject: TDataObject): TDragResult;
|
||||
function Execute: TDragResult;
|
||||
function CopyToClipboard: Boolean; virtual;
|
||||
function GetFromClipboard: Boolean; virtual;
|
||||
function GetFromClipboard(var dwEffect: LongInt): Boolean; virtual;
|
||||
procedure StartDnDDetection(Button: TMouseButton); virtual;
|
||||
property OwnerIsSource:Boolean read FOwnerIsSource;
|
||||
property Registered: Boolean read FRegistered default False;
|
||||
@@ -1200,25 +1201,13 @@ begin
|
||||
Accept := True;
|
||||
end;
|
||||
|
||||
function TDropTarget.DragEnter(
|
||||
const dataObj: IDataObject; grfKeyState: LongInt; pt: TPoint; var dwEffect: LongInt): HResult;
|
||||
// Is called if the d&d-mouse cursor moves ON (one call only) the TargeTWinControl. Here,
|
||||
// you influence if a drop can be accepted and the drop's effect if accepted.
|
||||
function TDropTarget.GetPreferredDropEffect(const DataObj: IDataObject): LongInt;
|
||||
var
|
||||
FormatEtc: TFormatEtc;
|
||||
StgMedium: TStgMedium;
|
||||
Ptr: Pointer;
|
||||
begin
|
||||
TDragDrop(FOwner).FInternalSource := GInternalSource;
|
||||
FOwner.FAvailableDropEffects := dwEffect;
|
||||
FOwner.FContextMenu := grfKeyState and MK_RBUTTON <> 0;
|
||||
if (FOwner.RenderDataOn = rdoEnter) or (FOwner.RenderDataOn = rdoEnterAndDropSync) or
|
||||
(FOwner.RenderDataOn = rdoEnterAndDropAsync) then
|
||||
begin
|
||||
RenderDropped(DataObj, grfKeyState, pt, dwEffect);
|
||||
end;
|
||||
|
||||
FPreferredEffect := 0;
|
||||
Result := 0;
|
||||
with FormatEtc do
|
||||
begin
|
||||
cfFormat := CF_PREFERREDDROPEFFECT;
|
||||
@@ -1227,14 +1216,14 @@ begin
|
||||
lindex := -1;
|
||||
tymed := TYMED_HGLOBAL;
|
||||
end;
|
||||
if dataObj.GetData(FormatEtc, StgMedium) = S_OK then
|
||||
if DataObj.GetData(FormatEtc, StgMedium) = S_OK then
|
||||
begin
|
||||
try
|
||||
if GlobalSize(StgMedium.HGlobal) = SizeOf(FPreferredEffect) then
|
||||
if GlobalSize(StgMedium.HGlobal) = SizeOf(Result) then
|
||||
begin
|
||||
Ptr := GlobalLock(StgMedium.HGlobal);
|
||||
try
|
||||
FPreferredEffect := PLongInt(Ptr)^;
|
||||
Result := PLongInt(Ptr)^;
|
||||
finally
|
||||
GlobalUnLock(StgMedium.HGlobal);
|
||||
end;
|
||||
@@ -1243,6 +1232,24 @@ begin
|
||||
ReleaseStgMedium(StgMedium);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDropTarget.DragEnter(
|
||||
const dataObj: IDataObject; grfKeyState: LongInt; pt: TPoint; var dwEffect: LongInt): HResult;
|
||||
// Is called if the d&d-mouse cursor moves ON (one call only) the TargeTWinControl. Here,
|
||||
// you influence if a drop can be accepted and the drop's effect if accepted.
|
||||
begin
|
||||
TDragDrop(FOwner).FInternalSource := GInternalSource;
|
||||
FOwner.FAvailableDropEffects := dwEffect;
|
||||
FOwner.FContextMenu := grfKeyState and MK_RBUTTON <> 0;
|
||||
if (FOwner.RenderDataOn = rdoEnter) or (FOwner.RenderDataOn = rdoEnterAndDropSync) or
|
||||
(FOwner.RenderDataOn = rdoEnterAndDropAsync) then
|
||||
begin
|
||||
var dwEffectDummy: LongInt;
|
||||
RenderDropped(DataObj, grfKeyState, pt, dwEffectDummy);
|
||||
end;
|
||||
|
||||
FPreferredEffect := GetPreferredDropEffect(dataObj);
|
||||
|
||||
SuggestDropEffect(grfKeyState, dwEffect);
|
||||
AcceptDataObject(DataObj, FAccept);
|
||||
@@ -1434,7 +1441,8 @@ begin
|
||||
mcursor := Screen.Cursor;
|
||||
Screen.Cursor := crHourGlass;
|
||||
try
|
||||
RenderDropped(DataObj, KeyState, pt, dwEffect);
|
||||
var dwEffectDummy: LongInt;
|
||||
RenderDropped(DataObj, KeyState, pt, dwEffectDummy);
|
||||
finally
|
||||
// Set old cursor
|
||||
Screen.Cursor := mcursor;
|
||||
@@ -1635,7 +1643,8 @@ begin
|
||||
mcursor := Screen.Cursor;
|
||||
Screen.Cursor := crHourGlass;
|
||||
try
|
||||
FDropTarget.RenderDropped(FDataObj, FgrfKeyState, Fpt, FdwEffect);
|
||||
var dwEffectDummy: LongInt;
|
||||
FDropTarget.RenderDropped(FDataObj, FgrfKeyState, Fpt, dwEffectDummy);
|
||||
FDataObj._Release;
|
||||
finally
|
||||
// Set old cursor
|
||||
@@ -2025,11 +2034,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDragDrop.GetFromClipboard: Boolean;
|
||||
function TDragDrop.GetFromClipboard(var dwEffect: LongInt): Boolean;
|
||||
var
|
||||
DataObject: IDataObject;
|
||||
pt: TPoint;
|
||||
dwEffect: LongInt;
|
||||
begin
|
||||
Result := (OLEGetClipBoard(DataObject) = S_OK);
|
||||
if Result then
|
||||
|
||||
@@ -863,6 +863,10 @@ begin
|
||||
ReleaseStgMedium(StgMedium);
|
||||
end;
|
||||
end;
|
||||
|
||||
var Effect := GetPreferredDropEffect(DataObj);
|
||||
if Effect <> 0 then
|
||||
dwEffect := Effect;
|
||||
end;
|
||||
|
||||
// TShellExtension ---------------------------------------------------
|
||||
|
||||
@@ -386,9 +386,6 @@ function DropFiles(
|
||||
out SourcePath: string; out SourceIsDirectory: Boolean): Boolean;
|
||||
procedure CheckCanOpenDirectory(Path: string);
|
||||
|
||||
var
|
||||
LastClipBoardOperation: TClipBoardOperation;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@@ -2190,7 +2187,6 @@ begin
|
||||
if Verb = shcCut then
|
||||
begin
|
||||
ClearCutState;
|
||||
LastClipBoardOperation := cboCut;
|
||||
{Set property cut to TRUE for all selected items:}
|
||||
Item := GetNextItem(nil, sdAll, [isSelected]);
|
||||
while Assigned(Item) do
|
||||
@@ -2205,7 +2201,6 @@ begin
|
||||
if Verb = shcCopy then
|
||||
begin
|
||||
ClearCutState;
|
||||
LastClipBoardOperation := cboCopy;
|
||||
end
|
||||
else
|
||||
{----------- Paste ----------}
|
||||
@@ -2244,7 +2239,6 @@ begin
|
||||
if Verb = shcCut then
|
||||
begin
|
||||
ClearCutState;
|
||||
LastClipBoardOperation := cboCut;
|
||||
ItemFocused.Cut := True;
|
||||
FAnyCut := True;
|
||||
end
|
||||
@@ -2253,7 +2247,6 @@ begin
|
||||
if Verb = shcCopy then
|
||||
begin
|
||||
ClearCutState;
|
||||
LastClipBoardOperation := cboCopy;
|
||||
end
|
||||
else
|
||||
{----------- Paste ----------}
|
||||
@@ -3285,7 +3278,6 @@ begin
|
||||
end;
|
||||
FAnyCut := False;
|
||||
end;
|
||||
LastClipBoardOperation := cboNone;
|
||||
if Assigned(FDriveView) and
|
||||
(TDriveView(FDriveView).LastPathCut <> '') then // prevent recursion
|
||||
begin
|
||||
@@ -3332,7 +3324,6 @@ begin
|
||||
end;
|
||||
|
||||
Result := DragDropFilesEx.CopyToClipBoard;
|
||||
LastClipBoardOperation := Operation;
|
||||
end;
|
||||
finally
|
||||
Screen.Cursor := SaveCursor;
|
||||
@@ -3350,33 +3341,17 @@ begin
|
||||
end;
|
||||
|
||||
function TDirView.PasteFromClipBoard(TargetPath: string): Boolean;
|
||||
var
|
||||
Effect: LongInt;
|
||||
begin
|
||||
DragDropFilesEx.FileList.Clear;
|
||||
Result := False;
|
||||
if CanPasteFromClipBoard and {MP}DragDropFilesEx.GetFromClipBoard{/MP}
|
||||
then
|
||||
Result := CanPasteFromClipBoard and DragDropFilesEx.GetFromClipBoard(Effect);
|
||||
if Result then
|
||||
begin
|
||||
if TargetPath = '' then
|
||||
TargetPath := PathName;
|
||||
case LastClipBoardOperation of
|
||||
cboNone:
|
||||
begin
|
||||
PerformDragDropFileOperation(TargetPath, DROPEFFECT_COPY);
|
||||
if Assigned(OnDDExecuted) then OnDDExecuted(Self, DROPEFFECT_COPY);
|
||||
end;
|
||||
cboCopy:
|
||||
begin
|
||||
PerformDragDropFileOperation(TargetPath, DROPEFFECT_COPY);
|
||||
if Assigned(OnDDExecuted) then OnDDExecuted(Self, DROPEFFECT_COPY);
|
||||
end;
|
||||
cboCut:
|
||||
begin
|
||||
PerformDragDropFileOperation(TargetPath, DROPEFFECT_MOVE);
|
||||
if Assigned(OnDDExecuted) then OnDDExecuted(Self, DROPEFFECT_MOVE);
|
||||
EmptyClipBoard;
|
||||
end;
|
||||
end;
|
||||
Result := True;
|
||||
PerformDragDropFileOperation(TargetPath, Effect);
|
||||
if Assigned(OnDDExecuted) then OnDDExecuted(Self, Effect);
|
||||
end;
|
||||
end; {PasteFromClipBoard}
|
||||
|
||||
@@ -3421,6 +3396,5 @@ end;
|
||||
{=================================================================}
|
||||
|
||||
initialization
|
||||
LastClipBoardOperation := cboNone;
|
||||
DaylightHack := (not IsWin7);
|
||||
end.
|
||||
|
||||
@@ -2669,7 +2669,6 @@ begin
|
||||
if Verb = shcCut then
|
||||
begin
|
||||
ClearCutState;
|
||||
LastClipBoardOperation := cboCut;
|
||||
FLastPathCut := NodePathName(Node);
|
||||
Node.Cut := True;
|
||||
end
|
||||
@@ -2677,7 +2676,6 @@ begin
|
||||
if Verb = shcCopy then
|
||||
begin
|
||||
ClearCutState;
|
||||
LastClipBoardOperation := cboCopy;
|
||||
end
|
||||
else
|
||||
if Verb = shcPaste then
|
||||
@@ -2915,7 +2913,6 @@ begin
|
||||
end;
|
||||
FLastPathCut := '';
|
||||
end;
|
||||
LastClipBoardOperation := cboNone;
|
||||
if Assigned(FDirView) and
|
||||
FDirView.AnyCut then // prevent recursion
|
||||
begin
|
||||
@@ -2944,26 +2941,17 @@ begin
|
||||
end; {CanPasteFromClipBoard}
|
||||
|
||||
procedure TDriveView.PasteFromClipBoard(Node: TTreeNode);
|
||||
var
|
||||
Effect: LongInt;
|
||||
begin
|
||||
ClearDragFileList(FDragDropFilesEx.FileList);
|
||||
if CanPasteFromClipBoard and FDragDropFilesEx.GetFromClipBoard then
|
||||
if CanPasteFromClipBoard and FDragDropFilesEx.GetFromClipBoard(Effect) then
|
||||
begin
|
||||
case LastClipBoardOperation of
|
||||
cboCopy,
|
||||
cboNone:
|
||||
begin
|
||||
PerformDragDropFileOperation(Node, DROPEFFECT_COPY);
|
||||
if Assigned(FOnDDExecuted) then
|
||||
FOnDDExecuted(Self, DROPEFFECT_COPY);
|
||||
end;
|
||||
cboCut:
|
||||
begin
|
||||
PerformDragDropFileOperation(Node, DROPEFFECT_MOVE);
|
||||
if Assigned(FOnDDExecuted) then
|
||||
FOnDDExecuted(Self, DROPEFFECT_MOVE);
|
||||
EmptyClipBoard;
|
||||
end;
|
||||
end;
|
||||
PerformDragDropFileOperation(Node, Effect);
|
||||
if Assigned(FOnDDExecuted) then
|
||||
FOnDDExecuted(Self, Effect);
|
||||
if Effect = DROPEFFECT_MOVE then
|
||||
EmptyClipBoard;
|
||||
end;
|
||||
end; {PasteFromClipBoard}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user