1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00
Files
winscp/source/forms/Copy.cpp

574 lines
18 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <Common.h>
#include <WinInterface.h>
#include <CoreMain.h>
#include <TextsWin.h>
#include <VCLCommon.h>
#include <CustomWinConfiguration.h>
#include <Tools.h>
#include <GUITools.h>
#include "Copy.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "Rights"
#pragma link "CopyParams"
#pragma link "HistoryComboBox"
#ifndef NO_RESOURCES
#pragma resource "*.dfm"
#endif
//---------------------------------------------------------------------------
bool __fastcall DoCopyDialog(bool ToRemote,
bool Move, TStrings * FileList, UnicodeString & TargetDirectory,
TGUICopyParamType * Params, int Options, int CopyParamAttrs, TSessionData * SessionData,
int * OutputOptions)
{
bool Result;
TCopyDialog *CopyDialog = new TCopyDialog(Application, ToRemote, Move, FileList, Options, CopyParamAttrs, SessionData);
try
{
if (FLAGSET(CopyParamAttrs, cpaNoTransferMode))
{
// If local and remote EOL types are the same, there is no need
// for ASCII (or Automatic) mode
Params->TransferMode = tmBinary;
}
if (OutputOptions != NULL)
{
CopyDialog->OutputOptions = *OutputOptions;
}
CopyDialog->Directory = TargetDirectory;
CopyDialog->Params = *Params;
Result = CopyDialog->Execute();
if (Result)
{
TargetDirectory = CopyDialog->Directory;
*Params = CopyDialog->Params;
if (OutputOptions != NULL)
{
*OutputOptions = CopyDialog->OutputOptions;
}
}
}
__finally
{
delete CopyDialog;
}
return Result;
}
//---------------------------------------------------------------------------
__fastcall TCopyDialog::TCopyDialog(
TComponent* Owner, bool ToRemote, bool Move, TStrings * FileList, int Options,
int CopyParamAttrs, TSessionData * SessionData) : TForm(Owner)
{
FToRemote = ToRemote;
FMove = Move;
FOptions = Options;
FCopyParamAttrs = CopyParamAttrs;
FFileList = FileList;
FSessionData = SessionData;
FOutputOptions = 0;
AdjustControls();
FPresetsMenu = new TPopupMenu(this);
HotTrackLabel(CopyParamLabel);
CopyParamListButton(TransferSettingsButton);
HotTrackLabel(ShortCutHintLabel);
UseSystemSettings(this);
}
//---------------------------------------------------------------------------
__fastcall TCopyDialog::~TCopyDialog()
{
delete FPresetsMenu;
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::AdjustTransferControls()
{
if (FFileList && FFileList->Count)
{
if (!FToRemote && !FMove && FLAGSET(FOutputOptions, cooRemoteTransfer))
{
UnicodeString Label;
if (FFileList->Count == 1)
{
UnicodeString FileName;
if (!FToRemote) FileName = UnixExtractFileName(FFileList->Strings[0]);
else FileName = ExtractFileName(FFileList->Strings[0]);
Label = FMTLOAD(REMOTE_COPY_FILE, (FileName));
}
else
{
Label = FMTLOAD(REMOTE_COPY_FILES, (FFileList->Count));
}
DirectoryLabel->Caption = Label;
}
else
{
UnicodeString TransferStr =
LoadStr(RemotePaths() ? COPY_COPY_TOREMOTE : COPY_COPY_TOLOCAL);
// currently the copy dialog is shown when downloading to temp folder
// only for drag&drop downloads, for we dare to display d&d specific prompt
UnicodeString DirectionStr =
LoadStr(((FOptions & coTemp) != 0) ? COPY_TODROP :
(RemotePaths() ? COPY_TOREMOTE : COPY_TOLOCAL));
if (FFileList->Count == 1)
{
UnicodeString FileName;
if (!FToRemote) FileName = UnixExtractFileName(FFileList->Strings[0]);
else FileName = ExtractFileName(FFileList->Strings[0]);
DirectoryLabel->Caption = FMTLOAD((FMove ? MOVE_FILE : COPY_FILE),
(TransferStr, FileName, DirectionStr));
}
else
{
DirectoryLabel->Caption = FMTLOAD((FMove ? MOVE_FILES : COPY_FILES),
(TransferStr, FFileList->Count, DirectionStr));
}
}
}
UnicodeString ImageName;
UnicodeString ACaption;
if (!FMove)
{
if (!FToRemote && FLAGSET(FOutputOptions, cooRemoteTransfer))
{
ACaption = LoadStr(REMOTE_COPY_TITLE);
ImageName = L"Duplicate";
}
else
{
if (RemotePaths())
{
ACaption = LoadStr(COPY_COPY_TOREMOTE_CAPTION);
ImageName = L"Upload File";
}
else
{
ACaption = LoadStr(COPY_COPY_TOLOCAL_CAPTION);
ImageName = L"Download File";
}
}
}
else
{
if (!FToRemote && FLAGSET(FOutputOptions, cooRemoteTransfer))
{
ACaption = LoadStr(COPY_MOVE_CAPTION);
ImageName = L"Move To";
}
else
{
if (RemotePaths())
{
ACaption = LoadStr(COPY_MOVE_TOREMOTE_CAPTION);
ImageName = L"Upload File Remove Original";
}
else
{
ACaption = LoadStr(COPY_MOVE_TOLOCAL_CAPTION);
ImageName = L"Download File Remove Original";
}
}
}
Caption = FormatFormCaption(this, ACaption);
LoadDialogImage(Image, ImageName);
bool RemoteTransfer = FLAGSET(FOutputOptions, cooRemoteTransfer);
DebugAssert(FLAGSET(FOptions, coAllowRemoteTransfer) || !RemoteTransfer);
EnableControl(TransferSettingsButton, !RemoteTransfer);
EnableControl(CopyParamGroup, !RemoteTransfer);
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::AdjustControls()
{
RemoteDirectoryEdit->Visible = false;
LocalDirectoryEdit->Visible = false;
DirectoryEdit->Visible = FLAGCLEAR(FOptions, coTemp);
EnableControl(DirectoryEdit, FLAGCLEAR(FOptions, coDisableDirectory));
EnableControl(DirectoryLabel, DirectoryEdit->Enabled);
EnableControl(LocalDirectoryBrowseButton, DirectoryEdit->Enabled);
DirectoryLabel->FocusControl = DirectoryEdit;
UnicodeString QueueLabel = LoadStr(COPY_BACKGROUND);
if (FLAGCLEAR(FOptions, coNoQueue))
{
QueueLabel = FMTLOAD(COPY_QUEUE, (QueueLabel));
}
QueueCheck2->Caption = QueueLabel;
AdjustTransferControls();
LocalDirectoryBrowseButton->Visible = !FToRemote &&
FLAGCLEAR(FOptions, coTemp);
if (FLAGCLEAR(FOptions, coDoNotShowAgain))
{
NeverShowAgainCheck->Visible = false;
ClientHeight = ClientHeight -
(ShortCutHintPanel->Top - NeverShowAgainCheck->Top);
}
if (FLAGCLEAR(FOptions, coShortCutHint) || CustomWinConfiguration->CopyShortCutHintShown)
{
ShortCutHintPanel->Visible = false;
ClientHeight = ClientHeight - ShortCutHintPanel->Height;
}
UpdateControls();
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::SetOutputOptions(int value)
{
if (OutputOptions != value)
{
FSaveSettings = FLAGSET(value, cooSaveSettings);
NeverShowAgainCheck->Checked = FLAGSET(value, cooDoNotShowAgain);
FOutputOptions = (value & ~(cooDoNotShowAgain | cooSaveSettings));
}
}
//---------------------------------------------------------------------------
int __fastcall TCopyDialog::GetOutputOptions()
{
return FOutputOptions |
FLAGMASK(FSaveSettings, cooSaveSettings) |
FLAGMASK(NeverShowAgainCheck->Checked, cooDoNotShowAgain);
}
//---------------------------------------------------------------------------
THistoryComboBox * __fastcall TCopyDialog::GetDirectoryEdit()
{
return FToRemote ? RemoteDirectoryEdit : LocalDirectoryEdit;
}
//---------------------------------------------------------------------------
bool __fastcall TCopyDialog::RemotePaths()
{
return (FToRemote || FLAGSET(FOutputOptions, cooRemoteTransfer));
}
//---------------------------------------------------------------------------
UnicodeString __fastcall TCopyDialog::GetFileMask()
{
return ExtractFileName(DirectoryEdit->Text, RemotePaths());
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::SetParams(const TGUICopyParamType & value)
{
FParams = value;
FCopyParams = value;
DirectoryEdit->Text = Directory + FParams.FileMask;
QueueCheck2->Checked = FParams.Queue;
UpdateControls();
}
//---------------------------------------------------------------------------
TGUICopyParamType __fastcall TCopyDialog::GetParams()
{
// overwrites TCopyParamType fields only
FParams = FCopyParams;
FParams.FileMask = GetFileMask();
FParams.Queue = QueueCheck2->Checked;
return FParams;
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::SetDirectory(UnicodeString value)
{
if (!value.IsEmpty())
{
value = RemotePaths() ?
UnicodeString(UnixIncludeTrailingBackslash(value)) : IncludeTrailingBackslash(value);
}
DirectoryEdit->Text = value + GetFileMask();
}
//---------------------------------------------------------------------------
UnicodeString __fastcall TCopyDialog::GetDirectory()
{
DebugAssert(DirectoryEdit);
UnicodeString Result = DirectoryEdit->Text;
if (RemotePaths())
{
Result = UnixExtractFilePath(Result);
if (!Result.IsEmpty())
{
Result = UnixIncludeTrailingBackslash(Result);
}
}
else
{
Result = ExtractFilePath(Result);
if (!Result.IsEmpty())
{
Result = IncludeTrailingBackslash(Result);
}
}
return Result;
}
//---------------------------------------------------------------------------
int __fastcall TCopyDialog::ActualCopyParamAttrs()
{
return FCopyParamAttrs | FLAGMASK(QueueCheck2->Checked && WinConfiguration->DefaultCopyParam.QueueParallel, cpaNoCalculateSize);
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::UpdateControls()
{
if (!FToRemote && FLAGSET(FOptions, coAllowRemoteTransfer))
{
UnicodeString Directory = DirectoryEdit->Text;
bool RemoteTransfer = (Directory.Pos(L"\\") == 0) && (Directory.Pos(L"/") > 0);
if (RemoteTransfer != FLAGSET(FOutputOptions, cooRemoteTransfer))
{
FOutputOptions =
(FOutputOptions & ~cooRemoteTransfer) |
FLAGMASK(RemoteTransfer, cooRemoteTransfer);
AdjustTransferControls();
}
}
UnicodeString InfoStr = FCopyParams.GetInfoStr(L"; ", ActualCopyParamAttrs());
SetLabelHintPopup(CopyParamLabel, InfoStr);
bool RemoteTransfer = FLAGSET(FOutputOptions, cooRemoteTransfer);
EnableControl(QueueCheck2,
((FOptions & (coDisableQueue | coTemp)) == 0) && !RemoteTransfer);
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::FormShow(TObject * /*Sender*/)
{
DebugAssert(FFileList && (FFileList->Count > 0));
if (DirectoryEdit->Enabled && DirectoryEdit->Visible)
{
ActiveControl = DirectoryEdit;
}
else
{
ActiveControl = OkButton;
}
UpdateControls();
InstallPathWordBreakProc(RemoteDirectoryEdit);
InstallPathWordBreakProc(LocalDirectoryEdit);
// Does not work when set from a contructor
ShortCutHintPanel->Color = Application->HintColor;
}
//---------------------------------------------------------------------------
bool __fastcall TCopyDialog::Execute()
{
// at start assume that copy param is current preset
FPreset = GUIConfiguration->CopyParamCurrent;
DirectoryEdit->Items = CustomWinConfiguration->History[
FToRemote ? L"RemoteTarget" : L"LocalTarget"];
bool Result = (ShowModal() == DefaultResult(this));
if (Result)
{
Configuration->BeginUpdate();
try
{
if (FLAGSET(OutputOptions, cooSaveSettings) &&
FLAGCLEAR(FOptions, coDisableSaveSettings))
{
GUIConfiguration->DefaultCopyParam = Params;
}
DirectoryEdit->SaveToHistory();
CustomWinConfiguration->History[FToRemote ?
L"RemoteTarget" : L"LocalTarget"] = DirectoryEdit->Items;
if (FLAGSET(FOptions, coShortCutHint))
{
CustomWinConfiguration->CopyShortCutHintShown = true;
}
}
__finally
{
Configuration->EndUpdate();
}
}
return Result;
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::FormCloseQuery(TObject * /*Sender*/,
bool &CanClose)
{
if (ModalResult == DefaultResult(this))
{
if (!RemotePaths() && ((FOptions & coTemp) == 0))
{
UnicodeString Dir = Directory;
UnicodeString Drive = ExtractFileDrive(Dir);
if (!DirectoryExists(ApiPath(Dir)))
{
if (MessageDialog(MainInstructions(FMTLOAD(CREATE_LOCAL_DIRECTORY, (Dir))),
qtConfirmation, qaOK | qaCancel, HELP_NONE) != qaCancel)
{
if (!ForceDirectories(ApiPath(Dir)))
{
SimpleErrorDialog(FMTLOAD(CREATE_LOCAL_DIR_ERROR, (Dir)));
CanClose = false;
}
}
else
{
CanClose = False;
}
}
if (!CanClose)
{
DirectoryEdit->SelectAll();
DirectoryEdit->SetFocus();
}
}
if (CanClose && !IsFileNameMask(GetFileMask()) && (FFileList->Count > 1))
{
UnicodeString Message =
FormatMultiFilesToOneConfirmation(DirectoryEdit->Text, RemotePaths());
CanClose =
(MessageDialog(Message, qtConfirmation, qaOK | qaCancel, HELP_NONE) != qaCancel);
}
if (CanClose)
{
ExitActiveControl(this);
}
}
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::LocalDirectoryBrowseButtonClick(
TObject * /*Sender*/)
{
DebugAssert(!FToRemote);
UnicodeString ADirectory;
// if we are duplicating, we have remote path there
if (!RemotePaths())
{
ADirectory = Directory;
}
if (SelectDirectory(ADirectory, LoadStr(SELECT_LOCAL_DIRECTORY), true))
{
Directory = ADirectory;
UpdateControls();
}
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::ControlChange(TObject * /*Sender*/)
{
UpdateControls();
ResetSystemSettings(this);
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::TransferSettingsButtonClick(TObject * /*Sender*/)
{
if (!SupportsSplitButton())
{
CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), 0);
}
else
{
CopyParamGroupClick(NULL);
}
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::GenerateCode()
{
TFilesSelected FilesSelected = FLAGSET(FOptions, coAllFiles) ? fsAll : fsList;
DoGenerateTransferCodeDialog(FToRemote, FMove, ActualCopyParamAttrs(), FSessionData, FilesSelected, FFileList, Directory, Params);
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::CopyParamClick(TObject * Sender)
{
// Save including the preset-unspecific queue properties,
// so that they are preserved when assigning back later
TGUICopyParamType Param = Params;
bool PrevSaveSettings = FSaveSettings;
int Result = CopyParamListPopupClick(Sender, Param, FPreset, ActualCopyParamAttrs(), &FSaveSettings);
if (Result < 0)
{
if (DebugAlwaysTrue(Result == -cplGenerateCode))
{
GenerateCode();
}
}
else
{
if (Result > 0)
{
Params = Param;
}
else
{
UpdateControls();
}
if (PrevSaveSettings && !FSaveSettings)
{
NeverShowAgainCheck->Checked = false;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::HelpButtonClick(TObject * /*Sender*/)
{
FormHelp(this);
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::CopyParamGroupClick(TObject * /*Sender*/)
{
if (CopyParamGroup->Enabled)
{
if (DoCopyParamCustomDialog(FCopyParams, ActualCopyParamAttrs()))
{
UpdateControls();
}
}
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::CopyParamGroupContextPopup(TObject * /*Sender*/,
TPoint & MousePos, bool & Handled)
{
CopyParamListPopup(CalculatePopupRect(CopyParamGroup, MousePos), cplCustomizeDefault);
Handled = true;
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::CopyParamListPopup(TRect R, int AdditionalOptions)
{
bool RemoteTransfer = FLAGSET(FOutputOptions, cooRemoteTransfer);
::CopyParamListPopup(R, FPresetsMenu,
FCopyParams, FPreset, CopyParamClick,
AdditionalOptions |
FLAGMASK(
FLAGCLEAR(FOptions, coDisableSaveSettings) && !RemoteTransfer,
cplSaveSettings) |
FLAGMASK(FLAGCLEAR(FOutputOptions, cooRemoteTransfer) && FLAGCLEAR(FOptions, coTemp), cplGenerateCode),
ActualCopyParamAttrs(),
FSaveSettings);
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::TransferSettingsButtonDropDownClick(TObject * /*Sender*/)
{
CopyParamListPopup(CalculatePopupRect(TransferSettingsButton), cplCustomizeDefault);
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::NeverShowAgainCheckClick(TObject * /*Sender*/)
{
FSaveSettings = NeverShowAgainCheck->Checked;
UpdateControls();
}
//---------------------------------------------------------------------------
void __fastcall TCopyDialog::ShortCutHintLabelClick(TObject * /*Sender*/)
{
DoPreferencesDialog(pmCommander);
}
//---------------------------------------------------------------------------