mirror of
https://github.com/winscp/winscp.git
synced 2026-10-25 14:19:30 +03:00
Bug 1701: Allow dropping remote files to network drives (and floppy drives) + Allow excluding certain drive letters from monitoring for dropped files + Better error message when drop target cannot be detected and drag&drop shell extension is not available
Source commit: 57d195f901e30a72e4e8dfaa45be586c5118334e
This commit is contained in:
@@ -7189,7 +7189,14 @@ void __fastcall TCustomScpExplorerForm::RemoteFileControlDDEnd(TObject * Sender)
|
||||
// as it is checked as soon as drag&drop starts from
|
||||
// RemoteFileControlDDCreateDragFileList
|
||||
Configuration->Usage->Inc(L"DownloadsDragDropExternalExtTargetUnknown");
|
||||
throw ExtException(NULL, LoadStr(DRAGEXT_TARGET_UNKNOWN2), HELP_DRAGEXT_TARGET_UNKNOWN);
|
||||
if (!WinConfiguration->DDExtInstalled || WinConfiguration->IsDDExtBroken())
|
||||
{
|
||||
throw ExtException(NULL, LoadStr(DD_TARGET_UNKNOWN), HELP_DD_TARGET_UNKNOWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ExtException(NULL, LoadStr(DRAGEXT_TARGET_UNKNOWN2), HELP_DRAGEXT_TARGET_UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -288,6 +288,7 @@ void __fastcall TPreferencesDialog::LoadConfiguration()
|
||||
|
||||
DDFakeFileEnabledButton->Checked = WinConfiguration->DDFakeFile;
|
||||
DDFakeFileDisabledButton->Checked = !DDFakeFileEnabledButton->Checked;
|
||||
DDDrivesMemo->Lines->CommaText = WinConfiguration->DDDrives;
|
||||
|
||||
if (WinConfiguration->DDTemporaryDirectory.IsEmpty())
|
||||
{
|
||||
@@ -663,6 +664,7 @@ void __fastcall TPreferencesDialog::SaveConfiguration()
|
||||
BOOLPROP(BalloonNotifications);
|
||||
|
||||
WinConfiguration->DDFakeFile = DDFakeFileEnabledButton->Checked;
|
||||
WinConfiguration->DDDrives = DDDrivesMemo->Lines->CommaText;
|
||||
|
||||
if (DDSystemTemporaryDirectoryButton->Checked)
|
||||
{
|
||||
@@ -1230,15 +1232,17 @@ void __fastcall TPreferencesDialog::UpdateControls()
|
||||
else if (!WinConfiguration->IsDDExtRunning())
|
||||
{
|
||||
DragExtStatusLabel->Caption = LoadStr(PREFERENCES_DRAGEXT_NOT_RUNNING);
|
||||
DragExtStatusLabel->Enabled = true;
|
||||
DragExtStatusLabel->Enabled = DDFakeFileEnabledButton->Checked;
|
||||
DragExtStatusLabel->Font->Color = clGrayText;
|
||||
}
|
||||
else
|
||||
{
|
||||
DragExtStatusLabel->Caption = LoadStr(PREFERENCES_DRAGEXT_RUNNING);
|
||||
DragExtStatusLabel->Enabled = true;
|
||||
DragExtStatusLabel->Enabled = DDFakeFileEnabledButton->Checked;
|
||||
DragExtStatusLabel->Font->Color = clWindowText;
|
||||
}
|
||||
EnableControl(DDDrivesMemo, DDFakeFileEnabledButton->Checked);
|
||||
EnableControl(DDDrivesLabel, DDDrivesMemo->Enabled);
|
||||
EnableControl(DDFakeFileDisabledPanel, DDFakeFileDisabledButton->Checked);
|
||||
EnableControl(DDTemporaryDirectoryEdit, DDCustomTemporaryDirectoryButton->Enabled &&
|
||||
DDCustomTemporaryDirectoryButton->Checked);
|
||||
|
||||
@@ -1313,13 +1313,13 @@ object PreferencesDialog: TPreferencesDialog
|
||||
Left = 8
|
||||
Top = 8
|
||||
Width = 389
|
||||
Height = 230
|
||||
Height = 310
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
Caption = 'Drag && Drop downloads'
|
||||
TabOrder = 0
|
||||
DesignSize = (
|
||||
389
|
||||
230)
|
||||
310)
|
||||
object DDFakeFileEnabledLabel: TLabel
|
||||
Left = 35
|
||||
Top = 44
|
||||
@@ -1337,7 +1337,7 @@ object PreferencesDialog: TPreferencesDialog
|
||||
end
|
||||
object DDFakeFileDisabledLabel: TLabel
|
||||
Left = 35
|
||||
Top = 141
|
||||
Top = 221
|
||||
Width = 346
|
||||
Height = 54
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
@@ -1352,14 +1352,21 @@ object PreferencesDialog: TPreferencesDialog
|
||||
object DragExtStatusLabel: TLabel
|
||||
Left = 35
|
||||
Top = 96
|
||||
Width = 345
|
||||
Height = 26
|
||||
Width = 95
|
||||
Height = 13
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
AutoSize = False
|
||||
Caption = 'DragExtStatusLabel'
|
||||
WordWrap = True
|
||||
OnClick = DDLabelClick
|
||||
end
|
||||
object DDDrivesLabel: TLabel
|
||||
Left = 35
|
||||
Top = 116
|
||||
Width = 246
|
||||
Height = 13
|
||||
AutoSize = False
|
||||
Caption = 'Allow dropping files to these &network drives:'
|
||||
FocusControl = DDDrivesMemo
|
||||
end
|
||||
object DDFakeFileEnabledButton: TRadioButton
|
||||
Left = 16
|
||||
Top = 24
|
||||
@@ -1372,7 +1379,7 @@ object PreferencesDialog: TPreferencesDialog
|
||||
end
|
||||
object DDFakeFileDisabledButton: TRadioButton
|
||||
Left = 16
|
||||
Top = 121
|
||||
Top = 202
|
||||
Width = 356
|
||||
Height = 17
|
||||
Anchors = [akLeft, akTop, akRight]
|
||||
@@ -1382,7 +1389,7 @@ object PreferencesDialog: TPreferencesDialog
|
||||
end
|
||||
object DDFakeFileDisabledPanel: TPanel
|
||||
Left = 34
|
||||
Top = 192
|
||||
Top = 272
|
||||
Width = 315
|
||||
Height = 28
|
||||
BevelOuter = bvNone
|
||||
@@ -1401,6 +1408,16 @@ object PreferencesDialog: TPreferencesDialog
|
||||
OnClick = ControlChange
|
||||
end
|
||||
end
|
||||
object DDDrivesMemo: TMemo
|
||||
Left = 34
|
||||
Top = 132
|
||||
Width = 337
|
||||
Height = 61
|
||||
Lines.Strings = (
|
||||
'DDDrivesMemo')
|
||||
ScrollBars = ssVertical
|
||||
TabOrder = 3
|
||||
end
|
||||
end
|
||||
end
|
||||
object QueueSheet: TTabSheet
|
||||
|
||||
@@ -320,6 +320,8 @@ __published:
|
||||
TCheckBox *NaturalOrderNumericalSortingCheck;
|
||||
TLabel *DragExtStatusLabel;
|
||||
TCheckBox *SynchronizeSummaryCheck;
|
||||
TMemo *DDDrivesMemo;
|
||||
TLabel *DDDrivesLabel;
|
||||
void __fastcall FormShow(TObject *Sender);
|
||||
void __fastcall ControlChange(TObject *Sender);
|
||||
void __fastcall EditorFontButtonClick(TObject *Sender);
|
||||
|
||||
@@ -62,5 +62,6 @@
|
||||
#define HELP_LOGIN_AUTHORIZED_KEYS "guide_public_key"
|
||||
#define HELP_READONLY_INI_FILE "config#ini_readonly"
|
||||
#define HELP_SESSION_RENAME "task_connection"
|
||||
#define HELP_DD_TARGET_UNKNOWN "dragdrop_download"
|
||||
|
||||
#endif // TextsWin
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
#define EXTENSION_INSTALLED_ALREADY 1206
|
||||
#define EXTENSION_LOAD_ERROR 1207
|
||||
#define NO_SITE_FOR_COMMAND 1208
|
||||
#define DD_TARGET_UNKNOWN 1209
|
||||
|
||||
#define WIN_CONFIRMATION_STRINGS 1300
|
||||
#define CONFIRM_OVERWRITE_SESSION 1301
|
||||
|
||||
@@ -97,6 +97,7 @@ BEGIN
|
||||
EXTENSION_INSTALLED_ALREADY, "The extension is installed already."
|
||||
EXTENSION_LOAD_ERROR, "Error loading an extension from \"%s\"."
|
||||
NO_SITE_FOR_COMMAND, "**No session is opened**\nThe selected command has site-specific options, but no session is opened."
|
||||
DD_TARGET_UNKNOWN, "**WinSCP was not able to detect a folder, where the dragged file(s) was dropped.** In the default drag&drop mode, WinSCP allows dropping files only to local drives and mapped nework drives.\n\nYou can allow dropping files to other targets in preferences. Press Help button for details."
|
||||
|
||||
WIN_CONFIRMATION_STRINGS, "WIN_CONFIRMATION"
|
||||
CONFIRM_OVERWRITE_SESSION, "Site with name '%s' already exists. Overwrite?"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <Common.h>
|
||||
|
||||
#include "GUITools.h"
|
||||
#include "GUIConfiguration.h"
|
||||
#include "WinConfiguration.h"
|
||||
#include <TextsCore.h>
|
||||
#include <CoreMain.h>
|
||||
#include <SessionData.h>
|
||||
@@ -284,31 +284,62 @@ void __fastcall ExecuteTool(const UnicodeString & Name)
|
||||
//---------------------------------------------------------------------------
|
||||
TObjectList * StartCreationDirectoryMonitorsOnEachDrive(unsigned int Filter, TFileChangedEvent OnChanged)
|
||||
{
|
||||
std::unique_ptr<TObjectList> Result(new TObjectList());
|
||||
std::unique_ptr<TStrings> Drives(new TStringList());
|
||||
|
||||
std::unique_ptr<TStrings> DDDrives(new TStringList());
|
||||
DDDrives->CommaText = WinConfiguration->DDDrives;
|
||||
UnicodeString ExcludedDrives;
|
||||
for (int Index = 0; Index < DDDrives->Count; Index++)
|
||||
{
|
||||
UnicodeString S = Trim(DDDrives->Strings[Index]);
|
||||
if (!S.IsEmpty() && (S[1] == L'-'))
|
||||
{
|
||||
S = Trim(S.SubString(2, S.Length() - 1));
|
||||
if (!S.IsEmpty())
|
||||
{
|
||||
ExcludedDrives += S[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Drives->Add(S);
|
||||
}
|
||||
}
|
||||
|
||||
for (char Drive = FirstDrive; Drive <= LastDrive; Drive++)
|
||||
{
|
||||
std::unique_ptr<TDirectoryMonitor> Monitor(new TDirectoryMonitor(Application));
|
||||
TDriveInfoRec * DriveInfoRec = DriveInfo->Get(Drive);
|
||||
if (DriveInfoRec->Valid &&
|
||||
(DriveInfoRec->DriveType != DRIVE_CDROM) &&
|
||||
((DriveInfoRec->DriveType != DRIVE_REMOVABLE) || (Drive >= FirstFixedDrive)))
|
||||
if (ExcludedDrives.Pos(Drive) == 0)
|
||||
{
|
||||
try
|
||||
TDriveInfoRec * DriveInfoRec = DriveInfo->Get(Drive);
|
||||
if (DriveInfoRec->Valid &&
|
||||
(DriveInfoRec->DriveType != DRIVE_CDROM) &&
|
||||
((DriveInfoRec->DriveType != DRIVE_REMOVABLE) || (Drive >= FirstFixedDrive)))
|
||||
{
|
||||
Monitor->Path = DriveInfo->GetDriveRoot(Drive);
|
||||
Monitor->WatchSubtree = true;
|
||||
Monitor->WatchFilters = Filter;
|
||||
Monitor->OnCreated = OnChanged;
|
||||
Monitor->OnModified = OnChanged;
|
||||
Monitor->Active = true;
|
||||
Result->Add(Monitor.release());
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
// Ignore errors watching not-ready drives
|
||||
Drives->Add(Drive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TObjectList> Result(new TObjectList());
|
||||
for (int Index = 0; Index < Drives->Count; Index++)
|
||||
{
|
||||
UnicodeString Drive = Drives->Strings[Index];
|
||||
std::unique_ptr<TDirectoryMonitor> Monitor(new TDirectoryMonitor(Application));
|
||||
try
|
||||
{
|
||||
Monitor->Path = DriveInfo->GetDriveRoot(Drive);
|
||||
Monitor->WatchSubtree = true;
|
||||
Monitor->WatchFilters = Filter;
|
||||
Monitor->OnCreated = OnChanged;
|
||||
Monitor->OnModified = OnChanged;
|
||||
Monitor->Active = true;
|
||||
Result->Add(Monitor.release());
|
||||
}
|
||||
catch (Exception & E)
|
||||
{
|
||||
// Ignore errors watching not-ready drives
|
||||
}
|
||||
}
|
||||
return Result.release();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -491,6 +491,7 @@ void __fastcall TWinConfiguration::Default()
|
||||
|
||||
FDDTransferConfirmation = asAuto;
|
||||
FDDTemporaryDirectory = L"";
|
||||
FDDDrives = L"";
|
||||
FDDWarnLackOfTempSpace = true;
|
||||
FDDWarnLackOfTempSpaceRatio = 1.1;
|
||||
FDDFakeFile = true;
|
||||
@@ -895,6 +896,7 @@ THierarchicalStorage * TWinConfiguration::CreateScpStorage(bool & SessionList)
|
||||
KEY(Bool, CopyOnDoubleClickConfirmation); \
|
||||
KEYEX(Integer, DDTransferConfirmation, L"DDTransferConfirmation2"); \
|
||||
KEY(String, DDTemporaryDirectory); \
|
||||
KEY(String, DDDrives); \
|
||||
KEY(Bool, DDWarnLackOfTempSpace); \
|
||||
KEY(Float, DDWarnLackOfTempSpaceRatio); \
|
||||
KEY(Bool, DeleteToRecycleBin); \
|
||||
@@ -1831,6 +1833,11 @@ void __fastcall TWinConfiguration::SetDDTemporaryDirectory(UnicodeString value)
|
||||
SET_CONFIG_PROPERTY(DDTemporaryDirectory);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::SetDDDrives(UnicodeString value)
|
||||
{
|
||||
SET_CONFIG_PROPERTY(DDDrives);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWinConfiguration::SetDDFakeFile(bool value)
|
||||
{
|
||||
SET_CONFIG_PROPERTY(DDFakeFile);
|
||||
|
||||
@@ -353,6 +353,7 @@ private:
|
||||
bool FUseLocationProfiles;
|
||||
bool FUseSharedBookmarks;
|
||||
UnicodeString FDDTemporaryDirectory;
|
||||
UnicodeString FDDDrives;
|
||||
bool FDDWarnLackOfTempSpace;
|
||||
bool FDDFakeFile;
|
||||
int FDDExtInstalled;
|
||||
@@ -461,6 +462,7 @@ private:
|
||||
void __fastcall SetUseLocationProfiles(bool value);
|
||||
void __fastcall SetUseSharedBookmarks(bool value);
|
||||
void __fastcall SetDDTemporaryDirectory(UnicodeString value);
|
||||
void __fastcall SetDDDrives(UnicodeString value);
|
||||
void __fastcall SetDDWarnLackOfTempSpace(bool value);
|
||||
void __fastcall SetDDFakeFile(bool value);
|
||||
void __fastcall SetDDExtTimeout(int value);
|
||||
@@ -646,6 +648,7 @@ public:
|
||||
__property bool UseLocationProfiles = { read = FUseLocationProfiles, write = SetUseLocationProfiles};
|
||||
__property bool UseSharedBookmarks = { read = FUseSharedBookmarks, write = SetUseSharedBookmarks};
|
||||
__property UnicodeString DDTemporaryDirectory = { read=FDDTemporaryDirectory, write=SetDDTemporaryDirectory };
|
||||
__property UnicodeString DDDrives = { read=FDDDrives, write=SetDDDrives };
|
||||
__property bool DDWarnLackOfTempSpace = { read=FDDWarnLackOfTempSpace, write=SetDDWarnLackOfTempSpace };
|
||||
__property bool DDFakeFile = { read=FDDFakeFile, write=SetDDFakeFile };
|
||||
__property bool DDExtInstalled = { read=GetDDExtInstalled };
|
||||
|
||||
Reference in New Issue
Block a user