View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0003080 | Far Manager | FindFiles | public | 2015-09-02 10:09 | 2015-10-03 16:08 |
Reporter | 4eyes | Assigned To | DrKnS | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Product Version | 3.0 | ||||
Fixed in Version | 3.0 | ||||
Summary | 0003080: [patch] Alternate editor/viewer in FindFile results | ||||
Description | FindFile results list doesn't support custom editor/viewer for found files. Although FAR may use file associations or editor/viewer configuration for customizing files opening method, these settings aren't applied for FindFile results. Patch is included to this issue. Forum link: http://forum.farmanager.com/viewtopic.php?f=6&t=9797 | ||||
Steps To Reproduce | - create Edit file association, or set up external editor using Editor options; - start search in FindFile; - wait for a first results; - try to open external editor, or editor associated with 'file associations' | ||||
Additional Information | I think, it would be nice and consistent if file associations and Editor/Viewer options were working globally for any files list. This patch is a little step further. Additionally, with this patch user may launch external editor/viewer while search still in progress, which is impossible from temporary panel. Moreover, sometimes ind results dialog is more handy then temporary panel, due to short file name, grouping, etc. Feel free to contact me here or on forum, if there is any suggestions to my patch. | ||||
Tags | No tags attached. | ||||
Build | 4430 | ||||
|
unicode_far_r13359_FindFileList.patch (16,288 bytes)
Index: FarRus.hlf.m4 =================================================================== --- FarRus.hlf.m4 (revision 13359) +++ FarRus.hlf.m4 (working copy) @@ -1866,8 +1866,24 @@ #Отмена# Прервать поиск и закрыть диалог. - Для просмотра и редактирования найденных файлов могут быть использованы -#F3# и #F4#. Редактирование и просмотр поддерживаются также для файловых систем + Во время поиска поддерживается просмотр и редактирование найденных файлов. + + Просмотр #Ctrl-Shift-F3, Numpad 5, F3, ALT-F3# + + #NumPad 5#, #F3# или #ALT-F3# используются для вызова ~встроенной~@Viewer@, внешней + или ~ассоциированной~@FileAssoc@ программы просмотра, в зависимости от типа файла и + ~настроек программы просмотра~@ViewerSettings@. + #Ctrl-Shift-F3# всегда вызывает встроенную программу просмотра, вне + зависимости от файловых ассоциаций. + + Редактирование #Ctrl-Shift-F4, F4, ALT-F4# + + #F4# или #ALT-F4# вызывает ~встроенный~@Editor@, внешний или ~ассоциированный~@FileAssoc@ + редактор, в зависимости от типа файла и ~настроек редактора~@EditorSettings@. + #Ctrl-Shift-F4# всегда вызывает встроенный редактор, вне зависимости от + файловых ассоциаций. + +Редактирование и просмотр поддерживаются также для файловых систем плагинов. Заметьте, что сохранение изменений в редакторе по клавише #F2# для файловых систем плагинов будет вызывать операцию #Сохранить в# вместо обычного #Сохранить#. Index: filetype.cpp =================================================================== --- filetype.cpp (revision 13359) +++ filetype.cpp (working copy) @@ -245,6 +245,73 @@ } +bool GetFiletypeOpenMode(int keyPressed, FILETYPE_MODE& mode, bool& shouldForceInternal) +{ + bool isModeFound = false; + + switch (keyPressed) + { + case KEY_F3: + case KEY_NUMPAD5: + case KEY_SHIFTNUMPAD5: + mode = Global->Opt->ViOpt.UseExternalViewer ? FILETYPE_ALTVIEW : FILETYPE_VIEW; + shouldForceInternal = false; + isModeFound = true; + break; + + case KEY_CTRLSHIFTF3: + case KEY_RCTRLSHIFTF3: + mode = FILETYPE_VIEW; + shouldForceInternal = true; + isModeFound = true; + break; + + case KEY_RALTF3: + case KEY_ALTF3: + mode = !Global->Opt->ViOpt.UseExternalViewer ? FILETYPE_ALTVIEW : FILETYPE_VIEW;; + shouldForceInternal = false; + isModeFound = true; + break; + + case KEY_F4: + mode = Global->Opt->EdOpt.UseExternalEditor ? FILETYPE_ALTEDIT: FILETYPE_EDIT; + shouldForceInternal = false; + isModeFound = true; + break; + + case KEY_CTRLSHIFTF4: + case KEY_RCTRLSHIFTF4: + mode = FILETYPE_EDIT; + shouldForceInternal = true; + isModeFound = true; + break; + + case KEY_ALTF4: + case KEY_RALTF4: + mode = !Global->Opt->EdOpt.UseExternalEditor ? FILETYPE_ALTEDIT : FILETYPE_EDIT; + shouldForceInternal = false; + isModeFound = true; + break; + + case KEY_ENTER: + mode = FILETYPE_EXEC; + isModeFound = true; + break; + + case KEY_CTRLPGDN: + case KEY_RCTRLPGDN: + mode = FILETYPE_ALTEXEC; + isModeFound = true; + break; + + default: + // non-default key may be pressed, it's ok. + break; + } + + return isModeFound; +} + void ProcessGlobalFileTypes(const string& Name, bool AlwaysWaitFinish, bool RunAs, bool FromPanel) { string strName(Name); Index: filetype.hpp =================================================================== --- filetype.hpp (revision 13359) +++ filetype.hpp (working copy) @@ -44,6 +44,13 @@ FILETYPE_ALTEDIT // Alt-F4 }; +/* + * Convert pressed key into FILETYPE_MODE operation, if possible. + * Won't change 'mode' if key is unknown + * return true if succeed. + */ +bool GetFiletypeOpenMode(int keyPressed, FILETYPE_MODE& mode, bool& shouldForceInternal); + void ProcessGlobalFileTypes(const string& Name, bool AlwaysWaitFinish, bool RunAs,bool FromPanel=false); bool ProcessLocalFileTypes(const string& Name, const string& ShortName, FILETYPE_MODE Mode, bool AlwaysWaitFinish); void ProcessExternal(const string& Command, const string& Name, const string& ShortName, bool AlwaysWaitFinish); Index: findfile.cpp =================================================================== --- findfile.cpp (revision 13359) +++ findfile.cpp (working copy) @@ -78,6 +78,7 @@ #include "filestr.hpp" #include "exitcode.hpp" #include "panelctype.hpp" +#include "filetype.hpp" // ������ ������. ���� ���� ������ � �����, �� FindList->ArcIndex �������� ���. struct ArcListItem @@ -101,7 +102,7 @@ class InterThreadData { private: - CriticalSection DataCS; + mutable CriticalSection DataCS; ArcListItem* FindFileArcItem; int Percent; int LastFoundNumber; @@ -112,6 +113,8 @@ std::list<ArcListItem> ArcList; string strFindMessage; + std::list<FindListItem>& GetFindList() { return FindList; } + public: InterThreadData() {Init();} ~InterThreadData() { ClearAllLists(); } @@ -129,11 +132,7 @@ strFindMessage.clear(); } - std::list<FindListItem>& GetFindList() {return FindList;} - void Lock() {DataCS.lock();} - void Unlock() {DataCS.unlock();} - ArcListItem* GetFindFileArcItem() { SCOPED_ACTION(CriticalSectionLock)(DataCS); @@ -178,7 +177,11 @@ DirCount = Value; } - size_t GetFindListCount() const { return FindList.size(); } + size_t GetFindListCount() const + { + SCOPED_ACTION(CriticalSectionLock)(DataCS); + return FindList.size(); + } void GetFindMessage(string& To) { @@ -243,6 +246,23 @@ FindList.emplace_back(NewItem); return FindList.back(); } + + template <typename Visitor> + void ForEachFindItem(const Visitor& visitor) const + { + SCOPED_ACTION(CriticalSectionLock)(DataCS); + for (const auto& i : GetFindList()) + visitor(i); + } + + template <typename Visitor> + void ForEachFindItem(const Visitor& visitor) + { + SCOPED_ACTION(CriticalSectionLock)(DataCS); + for (auto& i : GetFindList()) + visitor(i); + } + }; @@ -1578,9 +1598,17 @@ */ case KEY_F3: + case KEY_ALTF3: + case KEY_RALTF3: + case KEY_CTRLSHIFTF3: + case KEY_RCTRLSHIFTF3: case KEY_NUMPAD5: case KEY_SHIFTNUMPAD5: case KEY_F4: + case KEY_ALTF4: + case KEY_RALTF4: + case KEY_CTRLSHIFTF4: + case KEY_RCTRLSHIFTF4: { if (ListBox->empty()) { @@ -1662,81 +1690,8 @@ strSearchFileName = FindItem->FindData.strAlternateFileName; } - if (os::fs::exists(strSearchFileName)) - { - const auto strOldTitle = Console().GetTitle(); + OpenFile(strSearchFileName, key, FindItem, Dlg); - if (key==KEY_F3 || key==KEY_NUMPAD5 || key==KEY_SHIFTNUMPAD5) - { - NamesList ViewList; - int list_count = 0; - - // ������ ��� ����, ������ ���� ������ �����... - itd->Lock(); - std::for_each(CONST_RANGE(itd->GetFindList(), i) - { - bool RealNames=true; - if(i.Arc) - { - if(!(i.Arc->Flags & OPIF_REALNAMES)) - { - RealNames=false; - } - } - if (RealNames) - { - if (!i.FindData.strFileName.empty() && !(i.FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) - { - ++list_count; - ViewList.AddName(i.FindData.strFileName); - } - } - }); - itd->Unlock(); - ViewList.SetCurName(FindItem->FindData.strFileName); - - Dlg->SendMessage(DM_SHOWDIALOG, FALSE, nullptr); - Dlg->SendMessage(DM_ENABLEREDRAW, FALSE, nullptr); - { - auto ShellViewer = FileViewer::create(strSearchFileName, FALSE, FALSE, FALSE, -1, nullptr, (list_count > 1 ? &ViewList : nullptr)); - ShellViewer->SetEnableF6(TRUE); - - if(FindItem->Arc) - { - if(!(FindItem->Arc->Flags & OPIF_REALNAMES)) - { - ShellViewer->SetSaveToSaveAs(true); - } - } - Global->WindowManager->ExecuteModal(ShellViewer); - // ��������� �������� ����� - Global->WindowManager->ProcessKey(Manager::Key(KEY_CONSOLE_BUFFER_RESIZE)); - } - Dlg->SendMessage(DM_ENABLEREDRAW, TRUE, nullptr); - Dlg->SendMessage(DM_SHOWDIALOG, TRUE, nullptr); - } - else - { - auto ShellEditor = FileEditor::create(strSearchFileName, CP_DEFAULT, 0); - ShellEditor->SetEnableF6(true); - - if(FindItem->Arc) - { - if(!(FindItem->Arc->Flags & OPIF_REALNAMES)) - { - ShellEditor->SetSaveToSaveAs(true); - } - } - auto editorExitCode=ShellEditor->GetExitCode(); - if (editorExitCode != XC_OPEN_ERROR && editorExitCode != XC_LOADING_INTERRUPTED) - { - Global->WindowManager->ExecuteModal(ShellEditor); - // ��������� �������� ����� - Global->WindowManager->ProcessKey(Manager::Key(KEY_CONSOLE_BUFFER_RESIZE)); - } - } - Console().SetTitle(strOldTitle); - } if (RemoveTemp) { DeleteFileWithFolder(strSearchFileName); @@ -1906,8 +1861,96 @@ return Dlg->DefProc(Msg,Param1,Param2); } -void FindFiles::AddMenuRecord(Dialog* Dlg,const string& FullName, const os::FAR_FIND_DATA& FindData, void* Data, FARPANELITEMFREECALLBACK FreeData) +void FindFiles::OpenFile(string strSearchFileName, int openKey, const FindListItem* FindItem, Dialog* Dlg) { + if (!os::fs::exists(strSearchFileName)) + return; + + FILETYPE_MODE openMode = FILETYPE_VIEW; + bool shouldForceInternal = false; + bool isKnownKey = GetFiletypeOpenMode(openKey, openMode, shouldForceInternal); + assert(isKnownKey); // ensure all possible keys are handled + + const auto strOldTitle = Console().GetTitle(); + + string shortFileName = ExtractFileName(strSearchFileName); + bool isProcessed = !shouldForceInternal && ProcessLocalFileTypes(strSearchFileName, shortFileName, openMode, PluginMode); + + if (!isProcessed) + { + if (openMode == FILETYPE_ALTVIEW && Global->Opt->strExternalViewer.empty()) + openMode = FILETYPE_VIEW; + + if (openMode == FILETYPE_ALTEDIT && Global->Opt->strExternalEditor.empty()) + openMode = FILETYPE_EDIT; + + if (openMode == FILETYPE_VIEW) + { + NamesList ViewList; + int list_count = 0; + + // ������ ��� ����, ������ ���� ������ �����... + itd->ForEachFindItem([&list_count, &ViewList](const FindListItem& i) + { + bool isRealName = !i.Arc || (i.Arc->Flags & OPIF_REALNAMES); + if (isRealName) + { + if (!i.FindData.strFileName.empty() && !(i.FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) + { + ++list_count; + ViewList.AddName(i.FindData.strFileName); + } + } + }); + + ViewList.SetCurName(FindItem->FindData.strFileName); + + Dlg->SendMessage(DM_SHOWDIALOG, FALSE, nullptr); + Dlg->SendMessage(DM_ENABLEREDRAW, FALSE, nullptr); + { + auto ShellViewer = FileViewer::create(strSearchFileName, FALSE, FALSE, FALSE, -1, nullptr, (list_count > 1 ? &ViewList : nullptr)); + ShellViewer->SetEnableF6(TRUE); + + if (FindItem->Arc && !(FindItem->Arc->Flags & OPIF_REALNAMES)) + ShellViewer->SetSaveToSaveAs(true); + + Global->WindowManager->ExecuteModal(ShellViewer); + // ��������� �������� ����� + Global->WindowManager->ProcessKey(Manager::Key(KEY_CONSOLE_BUFFER_RESIZE)); + } + Dlg->SendMessage(DM_ENABLEREDRAW, TRUE, nullptr); + Dlg->SendMessage(DM_SHOWDIALOG, TRUE, nullptr); + } + + if (openMode == FILETYPE_EDIT) + { + auto ShellEditor = FileEditor::create(strSearchFileName, CP_DEFAULT, 0); + ShellEditor->SetEnableF6(true); + + if (FindItem->Arc && !(FindItem->Arc->Flags & OPIF_REALNAMES)) + ShellEditor->SetSaveToSaveAs(true); + + auto editorExitCode = ShellEditor->GetExitCode(); + if (editorExitCode != XC_OPEN_ERROR && editorExitCode != XC_LOADING_INTERRUPTED) + { + Global->WindowManager->ExecuteModal(ShellEditor); + // ��������� �������� ����� + Global->WindowManager->ProcessKey(Manager::Key(KEY_CONSOLE_BUFFER_RESIZE)); + } + } + + if (openMode == FILETYPE_ALTEDIT || openMode == FILETYPE_ALTVIEW) + { + string externalCommand = openMode == FILETYPE_ALTEDIT ? Global->Opt->strExternalEditor : Global->Opt->strExternalViewer; + ProcessExternal(externalCommand, strSearchFileName, shortFileName, PluginMode); + } + } + + Console().SetTitle(strOldTitle); +} + +void FindFiles::AddMenuRecord(Dialog* Dlg, const string& FullName, const os::FAR_FIND_DATA& FindData, void* Data, FARPANELITEMFREECALLBACK FreeData) +{ if (!Dlg) return; @@ -2726,30 +2769,22 @@ case FD_BUTTON_PANEL: // ���������� ���������� �� �������� ����� { - itd->Lock(); - size_t ListSize = itd->GetFindList().size(); std::vector<PluginPanelItem> PanelItems; - PanelItems.reserve(ListSize); + PanelItems.reserve(itd->GetFindListCount()); - std::for_each(RANGE(itd->GetFindList(), i) + itd->ForEachFindItem([&PanelItems, this](FindListItem& i) { if (!i.FindData.strFileName.empty() && i.Used) - // �������� ������, ���� �� ������ { + // �������� ������, ���� �� ������ // �� �������� � ���������� ������� ������� �� ����� �� �� �����. // ����� ���� ������ ����� �����. - bool IsArchive=false; - if(i.Arc) - { - if(!(i.Arc->Flags&OPIF_REALNAMES)) - { - IsArchive=true; - } - } + bool IsArchive = i.Arc && !(i.Arc->Flags&OPIF_REALNAMES); + // �������� ����� ���� ��� ����� ������ ��� ����� ����� ������� if (IsArchive || (Global->Opt->FindOpt.FindFolders && !SearchHex) || - !(i.FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) - { + !(i.FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) + { if (IsArchive) { i.FindData.strFileName = i.Arc->strArcName; @@ -2767,8 +2802,9 @@ } } } + }); - itd->Unlock(); + auto hNewPlugin=Global->CtrlObject->Plugins->OpenFindListPlugin(PanelItems.data(), PanelItems.size()); if (hNewPlugin) Index: findfile.hpp =================================================================== --- findfile.hpp (revision 13359) +++ findfile.hpp (working copy) @@ -54,6 +54,7 @@ class InterThreadData; class filemasks; class FileFilter; +struct FindListItem; class FindFiles: noncopyable { @@ -74,7 +75,8 @@ bool LookForString(const string& Name); bool IsFileIncluded(PluginPanelItem* FileItem, const string& FullName, DWORD FileAttr, const string &strDisplayName); intptr_t FindDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Param1, void* Param2); - void AddMenuRecord(Dialog* Dlg,const string& FullName, const os::FAR_FIND_DATA& FindData, void* Data, FARPANELITEMFREECALLBACK FreeData); + void OpenFile(string strSearchFileName, int key, const FindListItem* FindItem, Dialog* Dlg); + void AddMenuRecord(Dialog* Dlg, const string& FullName, const os::FAR_FIND_DATA& FindData, void* Data, FARPANELITEMFREECALLBACK FreeData); void AddMenuRecord(Dialog* Dlg,const string& FullName, PluginPanelItem& FindData); void DoPreparePluginList(Dialog* Dlg, bool Internal); void ArchiveSearch(Dialog* Dlg, const string& ArcName); |
|
looks like I've somehow excluded FarEng.hlf.m4 from the patch... Will update it in a few hours. |
|
4411 |
|
Still needs improvement for emulated filesystems. On one of my PCs, when opening alternate editor while searching inside .zip, it managed to delete temporary file faster then alternate editor starts up. |
|
Fixed: temporary files will be deleted on FindFile closing. This should give enough time for external editor to open temporary file. Fix is attached as 'unicode_far_r13428_FindFileList_fix.patch' |
|
unicode_far_r13428_FindFileList_fix.patch (1,756 bytes)
Index: findfile.cpp =================================================================== --- findfile.cpp (revision 13428) +++ findfile.cpp (working copy) @@ -379,6 +379,16 @@ } }; +// RAII file deletion +class DelayedDeleter : noncopyable +{ + std::wstring m_pathToDelete; + +public: + DelayedDeleter(const std::wstring pathToDelete) : m_pathToDelete(pathToDelete) {} + ~DelayedDeleter() { DeleteFileWithFolder(m_pathToDelete); } +}; + void FindFiles::InitInFileSearch() { if (!InFileSearchInited && !strFindStr.empty()) @@ -1691,7 +1701,8 @@ if (RemoveTemp) { - DeleteFileWithFolder(strSearchFileName); + // external editor may not have enough time to open this file, so deffer deletion + m_DelayedDeleters.emplace_back(strSearchFileName); } return TRUE; } @@ -2956,7 +2967,8 @@ itd(std::make_unique<InterThreadData>()), PauseEvent(Event::manual, Event::signaled), StopEvent(Event::manual, Event::nonsignaled), - m_TimeCheck(time_check::immediate, GetRedrawTimeout()) + m_TimeCheck(time_check::immediate, GetRedrawTimeout()), + m_DelayedDeleters() { _ALGO(CleverSysLog clv(L"FindFiles::FindFiles()")); Index: findfile.hpp =================================================================== --- findfile.hpp (revision 13428) +++ findfile.hpp (working copy) @@ -55,6 +55,7 @@ class filemasks; class FileFilter; struct FindListItem; +class DelayedDeleter; class FindFiles: noncopyable { @@ -128,6 +129,7 @@ std::unique_ptr<InterThreadData> itd; struct CodePageInfo; std::list<CodePageInfo> m_CodePages; + std::list<DelayedDeleter> m_DelayedDeleters; CriticalSection PluginCS; Event PauseEvent; Event StopEvent; |
|
4430. Are you in our 'contributors' list already? |
|
> 4430 Build looks good, thanks. > Are you in our 'contributors' list already? No. My name is Victor Istomin. |
Date Modified | Username | Field | Change |
---|---|---|---|
2015-09-02 10:09 | 4eyes | New Issue | |
2015-09-02 10:09 | 4eyes | File Added: unicode_far_r13359_FindFileList.patch | |
2015-09-02 18:19 | DrKnS | Assigned To | => DrKnS |
2015-09-02 18:19 | DrKnS | Status | new => assigned |
2015-09-02 18:21 | 4eyes | Note Added: 0013819 | |
2015-09-02 18:22 | 4eyes | Note Edited: 0013819 | |
2015-09-02 19:23 | DrKnS | Note Added: 0013820 | |
2015-09-02 19:23 | DrKnS | Status | assigned => feedback |
2015-09-03 13:44 | 4eyes | Note Added: 0013823 | |
2015-09-03 13:44 | 4eyes | Status | feedback => assigned |
2015-10-02 00:44 | 4eyes | Note Added: 0013958 | |
2015-10-02 00:45 | 4eyes | File Added: unicode_far_r13428_FindFileList_fix.patch | |
2015-10-02 00:46 | 4eyes | Note Edited: 0013958 | |
2015-10-02 07:45 | DrKnS | Note Added: 0013959 | |
2015-10-02 07:45 | DrKnS | Status | assigned => feedback |
2015-10-03 12:42 | 4eyes | Note Added: 0013961 | |
2015-10-03 12:42 | 4eyes | Status | feedback => assigned |
2015-10-03 16:08 | DrKnS | Build | => 4430 |
2015-10-03 16:08 | DrKnS | Status | assigned => closed |
2015-10-03 16:08 | DrKnS | Resolution | open => fixed |
2015-10-03 16:08 | DrKnS | Fixed in Version | => 3.0 |