123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- //---------------------------------------------------------------------------
- #include <vcl.h>
- #pragma hdrstop
- #include <Common.h>
- #include <WinInterface.h>
- #include <VCLCommon.h>
- #include <TextsWin.h>
- #include <WinConfiguration.h>
- #include <CoreMain.h>
- #include <Tools.h>
- #include <BaseUtils.hpp>
- #include <Terminal.h>
- #include "FileFind.h"
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- #pragma link "HistoryComboBox"
- #pragma link "IEListView"
- #pragma link "NortonLikeListView"
- #pragma link "PngImageList"
- #ifndef NO_RESOURCES
- #pragma resource "*.dfm"
- #endif
- //---------------------------------------------------------------------------
- TFileFindDialog * FileFindDialog = NULL;
- //---------------------------------------------------------------------------
- void __fastcall ShowFileFindDialog(
- TTerminal * Terminal, UnicodeString Directory, TFindEvent OnFind, TFocusFileEvent OnFocusFile,
- TFileListOperationEvent OnDeleteFiles, TFileListOperationEvent OnDownloadFiles)
- {
- if (FileFindDialog == NULL)
- {
- FileFindDialog = new TFileFindDialog(Application);
- }
- FileFindDialog->Init(Terminal, Directory, OnFind, OnFocusFile, OnDeleteFiles, OnDownloadFiles);
- FileFindDialog->Show();
- }
- //---------------------------------------------------------------------------
- void __fastcall HideFileFindDialog()
- {
- if (FileFindDialog != NULL)
- {
- delete FileFindDialog;
- }
- }
- //---------------------------------------------------------------------------
- __fastcall TFileFindDialog::TFileFindDialog(TComponent * Owner)
- : TForm(Owner)
- {
- UseSystemSettings(this);
- FState = ffInit;
- FixComboBoxResizeBug(MaskEdit);
- FixComboBoxResizeBug(RemoteDirectoryEdit);
- HintLabel(MaskHintText,
- FORMAT(L"%s\n \n%s\n \n%s\n \n%s\n \n%s\n \n%s", (LoadStr(MASK_HINT2),
- LoadStr(FILE_MASK_EX_HINT), LoadStr(COMBINING_MASKS_HINT),
- LoadStr(PATH_MASK_HINT2), LoadStr(DIRECTORY_MASK_HINT),
- LoadStr(MASK_HELP))));
- UpdateImages();
- FileView->ShowColumnIcon = false;
- UseDesktopFont(FileView);
- UseDesktopFont(StatusBar);
- FFrameAnimation.Init(AnimationPaintBox, L"Find");
- FixFormIcons(this);
- }
- //---------------------------------------------------------------------------
- __fastcall TFileFindDialog::~TFileFindDialog()
- {
- TFindFileConfiguration FormConfiguration = CustomWinConfiguration->FindFile;
- FormConfiguration.ListParams = FileView->ColProperties->ParamsStr;
- UnicodeString WindowParams = StoreFormSize(this);
- // this is particularly to prevent saving the form state
- // for the first time, keeping default positioning by a system
- if (!FWindowParams.IsEmpty() && (FWindowParams != WindowParams))
- {
- FormConfiguration.WindowParams = WindowParams;
- }
- CustomWinConfiguration->FindFile = FormConfiguration;
- Clear();
- DebugAssert(FileFindDialog == this);
- FileFindDialog = NULL;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::UpdateImages()
- {
- FileView->SmallImages = ShellImageListForControl(this, ilsSmall);
- }
- //---------------------------------------------------------------------------
- bool __fastcall TFileFindDialog::IsFinding()
- {
- return (FState == ffFinding) || (FState == ffAborting);
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::UpdateControls()
- {
- bool Finding = IsFinding();
- Caption = FORMAT("%s - %s", (LoadStr(Finding ? FIND_FILE_FINDING : FIND_FILE_TITLE), FTerminalName));
- UnicodeString StartStopCaption;
- if (Finding)
- {
- EnableControl(StartStopButton, true);
- StartStopCaption = LoadStr(FIND_FILE_STOP);
- }
- else
- {
- EnableControl(StartStopButton, !RemoteDirectoryEdit->Text.IsEmpty());
- StartStopCaption = LoadStr(FIND_FILE_START);
- }
- StartStopButton->Caption = StartStopCaption;
- EnableControl(FilterGroup, !Finding);
- FocusAction->Enabled = (FileView->ItemFocused != NULL);
- bool EnableFileOperations = !Finding && (FileView->SelCount > 0);
- DeleteAction->Enabled = EnableFileOperations;
- DownloadAction->Enabled = EnableFileOperations;
- CopyAction->Enabled = (FileView->Items->Count > 0);
- SelectAllAction->Enabled = (FileView->SelCount < FileView->Items->Count);
- switch (FState)
- {
- case ffInit:
- StatusBar->SimpleText = L"";
- break;
- case ffFinding:
- case ffAborting:
- if (!FFindingInDirectory.IsEmpty())
- {
- StatusBar->SimpleText = FMTLOAD(FIND_FILE_IN_DIRECTORY, (FFindingInDirectory));
- }
- else
- {
- StatusBar->SimpleText = L"";
- }
- break;
- case ffAborted:
- StatusBar->SimpleText = LoadStr(FIND_FILE_ABORTED);
- break;
- case ffDone:
- StatusBar->SimpleText = LoadStr(FIND_FILE_DONE);
- break;
- default:
- DebugFail();
- break;
- }
- FocusButton->Default = FileView->Focused() && (FState != ffInit);
- StartStopButton->Default = !FocusButton->Default;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::ControlChange(TObject * /*Sender*/)
- {
- UpdateControls();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::Init(
- TTerminal * Terminal, UnicodeString Directory, TFindEvent OnFind, TFocusFileEvent OnFocusFile,
- TFileListOperationEvent OnDeleteFiles, TFileListOperationEvent OnDownloadFiles)
- {
- if (FTerminal != Terminal)
- {
- FTerminal = Terminal;
- FTerminalName = Terminal->SessionData->SessionName;
- Clear();
- FState = ffInit;
- ActiveControl = MaskEdit;
- }
- FOnFind = OnFind;
- FOnFocusFile = OnFocusFile;
- FOnDeleteFiles = OnDeleteFiles;
- FOnDownloadFiles = OnDownloadFiles;
- MaskEdit->Text = WinConfiguration->SelectMask;
- RemoteDirectoryEdit->Text = UnixExcludeTrailingBackslash(Directory);
- UpdateControls();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::CreateParams(TCreateParams & Params)
- {
- TForm::CreateParams(Params);
- Params.WndParent = GetDesktopWindow();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::ClearItem(TListItem * Item)
- {
- TRemoteFile * File = static_cast<TRemoteFile *>(Item->Data);
- Item->Data = NULL;
- delete File;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::Clear()
- {
- for (int Index = 0; Index < FileView->Items->Count; Index++)
- {
- ClearItem(FileView->Items->Item[Index]);
- }
- FileView->Items->Clear();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::Start()
- {
- if (MaskEdit->Focused())
- {
- MaskEditExit(NULL);
- }
- RemoteDirectoryEdit->SaveToHistory();
- CustomWinConfiguration->History[L"RemoteDirectory"] = RemoteDirectoryEdit->Items;
- MaskEdit->SaveToHistory();
- WinConfiguration->History[L"Mask"] = MaskEdit->Items;
- WinConfiguration->SelectMask = MaskEdit->Text;
- DebugAssert(FState != ffFinding);
- FState = ffFinding;
- try
- {
- FFrameAnimation.Start();
- UpdateControls();
- Repaint();
- TOperationVisualizer Visualizer;
- DebugAssert(FOnFind != NULL);
- UnicodeString Directory = UnixExcludeTrailingBackslash(RemoteDirectoryEdit->Text);
- FDirectory = Directory;
- if (FDirectory == ROOTDIRECTORY)
- {
- FDirectory = UnicodeString();
- }
- FOnFind(FTerminal, Directory, MaskEdit->Text, FileFound, FindingFile);
- }
- __finally
- {
- FFindingInDirectory = L"";
- if (FState == ffFinding)
- {
- FState = ffDone;
- }
- if (FState == ffAborting)
- {
- FState = ffAborted;
- }
- FFrameAnimation.Stop();
- if (WindowState == wsMinimized)
- {
- ShowNotification(
- NULL, MainInstructions(LoadStr(BALLOON_OPERATION_COMPLETE)),
- qtInformation);
- }
- if (!FFocusPath.IsEmpty())
- {
- UnicodeString FocusPath = FFocusPath;
- FFocusPath = L"";
- DoFocusFile(FocusPath);
- }
- UpdateControls();
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FileFound(TTerminal * /*Terminal*/,
- const UnicodeString FileName, const TRemoteFile * AFile, bool & Cancel)
- {
- TListItem * Item = FileView->Items->Add();
- TRemoteFile * File = AFile->Duplicate(true);
- Item->Data = File;
- Item->ImageIndex = File->IconIndex;
- UnicodeString Caption = File->FileName;
- if (File->IsDirectory)
- {
- Caption = UnixIncludeTrailingBackslash(Caption);
- }
- Item->Caption = Caption;
- UnicodeString Directory = UnixExtractFilePath(File->FullFileName);
- if (AnsiSameText(FDirectory, Directory.SubString(1, FDirectory.Length())))
- {
- Directory = L"." + Directory.SubString(FDirectory.Length() + 1, Directory.Length() - FDirectory.Length());
- }
- else
- {
- DebugFail();
- }
- Item->SubItems->Add(Directory);
- if (File->IsDirectory)
- {
- Item->SubItems->Add(L"");
- }
- else
- {
- Item->SubItems->Add(
- FormatPanelBytes(File->Size, WinConfiguration->FormatSizeBytes));
- }
- Item->SubItems->Add(UserModificationStr(File->Modification, File->ModificationFmt));
- UpdateControls();
- Cancel = (FState == ffAborting);
- Application->ProcessMessages();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FindingFile(TTerminal * /*Terminal*/,
- const UnicodeString Directory, bool & Cancel)
- {
- if (!Directory.IsEmpty() && (FFindingInDirectory != Directory))
- {
- FFindingInDirectory = Directory;
- UpdateControls();
- }
- Cancel = (FState == ffAborting);
- Application->ProcessMessages();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::StartStopButtonClick(TObject * /*Sender*/)
- {
- if (IsFinding())
- {
- Stop();
- }
- else
- {
- Clear();
- if (ActiveControl->Parent == FilterGroup)
- {
- FileView->SetFocus();
- }
- Start();
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::StopButtonClick(TObject * /*Sender*/)
- {
- Stop();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::Stop()
- {
- FState = ffAborting;
- UpdateControls();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FormShow(TObject * /*Sender*/)
- {
- InstallPathWordBreakProc(MaskEdit);
- InstallPathWordBreakProc(RemoteDirectoryEdit);
- // have to set history after value, to prevent autocompletition
- MaskEdit->Items = WinConfiguration->History[L"Mask"];
- RemoteDirectoryEdit->Items = CustomWinConfiguration->History[L"RemoteDirectory"];
- UpdateFormPosition(this, poOwnerFormCenter);
- RestoreFormSize(CustomWinConfiguration->FindFile.WindowParams, this);
- FileView->ColProperties->ParamsStr = CustomWinConfiguration->FindFile.ListParams;
- DebugAssert(FWindowParams.IsEmpty());
- if (FWindowParams.IsEmpty())
- {
- FWindowParams = StoreFormSize(this);
- }
- UpdateControls();
- }
- //---------------------------------------------------------------------------
- bool __fastcall TFileFindDialog::StopIfFinding()
- {
- bool Result = IsFinding();
- if (Result)
- {
- Stop();
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FormCloseQuery(TObject * /*Sender*/,
- bool & /*CanClose*/)
- {
- StopIfFinding();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::HelpButtonClick(TObject * /*Sender*/)
- {
- FormHelp(this);
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::Dispatch(void * Message)
- {
- TMessage * M = reinterpret_cast<TMessage*>(Message);
- if (M->Msg == CM_DIALOGKEY)
- {
- CMDialogKey(*((TWMKeyDown *)Message));
- }
- else if (M->Msg == CM_DPICHANGED)
- {
- CMDpiChanged(*M);
- }
- else
- {
- TForm::Dispatch(Message);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::CMDpiChanged(TMessage & Message)
- {
- TForm::Dispatch(&Message);
- UpdateImages();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::CMDialogKey(TWMKeyDown & Message)
- {
- // Handling VK_ESCAPE in FormKeyDown causes a beep when any "edit" has focus.
- // Moreover FormKeyDown is called when the the "esc" is pressed while drop down list is unrolled.
- if (Message.CharCode == VK_ESCAPE)
- {
- if (!StopIfFinding())
- {
- Close();
- }
- Message.Result = 1;
- return;
- }
- TForm::Dispatch(&Message);
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FormKeyDown(TObject * /*Sender*/, WORD & Key,
- TShiftState Shift)
- {
- if ((Key == L'C') && Shift.Contains(ssCtrl) &&
- (dynamic_cast<TCustomCombo *>(ActiveControl) == NULL))
- {
- CopyToClipboard();
- Key = 0;
- }
- else if ((Key == VK_F10) && Shift.Empty())
- {
- Key = 0;
- StopIfFinding();
- Close();
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::MaskEditExit(TObject * /*Sender*/)
- {
- ValidateMaskEdit(MaskEdit);
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::DoFocusFile(const UnicodeString & Path)
- {
- FOnFocusFile(FTerminal, Path);
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FocusFile()
- {
- UnicodeString Path = static_cast<TRemoteFile *>(FileView->ItemFocused->Data)->FullFileName;
- // To make focussing directories work,
- // otherwise it would try to focus "empty-named file" in the Path
- Path = UnixExcludeTrailingBackslash(Path);
- if (StopIfFinding())
- {
- FFocusPath = Path;
- }
- else
- {
- DoFocusFile(Path);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FileViewDblClick(TObject * /*Sender*/)
- {
- if (FileView->ItemFocused != NULL)
- {
- FocusFile();
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FocusActionExecute(TObject * /*Sender*/)
- {
- FocusFile();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FileViewSelectItem(TObject * /*Sender*/,
- TListItem * /*Item*/, bool /*Selected*/)
- {
- UpdateControls();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::MaskButtonClick(TObject * /*Sender*/)
- {
- TFileMasks Masks = MaskEdit->Text;
- if (DoEditMaskDialog(Masks))
- {
- MaskEdit->Text = Masks.Masks;
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::CopyToClipboard()
- {
- TInstantOperationVisualizer Visualizer;
- std::unique_ptr<TStrings> Strings(new TStringList());
- for (int Index = 0; Index < FileView->Items->Count; Index++)
- {
- TListItem * Item = FileView->Items->Item[Index];
- TRemoteFile * File = static_cast<TRemoteFile *>(Item->Data);
- Strings->Add(File->FullFileName);
- }
- ::CopyToClipboard(Strings.get());
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::CopyActionExecute(TObject * /*Sender*/)
- {
- CopyToClipboard();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FormClose(TObject * /*Sender*/, TCloseAction & Action)
- {
- StopIfFinding();
- Action = caFree;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FileViewContextPopup(TObject * Sender, TPoint & MousePos, bool & Handled)
- {
- // to update source popup menu before TBX menu is created
- UpdateControls();
- MenuPopup(Sender, MousePos, Handled);
- }
- //---------------------------------------------------------------------------
- TListItem * __fastcall TFileFindDialog::FileOperationFinished(const UnicodeString & FileName)
- {
- TFileItemMap::iterator I = FFileItemMap.find(FileName);
- TListItem * Result = NULL;
- if (DebugAlwaysTrue(I != FFileItemMap.end()))
- {
- Result = I->second;
- FileView->MakeProgressVisible(Result);
- FFileItemMap.erase(I);
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FileDeleteFinished(const UnicodeString & FileName, bool Success)
- {
- // Delete in queue not supported
- DebugAssert(!FileName.IsEmpty());
- TListItem * Item = FileOperationFinished(FileName);
- if (DebugAlwaysTrue(Item != NULL) && Success)
- {
- ClearItem(Item);
- Item->Delete();
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FileDownloadFinished(const UnicodeString & FileName, bool Success)
- {
- if (FileName.IsEmpty())
- {
- DebugAssert(Success);
- // Moved to queue, see call in TCustomScpExplorerForm::CopyParamDialog
- FileView->SelectAll(smNone);
- }
- else
- {
- TListItem * Item = FileOperationFinished(FileName);
- if (DebugAlwaysTrue(Item != NULL) && Success)
- {
- Item->Selected = false;
- }
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::FileListOperation(
- TFileListOperationEvent Operation, TFileOperationFinishedEvent OnFileOperationFinished)
- {
- std::unique_ptr<TStrings> FileList(new TStringList());
- DebugAssert(FFileItemMap.empty());
- TListItem * Item = FileView->Selected;
- while (Item != NULL)
- {
- TRemoteFile * File = static_cast<TRemoteFile *>(Item->Data);
- FileList->AddObject(File->FullFileName, File);
- FFileItemMap.insert(std::make_pair(File->FullFileName, Item));
- Item = FileView->GetNextItem(Item, sdAll, TItemStates() << isSelected);
- }
- try
- {
- Operation(FTerminal, FileList.get(), OnFileOperationFinished);
- }
- __finally
- {
- // can be non-empty only when not all files were processed
- FFileItemMap.clear();
- }
- UpdateControls();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::DeleteActionExecute(TObject * /*Sender*/)
- {
- FileListOperation(FOnDeleteFiles, FileDeleteFinished);
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::SelectAllActionExecute(TObject * /*Sender*/)
- {
- FileView->SelectAll(smAll);
- }
- //---------------------------------------------------------------------------
- void __fastcall TFileFindDialog::DownloadActionExecute(TObject * /*Sender*/)
- {
- FileListOperation(FOnDownloadFiles, FileDownloadFinished);
- }
- //---------------------------------------------------------------------------
|