Skip to content

Commit

Permalink
Bug 2209: Improve behavior when moving/renaming over an existing folder
Browse files Browse the repository at this point in the history
https://winscp.net/tracker/2209

Source commit: d7a7d5b2efeb6d81bafe7e18f60457fdbd4e11d1
  • Loading branch information
martinprikryl committed Aug 6, 2023
1 parent d506d44 commit 52cf67f
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 24 deletions.
2 changes: 1 addition & 1 deletion source/core/ScpFileSystem.cpp
Expand Up @@ -1736,7 +1736,7 @@ void __fastcall TSCPFileSystem::CopyToRemote(TStrings * FilesToCopy,
unsigned int Answer;
if (File->IsDirectory)
{
UnicodeString Message = FMTLOAD(DIRECTORY_OVERWRITE, (FileNameOnly));
UnicodeString Message = MainInstructions(FMTLOAD(DIRECTORY_OVERWRITE, (FileNameOnly)));
TQueryParams QueryParams(qpNeverAskAgainCheck);

TSuspendFileOperationProgress Suspend(OperationProgress);
Expand Down
11 changes: 7 additions & 4 deletions source/core/Terminal.cpp
Expand Up @@ -4853,18 +4853,21 @@ bool __fastcall TTerminal::DoRenameFile(
if (DuplicateFile.get() != NULL)
{
UnicodeString QuestionFmt;
TQueryType QueryType;
if (DuplicateFile->IsDirectory)
{
QuestionFmt = LoadStr(DIRECTORY_OVERWRITE);
QuestionFmt = MainInstructions(LoadStr(DIRECTORY_OVERWRITE)) + LoadStr(DIRECTORY_OVERWRITE_WARNING);
QueryType = qtWarning;
}
else
{
QuestionFmt = LoadStr(FILE_OVERWRITE);
QuestionFmt = MainInstructions(LoadStr(FILE_OVERWRITE));
QueryType = qtConfirmation;
}
TQueryParams Params(qpNeverAskAgainCheck);
UnicodeString Question = MainInstructions(FORMAT(QuestionFmt, (NewName)));
UnicodeString Question = FORMAT(QuestionFmt, (NewName));
unsigned int Answers = qaYes | qaNo | FLAGMASK(OperationProgress != NULL, qaCancel) | FLAGMASK(IsBatchMove, qaYesToAll | qaNoToAll);
unsigned int Answer = QueryUser(Question, NULL, Answers, &Params);
unsigned int Answer = QueryUser(Question, NULL, Answers, &Params, QueryType);
switch (Answer)
{
case qaNeverAskAgain:
Expand Down
16 changes: 12 additions & 4 deletions source/forms/Custom.cpp
Expand Up @@ -802,7 +802,7 @@ bool __fastcall DoShortCutDialog(TShortCut & ShortCut,
class TRemoteMoveDialog : public TCustomDialog
{
public:
__fastcall TRemoteMoveDialog(bool Multi);
__fastcall TRemoteMoveDialog(bool Multi, TDirectoryExistsEvent OnDirectoryExists);

bool __fastcall Execute(UnicodeString & Target, UnicodeString & FileMask);

Expand All @@ -814,16 +814,18 @@ class TRemoteMoveDialog : public TCustomDialog
private:
THistoryComboBox * Combo;
bool FMulti;
TDirectoryExistsEvent FOnDirectoryExists;
};
//---------------------------------------------------------------------------
__fastcall TRemoteMoveDialog::TRemoteMoveDialog(bool Multi) :
__fastcall TRemoteMoveDialog::TRemoteMoveDialog(bool Multi, TDirectoryExistsEvent OnDirectoryExists) :
TCustomDialog(HELP_REMOTE_MOVE)
{
Caption = LoadStr(REMOTE_MOVE_TITLE);
// The same as TRemoteTransferDialog
ClientWidth = ScaleByTextHeight(this, 420);

FMulti = Multi;
FOnDirectoryExists = OnDirectoryExists;

AddImage(L"Move L to R");

Expand Down Expand Up @@ -860,6 +862,11 @@ void __fastcall TRemoteMoveDialog::DoShow()
//---------------------------------------------------------------------------
void __fastcall TRemoteMoveDialog::DoValidate()
{
if (FOnDirectoryExists(NULL, Combo->Text))
{
Combo->Text = UnixCombinePaths(Combo->Text, AnyMask);
}

if (!IsFileNameMask(GetFileMask()) && FMulti)
{
UnicodeString Message =
Expand All @@ -873,9 +880,10 @@ void __fastcall TRemoteMoveDialog::DoValidate()
TCustomDialog::DoValidate();
}
//---------------------------------------------------------------------------
bool __fastcall DoRemoteMoveDialog(bool Multi, UnicodeString & Target, UnicodeString & FileMask)
bool __fastcall DoRemoteMoveDialog(
bool Multi, UnicodeString & Target, UnicodeString & FileMask, TDirectoryExistsEvent OnDirectoryExists)
{
std::unique_ptr<TRemoteMoveDialog> Dialog(new TRemoteMoveDialog(Multi));
std::unique_ptr<TRemoteMoveDialog> Dialog(new TRemoteMoveDialog(Multi, OnDirectoryExists));
return Dialog->Execute(Target, FileMask);
}
//---------------------------------------------------------------------------
Expand Down
17 changes: 15 additions & 2 deletions source/forms/CustomScpExplorer.cpp
Expand Up @@ -4450,6 +4450,18 @@ void __fastcall TCustomScpExplorerForm::LockFiles(TStrings * FileList, bool Lock
RemoteDirView->RestoreSelection();
}
//---------------------------------------------------------------------------
bool TCustomScpExplorerForm::DoDirectoryExists(void * Session, const UnicodeString & Directory)
{
bool Result = false;
TTerminal * ATerminal = (Session == NULL) ? Terminal : reinterpret_cast<TTerminal *>(Session);
if (IsActiveTerminal(ATerminal))
{
std::unique_ptr<TRemoteFile> File(ATerminal->TryReadFile(Directory));
Result = File && File->IsDirectory;
}
return Result;
}
//---------------------------------------------------------------------------
bool __fastcall TCustomScpExplorerForm::RemoteTransferDialog(TManagedTerminal *& Session,
TStrings * FileList, UnicodeString & Target, UnicodeString & FileMask, bool & DirectCopy,
bool NoConfirmation, bool Move)
Expand Down Expand Up @@ -4501,7 +4513,7 @@ bool __fastcall TCustomScpExplorerForm::RemoteTransferDialog(TManagedTerminal *&

if (Move)
{
Result = DoRemoteMoveDialog(Multi, Target, FileMask);
Result = DoRemoteMoveDialog(Multi, Target, FileMask, DoDirectoryExists);
}
else
{
Expand Down Expand Up @@ -4537,7 +4549,8 @@ bool __fastcall TCustomScpExplorerForm::RemoteTransferDialog(TManagedTerminal *&
}
void * ASession = Session;
Result = DoRemoteCopyDialog(
Sessions.get(), Directories.get(), AllowDirectCopy, Multi, ASession, Target, FileMask, DirectCopy, Terminal);
Sessions.get(), Directories.get(), AllowDirectCopy, Multi, ASession, Target, FileMask, DirectCopy, Terminal,
DoDirectoryExists);
Session = static_cast<TManagedTerminal *>(ASession);
}
}
Expand Down
1 change: 1 addition & 0 deletions source/forms/CustomScpExplorer.h
Expand Up @@ -755,6 +755,7 @@ friend class TEditorUploadQueueItem;
void __fastcall FileDeleted(TOperationSide Side, const UnicodeString & FileName, bool Success);
void LoadFilesProperties(TStrings * FileList);
void PasteFiles();
bool DoDirectoryExists(void * Session, const UnicodeString & Directory);

public:
virtual __fastcall ~TCustomScpExplorerForm();
Expand Down
27 changes: 20 additions & 7 deletions source/forms/RemoteTransfer.cpp
Expand Up @@ -16,15 +16,16 @@
#pragma link "HistoryComboBox"
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
bool __fastcall DoRemoteCopyDialog(TStrings * Sessions, TStrings * Directories,
bool __fastcall DoRemoteCopyDialog(
TStrings * Sessions, TStrings * Directories,
TDirectRemoteCopy AllowDirectCopy, bool Multi, void *& Session, UnicodeString & Target, UnicodeString & FileMask,
bool & DirectCopy, void * CurrentSession)
bool & DirectCopy, void * CurrentSession, TDirectoryExistsEvent OnDirectoryExists)
{
bool Result;
TRemoteTransferDialog * Dialog = SafeFormCreate<TRemoteTransferDialog>();
try
{
Dialog->Init(Multi, Sessions, Directories, AllowDirectCopy, CurrentSession);
Dialog->Init(Multi, Sessions, Directories, AllowDirectCopy, CurrentSession, OnDirectoryExists);
Result = Dialog->Execute(Session, Target, FileMask, DirectCopy);
}
__finally
Expand All @@ -42,8 +43,9 @@ __fastcall TRemoteTransferDialog::TRemoteTransferDialog(TComponent * Owner)
Caption = LoadStr(REMOTE_COPY_TITLE);
}
//---------------------------------------------------------------------------
void __fastcall TRemoteTransferDialog::Init(bool Multi, TStrings * Sessions,
TStrings * Directories, TDirectRemoteCopy AllowDirectCopy, void * CurrentSession)
void __fastcall TRemoteTransferDialog::Init(
bool Multi, TStrings * Sessions, TStrings * Directories, TDirectRemoteCopy AllowDirectCopy, void * CurrentSession,
TDirectoryExistsEvent OnDirectoryExists)
{
FMulti = Multi;
SessionCombo->Items = Sessions;
Expand All @@ -52,6 +54,7 @@ void __fastcall TRemoteTransferDialog::Init(bool Multi, TStrings * Sessions,
DebugAssert(SessionCombo->Items->Count == FDirectories->Count);
FAllowDirectCopy = AllowDirectCopy;
FCurrentSession = CurrentSession;
FOnDirectoryExists = OnDirectoryExists;
LoadDialogImage(Image, L"Duplicate L to R");
}
//---------------------------------------------------------------------------
Expand All @@ -73,7 +76,7 @@ bool __fastcall TRemoteTransferDialog::Execute(void *& Session, UnicodeString &
bool Result = (ShowModal() == DefaultResult(this));
if (Result)
{
Session = SessionCombo->Items->Objects[SessionCombo->ItemIndex];
Session = GetSelectedSession();
CustomWinConfiguration->History[L"RemoteTarget"] = DirectoryEdit->Items;
Target = UnixExtractFilePath(DirectoryEdit->Text);
FileMask = GetFileMask();
Expand Down Expand Up @@ -139,6 +142,11 @@ void __fastcall TRemoteTransferDialog::FormCloseQuery(TObject * /*Sender*/,
{
if (ModalResult == DefaultResult(this))
{
if (FOnDirectoryExists(GetSelectedSession(), DirectoryEdit->Text))
{
DirectoryEdit->Text = UnixCombinePaths(DirectoryEdit->Text, AnyMask);
}

if (!IsFileNameMask(GetFileMask()) && FMulti)
{
UnicodeString Message =
Expand Down Expand Up @@ -178,8 +186,13 @@ void __fastcall TRemoteTransferDialog::NotDirectCopyCheckClick(
}
}
//---------------------------------------------------------------------------
void * TRemoteTransferDialog::GetSelectedSession()
{
return SessionCombo->Items->Objects[SessionCombo->ItemIndex];
}
//---------------------------------------------------------------------------
bool __fastcall TRemoteTransferDialog::IsCurrentSessionSelected()
{
return (SessionCombo->Items->Objects[SessionCombo->ItemIndex] == FCurrentSession);
return (GetSelectedSession() == FCurrentSession);
}
//---------------------------------------------------------------------------
7 changes: 5 additions & 2 deletions source/forms/RemoteTransfer.h
Expand Up @@ -33,15 +33,17 @@ class TRemoteTransferDialog : public TForm
public:
__fastcall TRemoteTransferDialog(TComponent * Owner);

void __fastcall Init(bool Multi, TStrings * Sessions, TStrings * Directories,
TDirectRemoteCopy AllowDirectCopy, void * CurrentSession);
void __fastcall Init(
bool Multi, TStrings * Sessions, TStrings * Directories, TDirectRemoteCopy AllowDirectCopy, void * CurrentSession,
TDirectoryExistsEvent OnDirectoryExists);
bool __fastcall Execute(void *& Session, UnicodeString & Target,
UnicodeString & FileMask, bool & DirectCopy);

protected:
void __fastcall UpdateControls();
UnicodeString __fastcall GetFileMask();
bool __fastcall IsCurrentSessionSelected();
void * GetSelectedSession();
void __fastcall UpdateNotDirectCopyCheck();

private:
Expand All @@ -50,6 +52,7 @@ class TRemoteTransferDialog : public TForm
bool FDirectCopy;
bool FMulti;
TDirectRemoteCopy FAllowDirectCopy;
TDirectoryExistsEvent FOnDirectoryExists;

INTERFACE_HOOK;
};
Expand Down
1 change: 1 addition & 0 deletions source/resource/TextsCore.h
Expand Up @@ -346,6 +346,7 @@
#define PROXY_AUTH_TITLE 363
#define PROXY_AUTH_USERNAME_PROMPT 364
#define PROXY_AUTH_PASSWORD_PROMPT 365
#define DIRECTORY_OVERWRITE_WARNING 366

#define CORE_INFORMATION_STRINGS 400
#define YES_STR 401
Expand Down
1 change: 1 addition & 0 deletions source/resource/TextsCore1.rc
Expand Up @@ -315,6 +315,7 @@ BEGIN
PROXY_AUTH_TITLE, "Proxy authentication"
PROXY_AUTH_USERNAME_PROMPT, "Proxy &username:"
PROXY_AUTH_PASSWORD_PROMPT, "Proxy &password:"
DIRECTORY_OVERWRITE_WARNING, "All files in the target directory will be deleted!"

CORE_INFORMATION_STRINGS, "CORE_INFORMATION"
YES_STR, "Yes"
Expand Down
11 changes: 7 additions & 4 deletions source/windows/WinInterface.h
Expand Up @@ -324,11 +324,14 @@ bool __fastcall DoPropertiesDialog(TStrings * FileList,
int AllowedChanges, bool UserGroupByID, TCalculateSizeEvent OnCalculateSize,
TCalculateChecksumEvent OnCalculateChecksum);

bool __fastcall DoRemoteMoveDialog(bool Multi, UnicodeString & Target, UnicodeString & FileMask);
typedef bool (__closure * TDirectoryExistsEvent)(void * Session, const UnicodeString & Directory);
bool __fastcall DoRemoteMoveDialog(
bool Multi, UnicodeString & Target, UnicodeString & FileMask, TDirectoryExistsEvent OnDirectoryExists);
enum TDirectRemoteCopy { drcDisallow, drcAllow, drcConfirmCommandSession };
bool __fastcall DoRemoteCopyDialog(TStrings * Sessions, TStrings * Directories,
TDirectRemoteCopy AllowDirectCopy, bool Multi, void *& Session,
UnicodeString & Target, UnicodeString & FileMask, bool & DirectCopy, void * CurrentSession);
bool __fastcall DoRemoteCopyDialog(
TStrings * Sessions, TStrings * Directories,
TDirectRemoteCopy AllowDirectCopy, bool Multi, void *& Session, UnicodeString & Target, UnicodeString & FileMask,
bool & DirectCopy, void * CurrentSession, TDirectoryExistsEvent OnDirectoryExists);

// forms\SelectMask.cpp
bool __fastcall DoSelectMaskDialog(TControl * Parent, bool Select, TFileFilter & Filter);
Expand Down

0 comments on commit 52cf67f

Please sign in to comment.