diff --git a/far/REMINDER b/far/REMINDER index ba74591a76..22ff9f00a7 100644 --- a/far/REMINDER +++ b/far/REMINDER @@ -13,11 +13,6 @@ SetConsoleTitle & Macro svs 26.01.2007 16:02:00 +0300 -TPreRedrawFunc - 2SVS: "надо бы описать сей чудный механизм автоматической отрисовки" :) - - drkns 28.11.2008 18:34:19 +0200 - copy.cpp При вызовах apiGetDiskSize использовать не Root, а Dest (если Dest существует) drkns 20.04.2009 14:07:34 +0200 diff --git a/far/TPreRedrawFunc.hpp b/far/TPreRedrawFunc.hpp deleted file mode 100644 index e825d8393a..0000000000 --- a/far/TPreRedrawFunc.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef TPREREDRAWFUNC_HPP_57AEAD28_BBC8_4C43_A40A_5B46CBEA2425 -#define TPREREDRAWFUNC_HPP_57AEAD28_BBC8_4C43_A40A_5B46CBEA2425 -#pragma once - -/* -TPreRedrawFunc.hpp - -Фоновый апдейт - -*/ -/* -Copyright © 2000 Far Group -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -// Internal: - -// Platform: - -// Common: -#include "common/function_traits.hpp" -#include "common/singleton.hpp" - -// External: - -//---------------------------------------------------------------------------- - -class PreRedrawItem: noncopyable -{ -public: - using handler_type = std::function; - - explicit PreRedrawItem(handler_type PreRedrawFunc): - m_PreRedrawFunc(std::move(PreRedrawFunc)) - { - } - - virtual ~PreRedrawItem() = default; - - auto operator()() const - { - m_PreRedrawFunc(); - } - -private: - handler_type m_PreRedrawFunc; -}; - -class TPreRedrawFunc: public singleton -{ - IMPLEMENTS_SINGLETON; - -public: - void push(std::unique_ptr&& Source) - { - m_Items.emplace(std::move(Source)); - } - - auto pop() - { - auto Top = std::move(m_Items.top()); - m_Items.pop(); - return Top; - } - - template - void operator()(const callable& Callable) - { - if (m_Items.empty()) - return; - - // M#3849 - apparently sometimes the top handler isn't the one we're looking for. - // TODO: investigate further. - const auto Handler = dynamic_cast::template arg<0>>*>(m_Items.top().get()); - if (!Handler) - return; - - Callable(*Handler); - } - -private: - TPreRedrawFunc() = default; - - std::stack> m_Items; -}; - -class TPreRedrawFuncGuard: noncopyable -{ -public: - explicit TPreRedrawFuncGuard(std::unique_ptr&& Item) - { - TPreRedrawFunc::instance().push(std::move(Item)); - } - - ~TPreRedrawFuncGuard() - { - TPreRedrawFunc::instance().pop(); - } -}; - -#endif // TPREREDRAWFUNC_HPP_57AEAD28_BBC8_4C43_A40A_5B46CBEA2425 diff --git a/far/changelog b/far/changelog index 34ca19e4ac..f6c5d008c8 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,8 @@ +-------------------------------------------------------------------------------- +drkns 03.08.2021 02:04:01 +0100 - build 5866 + +1. Remove all fake dialogs & preredraw magic. + -------------------------------------------------------------------------------- drkns 02.08.2021 21:01:36 +0100 - build 5865 diff --git a/far/configdb.hpp b/far/configdb.hpp index 931d15aba8..34d1c192e0 100644 --- a/far/configdb.hpp +++ b/far/configdb.hpp @@ -103,9 +103,9 @@ class GeneralConfig : public representable, virtual public transactional auto ValuesEnumerator(lvalue_string_view const Key) const { using value_type = std::pair; - return make_inline_enumerator([=, this](const bool Reset, value_type& Value) + return make_inline_enumerator([=, Self = this](const bool Reset, value_type& Value) { - return EnumValues(Key, Reset, Value.first, Value.second); + return Self->EnumValues(Key, Reset, Value.first, Value.second); }, [this] { @@ -452,9 +452,9 @@ class HistoryConfig: public representable, virtual public transactional auto Enumerator(unsigned int const HistoryType, lvalue_string_view const HistoryName, lvalue_string_view const ItemName = {}, bool const Reverse = false) { using value_type = enum_data; - return make_inline_enumerator([=, this](const bool Reset, value_type& Value) + return make_inline_enumerator([=, Self = this](const bool Reset, value_type& Value) { - return Enum(Reset, HistoryType, HistoryName, ItemName, Value.Id, Value.Name, Value.Type, Value.Lock, Value.Time, Value.Uuid, Value.File, Value.Data, Reverse); + return Self->Enum(Reset, HistoryType, HistoryName, ItemName, Value.Id, Value.Name, Value.Type, Value.Lock, Value.Time, Value.Uuid, Value.File, Value.Data, Reverse); }, [this, Reverse] { diff --git a/far/copy_progress.cpp b/far/copy_progress.cpp index 462094986f..ed2135b24c 100644 --- a/far/copy_progress.cpp +++ b/far/copy_progress.cpp @@ -131,22 +131,8 @@ copy_progress::copy_progress(bool Move, bool Total, bool Time): ProgressDlgItems[progress_items::pr_doublebox].Y2 -= 2; } - m_Dialog = Dialog::create(ProgressDlgItems, [](Dialog* const Dlg, intptr_t const Msg, intptr_t const Param1, void* const Param2) - { - if (Msg == DN_RESIZECONSOLE) - { - COORD Position{ -1, -1 }; - Dlg->SendMessage(DM_MOVEDIALOG, 1, &Position); - } - - return Dlg->DefProc(Msg, Param1, Param2); - }); - const int DialogHeight = ProgressDlgItems[progress_items::pr_doublebox].Y2 - ProgressDlgItems[progress_items::pr_doublebox].Y1 + 1 + 2; - m_Dialog->SetPosition({ -1, -1, DlgW, DialogHeight }); - m_Dialog->SetCanLoseFocus(true); - m_Dialog->Process(); - + init(ProgressDlgItems, { -1, -1, DlgW, DialogHeight }); } size_t copy_progress::CanvasWidth() diff --git a/far/copy_progress.hpp b/far/copy_progress.hpp index a63f8346fb..356b5317f5 100644 --- a/far/copy_progress.hpp +++ b/far/copy_progress.hpp @@ -122,8 +122,6 @@ class copy_progress: progress_impl unsigned long long Total{}; } m_BytesCurrent, m_BytesTotal; - - dialog_ptr m_Dialog; }; #endif // COPY_PROGRESS_HPP_3D1EAAD8_8353_459C_8826_33AAAE06D01F diff --git a/far/delete.cpp b/far/delete.cpp index aed9495094..e2b2e6d5bc 100644 --- a/far/delete.cpp +++ b/far/delete.cpp @@ -42,7 +42,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "scantree.hpp" #include "treelist.hpp" #include "constitle.hpp" -#include "TPreRedrawFunc.hpp" #include "taskbar.hpp" #include "interf.hpp" #include "keyboard.hpp" @@ -77,20 +76,99 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //---------------------------------------------------------------------------- -enum DEL_MODE +struct total_items { - DEL_SCAN, - DEL_DEL, - DEL_WIPE, - DEL_WIPEPROCESS + size_t Items{}; + size_t Size{}; }; -static void PR_ShellDeleteMsg(); +struct progress +{ + size_t Value; + size_t Total; +}; -struct total_items +class delete_progress: progress_impl { - size_t Items{}; - size_t Size{}; + enum + { + DlgW = 76, + DlgH = 10, + }; + + enum items + { + pr_console_title, + pr_doublebox, + pr_message, + pr_file, + pr_wipe_progress, + pr_separator, + pr_total_files, + pr_total_progress, + + pr_count + }; + +public: + delete_progress(bool const Wipe, bool const Total) + { + auto ProgressDlgItems = MakeDialogItems( + { + { DI_TEXT, {{ 0, 0 }, { 0, 0 }}, DIF_HIDDEN, {}, }, + { DI_DOUBLEBOX, {{ 3, 1 }, { DlgW - 4, DlgH - 2 }}, DIF_NONE, msg(Wipe? lng::MDeleteWipeTitle : lng::MDeleteTitle), }, + { DI_TEXT, {{ 5, 2 }, { DlgW - 6, 2 }}, DIF_NONE, msg(Wipe? lng::MDeletingWiping : lng::MDeleting) }, + { DI_TEXT, {{ 5, 3 }, { DlgW - 6, 3 }}, DIF_NONE, {} }, + { DI_TEXT, {{ 5, 4 }, { DlgW - 6, 4 }}, DIF_NONE, {} }, + { DI_TEXT, {{ 5, 5 }, { DlgW - 6, 5 }}, DIF_SEPARATOR, {} }, + { DI_TEXT, {{ 5, 6 }, { DlgW - 6, 6 }}, DIF_NONE, {} }, + { DI_TEXT, {{ 5, 7 }, { DlgW - 6, 7 }}, DIF_NONE, {} }, + }); + + if (!Wipe) + { + ProgressDlgItems[items::pr_wipe_progress].Flags |= DIF_HIDDEN; + + for (size_t i = pr_separator; i <= pr_total_progress; ++i) + { + --ProgressDlgItems[i].Y1; + --ProgressDlgItems[i].Y2; + } + + --ProgressDlgItems[items::pr_doublebox].Y2; + } + + if (!Total) + { + ProgressDlgItems[items::pr_total_progress].Flags |= DIF_HIDDEN; + --ProgressDlgItems[items::pr_doublebox].Y2; + } + + const int DialogHeight = ProgressDlgItems[items::pr_doublebox].Y2 - ProgressDlgItems[items::pr_doublebox].Y1 + 1 + 2; + + init(ProgressDlgItems, { -1, -1, DlgW, DialogHeight }); + } + + void set_wipe_percent(size_t const Percent) const + { + m_Dialog->SendMessage(DM_SETTEXTPTR, items::pr_wipe_progress, UNSAFE_CSTR(make_progressbar(DlgW - 10, Percent, true, true))); + } + + void update(string_view const Name, progress const Files) const + { + m_Dialog->SendMessage(DM_SETTEXTPTR, items::pr_file, UNSAFE_CSTR(null_terminated(Name))); + + if (Files.Total) + { + const auto Percent = ToPercent(Files.Value, Files.Total); + const auto Title = reinterpret_cast(m_Dialog->SendMessage(DM_GETCONSTTEXTPTR, items::pr_doublebox, {})); + m_Dialog->SendMessage(DM_SETTEXTPTR, items::pr_console_title, UNSAFE_CSTR(concat(L'{', str(Percent), L"%} "sv, Title))); + m_Dialog->SendMessage(DM_SETTEXTPTR, items::pr_total_progress, UNSAFE_CSTR(make_progressbar(DlgW - 10, Percent, true, true))); + } + + const auto Str = copy_progress::FormatCounter(lng::MCopyFilesTotalInfo, lng::MCopyBytesTotalInfo, Files.Value, Files.Total, Files.Total != 0, copy_progress::CanvasWidth() - 5); + m_Dialog->SendMessage(DM_SETTEXTPTR, items::pr_total_files, UNSAFE_CSTR(Str)); + } }; class ShellDelete : noncopyable @@ -98,21 +176,16 @@ class ShellDelete : noncopyable public: ShellDelete(panel_ptr SrcPanel, delete_type Type); - struct progress - { - size_t Value; - size_t Total; - }; - private: bool ConfirmDeleteReadOnlyFile(string_view Name, os::fs::attributes Attr); - bool ShellRemoveFile(string_view Name, progress Files); + bool ShellRemoveFile(string_view Name, progress Files, delete_progress const& Progress); bool ERemoveDirectory(string_view Name, delete_type Type, bool& RetryRecycleAsRemove); bool RemoveToRecycleBin(string_view Name, bool dir, bool& RetryRecycleAsRemove, bool& Skip); void process_item( panel_ptr SrcPanel, const os::fs::find_data& SelFindData, const total_items& Total, + delete_progress const& Progress, const time_check& TimeCheck, bool CannotRecycleTryRemove = false ); @@ -127,83 +200,7 @@ class ShellDelete : noncopyable delete_type m_DeleteType; }; -struct DelPreRedrawItem : public PreRedrawItem -{ - DelPreRedrawItem(): - PreRedrawItem(PR_ShellDeleteMsg) - {} - - string name; - DEL_MODE Mode{}; - ShellDelete::progress Files{}; - int WipePercent{}; -}; - -static void ShellDeleteMsgImpl(string_view const Name, DEL_MODE Mode, ShellDelete::progress Files, int WipePercent) -{ - string strProgress, strWipeProgress; - const auto Width = copy_progress::CanvasWidth(); - - if(Mode==DEL_WIPEPROCESS || Mode==DEL_WIPE) - { - strWipeProgress = make_progressbar(Width, WipePercent, true, !Files.Total); - } - - if (Mode!=DEL_SCAN && Files.Total) - { - const auto Percent = ToPercent(Files.Value, Files.Total); - strProgress = make_progressbar(Width, Percent, true, true); - ConsoleTitle::SetFarTitle(concat(L'{', str(Percent), L"%} "sv, msg(Mode == DEL_WIPE || Mode == DEL_WIPEPROCESS? lng::MDeleteWipeTitle : lng::MDeleteTitle))); - } - - { - std::vector MsgItems - { - msg(Mode == DEL_SCAN ? lng::MScanningFolder : (Mode == DEL_WIPE || Mode == DEL_WIPEPROCESS) ? lng::MDeletingWiping : lng::MDeleting), - fit_to_left(truncate_path(Name, Width), Width) - }; - - if (!strWipeProgress.empty()) - MsgItems.emplace_back(strWipeProgress); - - MsgItems.emplace_back(L"\x1"sv); - MsgItems.emplace_back(copy_progress::FormatCounter(lng::MCopyFilesTotalInfo, lng::MCopyBytesTotalInfo, Files.Value, Files.Total, Files.Total != 0, copy_progress::CanvasWidth() - 5)); - - if (!strProgress.empty()) - MsgItems.emplace_back(strProgress); - - Message(MSG_LEFTALIGN, - msg((Mode == DEL_WIPE || Mode == DEL_WIPEPROCESS) ? lng::MDeleteWipeTitle : lng::MDeleteTitle), - std::move(MsgItems), - {}); - } -} - -static void ShellDeleteMsg(string_view const Name, DEL_MODE Mode, ShellDelete::progress Files, int WipePercent) -{ - if (CheckForEscAndConfirmAbort()) - cancel_operation(); - - ShellDeleteMsgImpl(Name, Mode, Files, WipePercent); - - TPreRedrawFunc::instance()([&](DelPreRedrawItem& Item) - { - Item.name = Name; - Item.Mode = Mode; - Item.Files = Files; - Item.WipePercent = WipePercent; - }); -} - -static void PR_ShellDeleteMsg() -{ - TPreRedrawFunc::instance()([](const DelPreRedrawItem& Item) - { - ShellDeleteMsgImpl(Item.name, Item.Mode, Item.Files, Item.WipePercent); - }); -} - -static bool EraseFileData(string_view const Name, ShellDelete::progress Files) +static bool EraseFileData(string_view const Name, progress Files, delete_progress const& Progress) { os::fs::file_walker File; if (!File.Open(Name, FILE_READ_DATA | FILE_WRITE_DATA, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN)) @@ -247,7 +244,13 @@ static bool EraseFileData(string_view const Name, ShellDelete::progress Files) return false; if (TimeCheck) - ShellDeleteMsg(Name, DEL_WIPEPROCESS, Files, File.GetPercent()); + { + if (CheckForEscAndConfirmAbort()) + cancel_operation(); + + Progress.update(Name, Files); + Progress.set_wipe_percent(File.GetPercent()); + } } while(File.Step()); @@ -260,12 +263,12 @@ static bool EraseFileData(string_view const Name, ShellDelete::progress Files) return true; } -static bool EraseFile(string_view const Name, ShellDelete::progress Files) +static bool EraseFile(string_view const Name, progress Files, delete_progress const& Progress) { if (!os::fs::set_file_attributes(Name, FILE_ATTRIBUTE_NORMAL)) return false; - if (!EraseFileData(Name, Files)) + if (!EraseFileData(Name, Files, Progress)) return false; const auto strTempName = MakeTemp({}, false); @@ -439,9 +442,6 @@ static void show_confirmation( static total_items calculate_total(panel_ptr const SrcPanel) { - if (!Global->Opt->DelOpt.ShowTotal) - return {}; - const time_check TimeCheck; total_items Total; dirinfo_progress const DirinfoProgress(msg(lng::MDeletingTitle)); @@ -480,6 +480,7 @@ void ShellDelete::process_item( panel_ptr const SrcPanel, const os::fs::find_data& SelFindData, const total_items& Total, + delete_progress const& Progress, const time_check& TimeCheck, bool const CannotRecycleTryRemove ) @@ -491,13 +492,18 @@ void ShellDelete::process_item( return; if (TimeCheck) - ShellDeleteMsg(strSelName, m_DeleteType == delete_type::erase? DEL_WIPE : DEL_DEL, { ProcessedItems, Total.Items }, 0); + { + if (CheckForEscAndConfirmAbort()) + cancel_operation(); + + Progress.update(strSelName, { ProcessedItems, Total.Items }); + } if (!(SelFindData.Attributes & FILE_ATTRIBUTE_DIRECTORY)) { if (ConfirmDeleteReadOnlyFile(strSelName, SelFindData.Attributes)) { - if (ShellRemoveFile(strSelName, { ProcessedItems, Total.Items }) && m_UpdateDiz) + if (ShellRemoveFile(strSelName, { ProcessedItems, Total.Items }, Progress) && m_UpdateDiz) SrcPanel->DeleteDiz(strSelName, strSelShortName); } @@ -573,6 +579,7 @@ void ShellDelete::process_item( path::join(SrcPanel->GetCurDir(), strSelName); ScTree.SetFindPath(strSelFullName, L"*"sv); + const time_check TreeTimeCheck(time_check::mode::immediate); os::fs::find_data FindData; @@ -580,7 +587,12 @@ void ShellDelete::process_item( while (ScTree.GetNextName(FindData,strFullName)) { if (TreeTimeCheck) - ShellDeleteMsg(strFullName, m_DeleteType == delete_type::erase? DEL_WIPE : DEL_DEL, { ProcessedItems, Total.Items }, 0); + { + if (CheckForEscAndConfirmAbort()) + cancel_operation(); + + Progress.update(strFullName, { ProcessedItems, Total.Items }); + } if (FindData.Attributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -658,7 +670,7 @@ void ShellDelete::process_item( if (ConfirmDeleteReadOnlyFile(strFullName,FindData.Attributes)) { // BUGBUG check result - ShellRemoveFile(strFullName, { ProcessedItems, Total.Items }); + ShellRemoveFile(strFullName, { ProcessedItems, Total.Items }, Progress); } } } @@ -689,7 +701,7 @@ void ShellDelete::process_item( { --ProcessedItems; m_DeleteType = delete_type::remove; - process_item(SrcPanel, SelFindData, Total, TimeCheck, true); + process_item(SrcPanel, SelFindData, Total, Progress, TimeCheck, true); m_DeleteType = delete_type::recycle; } @@ -706,9 +718,6 @@ ShellDelete::ShellDelete(panel_ptr SrcPanel, delete_type const Type): const auto strDizName = SrcPanel->GetDizName(); const auto CheckDiz = [&] { return !strDizName.empty() && os::fs::exists(strDizName); }; const auto DizPresent = CheckDiz(); - - SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique()); - const auto SelCount = SrcPanel->GetSelCount(); if (!SelCount) return; @@ -740,13 +749,13 @@ ShellDelete::ShellDelete(panel_ptr SrcPanel, delete_type const Type): SCOPED_ACTION(wakeful); SetCursorType(false, 0); - const auto Total = calculate_total(SrcPanel); - + delete_progress const Progress(m_DeleteType == delete_type::erase, Global->Opt->DelOpt.ShowTotal); + const auto Total = Global->Opt->DelOpt.ShowTotal? calculate_total(SrcPanel) : total_items{}; const time_check TimeCheck(time_check::mode::immediate); for (const auto& i: SrcPanel->enum_selected()) { - process_item(SrcPanel, i, Total, TimeCheck); + process_item(SrcPanel, i, Total, Progress, TimeCheck); } } @@ -843,11 +852,11 @@ static bool confirm_erase_file_with_hardlinks(string_view const File, int& WipeM } } -static bool erase_file_with_retry(string_view const Name, int& WipeMode, ShellDelete::progress Files, bool& SkipErrors) +static bool erase_file_with_retry(string_view const Name, int& WipeMode, progress const Files, delete_progress const& Progress, bool& SkipErrors) { return confirm_erase_file_with_hardlinks(Name, WipeMode) && - retryable_ui_operation([&]{ return EraseFile(Name, Files); }, Name, lng::MCannotDeleteFile, SkipErrors); + retryable_ui_operation([&]{ return EraseFile(Name, Files, Progress); }, Name, lng::MCannotDeleteFile, SkipErrors); } static bool delete_file_with_retry(string_view const Name, bool& SkipErrors) @@ -855,7 +864,7 @@ static bool delete_file_with_retry(string_view const Name, bool& SkipErrors) return retryable_ui_operation([&]{ return os::fs::delete_file(Name); }, Name, lng::MCannotDeleteFile, SkipErrors); } -bool ShellDelete::ShellRemoveFile(string_view const Name, progress Files) +bool ShellDelete::ShellRemoveFile(string_view const Name, progress Files, delete_progress const& Progress) { ProcessedItems++; const auto strFullName = ConvertNameToFull(Name); @@ -863,7 +872,7 @@ bool ShellDelete::ShellRemoveFile(string_view const Name, progress Files) switch (m_DeleteType) { case delete_type::erase: - return erase_file_with_retry(strFullName, SkipWipeMode, Files, m_SkipFileErrors); + return erase_file_with_retry(strFullName, SkipWipeMode, Files, Progress, m_SkipFileErrors); case delete_type::remove: return delete_file_with_retry(strFullName, m_SkipFileErrors); diff --git a/far/dialog.cpp b/far/dialog.cpp index e510c324d6..c85e9c1e6d 100644 --- a/far/dialog.cpp +++ b/far/dialog.cpp @@ -50,7 +50,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "manager.hpp" #include "savescr.hpp" #include "constitle.hpp" -#include "TPreRedrawFunc.hpp" #include "taskbar.hpp" #include "interf.hpp" #include "strmix.hpp" @@ -510,14 +509,6 @@ void Dialog::Show() if (!DialogMode.Check(DMODE_OBJECTS_INITED) || !DialogMode.Check(DMODE_VISIBLE)) return; - if (DialogMode.Check(DMODE_RESIZED)) - { - TPreRedrawFunc::instance()([](const PreRedrawItem& Item) - { - Item(); - }); - } - DialogMode.Clear(DMODE_RESIZED); DialogMode.Set(DMODE_SHOW); diff --git a/far/dizlist.cpp b/far/dizlist.cpp index a57dc2e8fa..f291cbeace 100644 --- a/far/dizlist.cpp +++ b/far/dizlist.cpp @@ -39,7 +39,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Internal: #include "lang.hpp" -#include "TPreRedrawFunc.hpp" #include "interf.hpp" #include "keyboard.hpp" #include "message.hpp" @@ -75,27 +74,10 @@ void DizList::Reset() m_CodePage.reset(); } -static void PR_ReadingMsg() -{ - Message(0, - {}, - { - msg(lng::MReadingDiz) - }, - {}); -} - void DizList::Read(string_view const Path, const string* DizName) { Reset(); - struct DizPreRedrawItem : public PreRedrawItem - { - DizPreRedrawItem() : PreRedrawItem(PR_ReadingMsg) {} - }; - - SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique()); - const auto ReadDizFile = [this](const string_view Name) { const os::fs::file DizFile(Name, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING); @@ -120,10 +102,11 @@ void DizList::Read(string_view const Path, const string* DizName) if (TimeCheck) { SetCursorType(false, 0); - PR_ReadingMsg(); if (CheckForEscAndConfirmAbort()) break; + + // MReadingDiz unused } inplace::trim_right(DizText); diff --git a/far/far.vcxproj b/far/far.vcxproj index b139b0a34f..685cd47c6c 100644 --- a/far/far.vcxproj +++ b/far/far.vcxproj @@ -549,7 +549,6 @@ cl /nologo /c /Fo"$(IntDir)%(Filename)_c++.testobj" /TP api_test.c - diff --git a/far/far.vcxproj.filters b/far/far.vcxproj.filters index cffecabdbe..9235ac447d 100644 --- a/far/far.vcxproj.filters +++ b/far/far.vcxproj.filters @@ -1087,9 +1087,6 @@ Header Files - - Header Files - Header Files diff --git a/far/keyboard.cpp b/far/keyboard.cpp index 3bef984e78..d08c7d8ad1 100644 --- a/far/keyboard.cpp +++ b/far/keyboard.cpp @@ -46,7 +46,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "scrbuf.hpp" #include "savescr.hpp" #include "lockscrn.hpp" -#include "TPreRedrawFunc.hpp" #include "interf.hpp" #include "message.hpp" #include "config.hpp" @@ -761,11 +760,6 @@ static DWORD ProcessBufferSizeEvent(point const Size) Global->WindowManager->ResizeAllWindows(); Global->WindowManager->GetCurrentWindow()->Show(); - - TPreRedrawFunc::instance()([](const PreRedrawItem& Item) - { - Item(); - }); } return KEY_CONSOLE_BUFFER_RESIZE; diff --git a/far/plugapi.cpp b/far/plugapi.cpp index 08060ef509..509c547ac5 100644 --- a/far/plugapi.cpp +++ b/far/plugapi.cpp @@ -56,7 +56,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ctrlobj.hpp" #include "window.hpp" #include "scrbuf.hpp" -#include "TPreRedrawFunc.hpp" #include "interf.hpp" #include "keyboard.hpp" #include "message.hpp" @@ -90,7 +89,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "global.hpp" #include "lockscrn.hpp" #include "exception_handler.hpp" -#include "history.hpp" // Platform: #include "platform.fs.hpp" @@ -1600,7 +1598,6 @@ intptr_t WINAPI apiGetDirList(const wchar_t *Dir,PluginPanelItem **pPanelItem,si {}); }; - SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique(PR_FarGetDirListMsg)); SCOPED_ACTION(SaveScreen); os::fs::find_data FindData; string strFullName; diff --git a/far/setattr.cpp b/far/setattr.cpp index d960934861..baf9083f55 100644 --- a/far/setattr.cpp +++ b/far/setattr.cpp @@ -45,7 +45,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "panel.hpp" #include "ctrlobj.hpp" #include "constitle.hpp" -#include "TPreRedrawFunc.hpp" #include "taskbar.hpp" #include "keyboard.hpp" #include "message.hpp" @@ -58,7 +57,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "fileowner.hpp" #include "wakeful.hpp" #include "uuids.far.dialogs.hpp" -#include "interf.hpp" #include "plugins.hpp" #include "imports.hpp" #include "lang.hpp" @@ -69,6 +67,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FarDlgBuilder.hpp" #include "cvtname.hpp" #include "log.hpp" +#include "scrbuf.hpp" // Platform: #include "platform.fs.hpp" @@ -537,54 +536,41 @@ static intptr_t SetAttrDlgProc(Dialog* Dlg,intptr_t Msg,intptr_t Param1,void* Pa return Dlg->DefProc(Msg,Param1,Param2); } -static void PR_ShellSetFileAttributesMsg(); - -struct AttrPreRedrawItem : public PreRedrawItem +class setarttr_progress: progress_impl { - AttrPreRedrawItem() : PreRedrawItem(PR_ShellSetFileAttributesMsg){} - - string Name; -}; - -static void ShellSetFileAttributesMsgImpl(string_view const Name) -{ - static int Width=54; - int WidthTemp; + enum + { + DlgW = 76, + DlgH = 5, + }; - if (!Name.empty()) - WidthTemp=std::max(static_cast(Name.size()), 54); - else - Width=WidthTemp=54; + enum items + { + pr_doublebox, + pr_label, + pr_message, - WidthTemp=std::min(WidthTemp, ScrX/2); - Width=std::max(Width,WidthTemp); + pr_count + }; - Message(0, - msg(lng::MSetAttrTitle), +public: + setarttr_progress() + { + auto ProgressDlgItems = MakeDialogItems( { - msg(lng::MSetAttrSetting), - fit_to_center(truncate_path(Name, Width), Width + 4) - }, - {}); -} + { DI_DOUBLEBOX, {{ 3, 1 }, { DlgW - 4, DlgH - 2 }}, DIF_NONE, msg(lng::MSetAttrTitle), }, + { DI_TEXT, {{ 5, 2 }, { DlgW - 6, 2 }}, DIF_NONE, msg(lng::MSetAttrSetting) }, + { DI_TEXT, {{ 5, 2 }, { DlgW - 6, 2 }}, DIF_NONE, {} }, + }); -static void ShellSetFileAttributesMsg(string_view const Name) -{ - ShellSetFileAttributesMsgImpl(Name); - - TPreRedrawFunc::instance()([&](AttrPreRedrawItem& Item) - { - Item.Name = Name; - }); -} + init(ProgressDlgItems, { -1, -1, DlgW, DlgH }); + } -static void PR_ShellSetFileAttributesMsg() -{ - TPreRedrawFunc::instance()([](const AttrPreRedrawItem& Item) + void update(string_view const Msg) const { - ShellSetFileAttributesMsgImpl(Item.Name); - }); -} + m_Dialog->SendMessage(DM_SETTEXTPTR, items::pr_message, UNSAFE_CSTR(null_terminated(Msg))); + } +}; static bool construct_time( os::chrono::time_point const OriginalFileTime, @@ -1231,8 +1217,15 @@ static bool ShellSetFileAttributesImpl(Panel* SrcPanel, const string* Object) AttrDlg[i.TimeId].strData[8] = locale.time_separator(); } - SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique()); - ShellSetFileAttributesMsg(SelCount==1? SingleSelFileName : string{}); + setarttr_progress const Progress; + + if (SelCount == 1) + { + Progress.update(SingleSelFileName); + + Global->WindowManager->PluginCommit(); + Global->ScrBuf->Flush(); + } auto SkipErrors = false; @@ -1275,10 +1268,10 @@ static bool ShellSetFileAttributesImpl(Panel* SrcPanel, const string* Object) { if (TimeCheck) { - ShellSetFileAttributesMsg(SingleSelFileName); - if (CheckForEscAndConfirmAbort()) break; + + Progress.update(SingleSelFileName); } { @@ -1306,7 +1299,7 @@ static bool ShellSetFileAttributesImpl(Panel* SrcPanel, const string* Object) { if (TreeTimeCheck) { - ShellSetFileAttributesMsg(strFullName); + Progress.update(strFullName); if (CheckForEscAndConfirmAbort()) { diff --git a/far/stddlg.cpp b/far/stddlg.cpp index 6b268c93e0..65611de7e8 100644 --- a/far/stddlg.cpp +++ b/far/stddlg.cpp @@ -884,6 +884,24 @@ progress_impl::~progress_impl() m_Dialog->CloseDialog(); } +void progress_impl::init(span const Items, rectangle const Position) +{ + m_Dialog = Dialog::create(Items, [](Dialog* const Dlg, intptr_t const Msg, intptr_t const Param1, void* const Param2) + { + if (Msg == DN_RESIZECONSOLE) + { + COORD Position{ -1, -1 }; + Dlg->SendMessage(DM_MOVEDIALOG, 1, &Position); + } + + return Dlg->DefProc(Msg, Param1, Param2); + }); + + m_Dialog->SetPosition(Position); + m_Dialog->SetCanLoseFocus(true); + m_Dialog->Process(); +} + struct single_progress_detail { enum @@ -917,21 +935,7 @@ single_progress::single_progress(string_view const Title, string_view const Msg, { DI_TEXT, {{ 5, 3 }, { DlgW - 6, 3 }}, DIF_NONE, make_progressbar(DlgW - 10, Percent, true, true) }, }); - m_Dialog = Dialog::create(ProgressDlgItems, [](Dialog* const Dlg, intptr_t const Msg, intptr_t const Param1, void* const Param2) - { - if (Msg == DN_RESIZECONSOLE) - { - COORD Position{ -1, -1 }; - Dlg->SendMessage(DM_MOVEDIALOG, 1, &Position); - } - - return Dlg->DefProc(Msg, Param1, Param2); - }); - - m_Dialog->SetPosition({ -1, -1, DlgW, DlgH }); - m_Dialog->SetCanLoseFocus(true); - m_Dialog->Hide(); - m_Dialog->Process(); + init(ProgressDlgItems, { -1, -1, DlgW, DlgH }); } void single_progress::update(string_view const Msg) const @@ -984,21 +988,7 @@ dirinfo_progress::dirinfo_progress(string_view const Title) { DI_TEXT, {{ 5, 6 }, { DlgW - 6, 6 }}, DIF_NONE, {} }, }); - m_Dialog = Dialog::create(ProgressDlgItems, [](Dialog* const Dlg, intptr_t const Msg, intptr_t const Param1, void* const Param2) - { - if (Msg == DN_RESIZECONSOLE) - { - COORD Position{ -1, -1 }; - Dlg->SendMessage(DM_MOVEDIALOG, 1, &Position); - } - - return Dlg->DefProc(Msg, Param1, Param2); - }); - - m_Dialog->SetPosition({ -1, -1, DlgW, DlgH }); - m_Dialog->SetCanLoseFocus(true); - m_Dialog->Process(); - m_Dialog->Hide(); + init(ProgressDlgItems, { -1, -1, DlgW, DlgH }); } void dirinfo_progress::set_name(string_view const Msg) const diff --git a/far/stddlg.hpp b/far/stddlg.hpp index 6f173c9733..9a591d8d78 100644 --- a/far/stddlg.hpp +++ b/far/stddlg.hpp @@ -37,6 +37,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Internal: #include "windowsfwd.hpp" +#include "dialog.hpp" // Platform: @@ -200,6 +201,8 @@ class progress_impl progress_impl() = default; ~progress_impl(); + void init(span Items, rectangle Position); + dialog_ptr m_Dialog; }; diff --git a/far/treelist.cpp b/far/treelist.cpp index c8b934ed9d..1e93c2e840 100644 --- a/far/treelist.cpp +++ b/far/treelist.cpp @@ -52,7 +52,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "lockscrn.hpp" #include "macroopcode.hpp" #include "refreshwindowmanager.hpp" -#include "TPreRedrawFunc.hpp" #include "taskbar.hpp" #include "interf.hpp" #include "message.hpp" @@ -77,6 +76,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "cvtname.hpp" #include "global.hpp" #include "network.hpp" +#include "dialog.hpp" +#include "stddlg.hpp" +#include "datetime.hpp" #if defined(TREEFILE_PROJECT) #include "drivemix.hpp" #endif @@ -616,61 +618,41 @@ void TreeList::Update(int Mode) } } -static void PR_MsgReadTree(); - -struct TreePreRedrawItem: public PreRedrawItem -{ - TreePreRedrawItem(): - PreRedrawItem(PR_MsgReadTree), - TreeCount() - {} - - size_t TreeCount; -}; - -static void MsgReadTreeImpl(size_t TreeCount) +class tree_progress: progress_impl { - /* $ 24.09.2001 VVM - ! Писать сообщение о чтении дерева только, если это заняло более 500 мсек. */ - const auto IsChangeConsole = LastScrX != ScrX || LastScrY != ScrY; - - if (IsChangeConsole) + enum { - LastScrX = ScrX; - LastScrY = ScrY; - } + DlgW = 76, + DlgH = 6, + }; - if (IsChangeConsole || std::chrono::steady_clock::now() - TreeStartTime > 1s) + enum items { - Message(0, - msg(lng::MTreeTitle), - { - msg(lng::MReadingTree), - str(TreeCount) - }, - {}); - - TreeStartTime = std::chrono::steady_clock::now(); - } -} + pr_doublebox, + pr_message, + pr_dirs, -static void MsgReadTree(size_t TreeCount) -{ - MsgReadTreeImpl(TreeCount); + pr_count + }; - TPreRedrawFunc::instance()([&](TreePreRedrawItem& Item) +public: + tree_progress() { - Item.TreeCount = TreeCount; - }); -} + auto ProgressDlgItems = MakeDialogItems( + { + { DI_DOUBLEBOX, {{ 3, 1 }, { DlgW - 4, DlgH - 2 }}, DIF_NONE, msg(lng::MTreeTitle), }, + { DI_TEXT, {{ 5, 2 }, { DlgW - 6, 2 }}, DIF_NONE, msg(lng::MReadingTree) }, + { DI_TEXT, {{ 5, 3 }, { DlgW - 6, 3 }}, DIF_NONE, {} }, + }); -static void PR_MsgReadTree() -{ - TPreRedrawFunc::instance()([](const TreePreRedrawItem& Item) + init(ProgressDlgItems, { -1, -1, DlgW, DlgH }); + } + + void update(size_t const Count) const { - MsgReadTreeImpl(Item.TreeCount); - }); -} + m_Dialog->SendMessage(DM_SETTEXTPTR, items::pr_dirs, UNSAFE_CSTR(str(Count))); + } +}; static os::fs::file OpenTreeFile(string_view const Name, bool const Writable) { @@ -798,7 +780,6 @@ bool TreeList::ReadTree() m_ReadingTree = true; SCOPE_EXIT{ m_ReadingTree = false; }; - SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique()); ScanTree ScTree(false, true, -1); os::fs::find_data fdata; string strFullName; @@ -821,21 +802,27 @@ bool TreeList::ReadTree() LastScrY = ScrY; SCOPED_ACTION(taskbar::indeterminate); SCOPED_ACTION(wakeful); + tree_progress const TreeProgress; + time_check TimeCheck; + while (ScTree.GetNextName(fdata,strFullName)) { - MsgReadTree(m_ListData.size()); - - // BUGBUG, Dialog calls Commit, TreeList redraws and crashes. - if (CheckForEscAndConfirmAbort()) - Aborted = true; - - if (Aborted) - break; - if (!(fdata.Attributes & FILE_ATTRIBUTE_DIRECTORY)) continue; m_ListData.emplace_back(strFullName); + + if (TimeCheck) + { + // BUGBUG, Dialog calls Commit, TreeList redraws and crashes. + if (CheckForEscAndConfirmAbort()) + { + Aborted = true; + break; + } + + TreeProgress.update(m_ListData.size()); + } } if (Aborted && m_ModalMode) @@ -1866,7 +1853,6 @@ void TreeList::ReadSubTree(string_view const Path) if (!os::fs::is_directory(Path)) return; - SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique()); ScanTree ScTree(false, true, -1); const auto strDirName = ConvertNameToFull(Path); @@ -1878,17 +1864,24 @@ void TreeList::ReadSubTree(string_view const Path) os::fs::find_data fdata; string strFullName; int Count = 0; + + tree_progress const TreeProgress; + time_check TimeCheck; + while (ScTree.GetNextName(fdata, strFullName)) { - if (fdata.Attributes & FILE_ATTRIBUTE_DIRECTORY) - { - MsgReadTree(Count + 1); + if (!(fdata.Attributes & FILE_ATTRIBUTE_DIRECTORY)) + continue; + AddTreeName(strFullName); + ++Count; + + if (TimeCheck) + { if (CheckForEscAndConfirmAbort()) break; - AddTreeName(strFullName); - ++Count; + TreeProgress.update(Count); } } } diff --git a/far/vbuild.m4 b/far/vbuild.m4 index e2fede57f6..69b0804d31 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -5865 +5866 diff --git a/far/viewer.cpp b/far/viewer.cpp index 70483a8ab7..9d69d34617 100644 --- a/far/viewer.cpp +++ b/far/viewer.cpp @@ -49,7 +49,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "fileview.hpp" #include "ctrlobj.hpp" #include "scrbuf.hpp" -#include "TPreRedrawFunc.hpp" #include "taskbar.hpp" #include "drivemix.hpp" #include "interf.hpp" @@ -2630,63 +2629,6 @@ intptr_t Viewer::ViewerSearchDlgProc(Dialog* Dlg,intptr_t Msg,intptr_t Param1,vo return Dlg->DefProc(Msg,Param1,Param2); } -static void PR_ViewerSearchMsg(); - -struct ViewerPreRedrawItem : public PreRedrawItem -{ - ViewerPreRedrawItem(): - PreRedrawItem(PR_ViewerSearchMsg), - percent(), - hex() - {} - - string name; - int percent; - int hex; -}; - -static void ViewerSearchMsgImpl(string_view const MsgStr, int Percent, int SearchHex) -{ - string strProgress; - const auto strMsg = concat(msg(SearchHex? lng::MViewSearchingHex : lng::MViewSearchingFor), L' ', MsgStr); - if (Percent>=0) - { - const size_t Length = std::max(std::min(ScrX - 1 - 10, static_cast(strMsg.size())), 40); - strProgress = make_progressbar(Length, Percent, true, true); - } - - { - std::vector MsgItems{ strMsg }; - if (!strProgress.empty()) - MsgItems.emplace_back(strProgress); - - Message(MSG_LEFTALIGN, - msg(lng::MViewSearchTitle), - std::move(MsgItems), - {}); - } -} - -static void ViewerSearchMsg(string_view const MsgStr, int Percent, int SearchHex) -{ - ViewerSearchMsgImpl(MsgStr, Percent, SearchHex); - - TPreRedrawFunc::instance()([&](ViewerPreRedrawItem& Item) - { - Item.name = MsgStr; - Item.percent = Percent; - Item.hex = SearchHex; - }); -} - -static void PR_ViewerSearchMsg() -{ - TPreRedrawFunc::instance()([](const ViewerPreRedrawItem& Item) - { - ViewerSearchMsgImpl(Item.name, Item.percent, Item.hex); - }); -} - static auto hex2ss(const string_view from, intptr_t * const pos = nullptr) { if (pos) @@ -3432,10 +3374,11 @@ void Viewer::Search(int Next,const Manager::Key* FirstChar) sd.CurPos = LastSelectPos; { SCOPED_ACTION(taskbar::indeterminate); - SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique()); SetCursorType(false, 0); + single_progress const Progress(msg(lng::MViewSearchTitle), concat(msg(SearchHex? lng::MViewSearchingHex : lng::MViewSearchingFor), L' ', strMsgStr), 0); const time_check TimeCheck; + for (;;) { const auto found = std::invoke(searcher, this, &sd); @@ -3487,7 +3430,7 @@ void Viewer::Search(int Next,const Manager::Key* FirstChar) return; } - int percent = -1; + int percent{}; long long total = FileSize; if ( total > 0 ) { @@ -3508,7 +3451,8 @@ void Viewer::Search(int Next,const Manager::Key* FirstChar) } percent = static_cast(done*100/total); } - ViewerSearchMsg(strMsgStr, percent, SearchHex); + + Progress.update(percent); } } }