From 8f4f32c65486ff889f0c609355816817b23c24d8 Mon Sep 17 00:00:00 2001 From: Alex Alabuzhev Date: Sun, 25 Jul 2021 19:42:55 +0100 Subject: [PATCH] Copy progress is a real dialog now. Yay. --- far/changelog | 5 ++ far/copy.cpp | 53 ++++++------- far/copy_progress.cpp | 170 ++++++++++++++++++++++++++++-------------- far/copy_progress.hpp | 7 +- far/dialog.cpp | 4 +- far/editor.cpp | 1 - far/manager.cpp | 5 +- far/message.cpp | 17 +---- far/message.hpp | 2 - far/platform.com.cpp | 1 - far/vbuild.m4 | 2 +- 11 files changed, 159 insertions(+), 108 deletions(-) diff --git a/far/changelog b/far/changelog index a3003a44d6..251b302d3c 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,8 @@ +-------------------------------------------------------------------------------- +drkns 25.07.2021 19:40:43 +0100 - build 5855 + +1. Copy progress is a real dialog now. Yay. + -------------------------------------------------------------------------------- drkns 23.07.2021 01:41:38 +0100 - build 5854 diff --git a/far/copy.cpp b/far/copy.cpp index 51b3704b85..d45f4270e4 100644 --- a/far/copy.cpp +++ b/far/copy.cpp @@ -149,8 +149,7 @@ class ShellCopy : noncopyable void SetSecurity(const string& FileName, const os::security::descriptor& sd); void ResetSecurity(const string& FileName); - // called by copy_selected_items - void CalcTotalSize() const; + std::pair CalcTotalSize() const; void ShellSetAttr(const string& Dest, os::fs::attributes Attr); void SetDestDizPath(const string& DestPath); @@ -206,7 +205,6 @@ class ShellCopy : noncopyable bool FilesPresent{}; bool AskRO{}; bool m_UseFilter{}; - bool m_TotalSizeCalculated{}; HANDLE m_FileHandleForStreamSizeFix{}; size_t m_NumberOfTargets{}; std::list m_CreatedFolders; @@ -1297,17 +1295,30 @@ ShellCopy::ShellCopy( } if (!CP) - CP = std::make_unique(Move, ShowTotalCopySize, ShowCopyTime); + { + unsigned long long + TotalFiles{}, + TotalBytes{}; - CP->reset_current(); + if (SelCount != 1 || FolderPresent) + { + // Не сканируем каталоги при создании линков + if (ShowTotalCopySize && !(Flags & FCOPY_LINK)) + std::tie(TotalFiles, TotalBytes) = CalcTotalSize(); + } + else + { + TotalFiles = 1; + TotalBytes = SingleSelectedFileSize; + } - if (SelCount == 1 && !FolderPresent) - { - CP->set_total_files(1); - CP->set_total_bytes(SingleSelectedFileSize); - CP->set_current_total(SingleSelectedFileSize); + CP = std::make_unique(Move, ShowTotalCopySize, ShowCopyTime); + CP->set_total_files(TotalFiles); + CP->set_total_bytes(TotalBytes); } + CP->reset_current(); + // Обнулим инфу про дизы strDestDizPath.clear(); Flags&=~FCOPY_DIZREAD; @@ -1367,19 +1378,6 @@ void ShellCopy::copy_selected_items(const string& Dest) const auto move_rename = (0 != (Flags & FCOPY_MOVE)); bool SameDisk = false; - if (!m_TotalSizeCalculated) - { - // ! Не сканируем каталоги при создании линков - if (CP->IsTotalVisible() && !(Flags & FCOPY_LINK)) - CalcTotalSize(); - - m_TotalSizeCalculated = true; - } - else - { - CP->reset_current(); - } - // Основной цикл копирования одной порции. // for (const auto& i: SrcPanel->enum_selected()) @@ -3332,7 +3330,7 @@ DWORD ShellCopy::CopyProgressRoutine(unsigned long long TotalFileSize, unsigned return Abort?PROGRESS_CANCEL:PROGRESS_CONTINUE; } -void ShellCopy::CalcTotalSize() const +std::pair ShellCopy::CalcTotalSize() const { unsigned long long Files{}, Bytes{}; @@ -3373,8 +3371,11 @@ void ShellCopy::CalcTotalSize() const } // INFO: Это для варианта, когда "ВСЕГО = общий размер * количество целей" - CP->set_total_files(Files * m_NumberOfTargets); - CP->set_total_bytes(Bytes * m_NumberOfTargets); + return + { + Files * m_NumberOfTargets, + Bytes * m_NumberOfTargets + }; } /* diff --git a/far/copy_progress.cpp b/far/copy_progress.cpp index b3904a2db6..d9ab571213 100644 --- a/far/copy_progress.cpp +++ b/far/copy_progress.cpp @@ -35,7 +35,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "copy_progress.hpp" // Internal: -#include "colormix.hpp" #include "lang.hpp" #include "config.hpp" #include "keyboard.hpp" @@ -44,8 +43,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "strmix.hpp" #include "interf.hpp" #include "message.hpp" -#include "scrbuf.hpp" -#include "global.hpp" +#include "dialog.hpp" // Platform: @@ -59,21 +57,105 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* Общее время ожидания пользователя */ extern std::chrono::steady_clock::duration WaitUserTime; +namespace +{ + enum + { + DlgW = 76, + DlgH = 15, + }; + + enum progress_items + { + pr_doublebox, + pr_src_label, + pr_src_name, + pr_dst_label, + pr_dst_name, + pr_current_progress, + pr_separator1, + pr_total_files, + pr_total_bytes, + pr_total_progress, + pr_separator2, + pr_stats, + + pr_count + }; +} + copy_progress::copy_progress(bool Move, bool Total, bool Time): m_CurrentBarSize(CanvasWidth()), m_TotalBarSize(CanvasWidth()), m_Move(Move), m_Total(Total), m_ShowTime(Time), - m_Color(colors::PaletteColorToFarColor(COL_DIALOGTEXT)), m_TimeCheck(time_check::mode::immediate, GetRedrawTimeout()), m_SpeedUpdateCheck(time_check::mode::immediate, 3s) { + auto ProgressDlgItems = MakeDialogItems( + { + { DI_DOUBLEBOX, {{ 3, 1 }, { DlgW - 4, DlgH - 2 }}, DIF_NONE, msg(m_Move? lng::MMoveDlgTitle : lng::MCopyDlgTitle), }, + { DI_TEXT, {{ 5, 2 }, { DlgW - 6, 2 }}, DIF_NONE, msg(m_Move? lng::MCopyMoving :lng::MCopyCopying), }, + { DI_TEXT, {{ 5, 3 }, { DlgW - 6, 3 }}, DIF_NONE, {}, }, + { DI_TEXT, {{ 5, 4 }, { DlgW - 6, 4 }}, DIF_NONE, msg(lng::MCopyTo), }, + { DI_TEXT, {{ 5, 5 }, { DlgW - 6, 5 }}, DIF_NONE, {}, }, + { DI_TEXT, {{ 5, 6 }, { DlgW - 6, 6 }}, DIF_NONE, make_progressbar(CanvasWidth(), 0, true, false) }, + { DI_TEXT, {{-1, 7 }, { DlgW - 6, 7 }}, DIF_SEPARATOR, msg(lng::MCopyDlgTotal), }, + { DI_TEXT, {{ 5, 8 }, { DlgW - 6, 8 }}, DIF_NONE, {}, }, + { DI_TEXT, {{ 5, 9 }, { DlgW - 6, 9 }}, DIF_NONE, {}, }, + { DI_TEXT, {{ 5, 10}, { DlgW - 6, 10}}, DIF_NONE, make_progressbar(CanvasWidth(), 0, true, false), }, + { DI_TEXT, {{-1, 11}, { DlgW - 6, 11}}, DIF_SEPARATOR, {}, }, + { DI_TEXT, {{ 5, 12}, { DlgW - 6, 12}}, DIF_NONE, {}, }, + }); + + if (!m_Total) + { + ProgressDlgItems[progress_items::pr_total_progress].Flags |= DIF_HIDDEN; + + for (size_t i = progress_items::pr_total_progress + 1; i != progress_items::pr_count; ++i) + { + --ProgressDlgItems[i].Y1; + --ProgressDlgItems[i].Y2; + } + + --ProgressDlgItems[progress_items::pr_doublebox].Y2; + } + + if (!m_ShowTime) + { + ProgressDlgItems[progress_items::pr_separator2].Flags |= DIF_HIDDEN; + ProgressDlgItems[progress_items::pr_stats].Flags |= DIF_HIDDEN; + 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(); + +} + +copy_progress::~copy_progress() +{ + if (m_Dialog) + m_Dialog->CloseDialog(); } size_t copy_progress::CanvasWidth() { - return 52; + return DlgW - 10; } void copy_progress::skip() @@ -150,27 +232,42 @@ void copy_progress::Flush() if (!m_TimeCheck || CheckEsc()) return; - CreateBackground(); + SCOPED_ACTION(Dialog::suppress_redraw)(m_Dialog.get()); + + m_Dialog->SendMessage(DM_SETTEXTPTR, progress_items::pr_src_name, UNSAFE_CSTR(m_Src)); + m_Dialog->SendMessage(DM_SETTEXTPTR, progress_items::pr_dst_name, UNSAFE_CSTR(m_Dst)); + + const auto CurrentProgress = make_progressbar(m_CurrentBarSize, m_CurrentPercent, true, !m_Total); + m_Dialog->SendMessage(DM_SETTEXTPTR, progress_items::pr_current_progress, UNSAFE_CSTR(CurrentProgress)); - Text({ m_Rect.left + 5, m_Rect.top + 3 }, m_Color, m_Src); - Text({ m_Rect.left + 5, m_Rect.top + 5 }, m_Color, m_Dst); - Text({ m_Rect.left + 5, m_Rect.top + 8 }, m_Color, m_FilesCopied); + m_Dialog->SendMessage(DM_SETTEXTPTR, progress_items::pr_total_files, UNSAFE_CSTR(m_FilesCopied)); const auto Result = FormatCounter(lng::MCopyBytesTotalInfo, lng::MCopyFilesTotalInfo, m_BytesTotal.Copied, m_BytesTotal.Total, m_Total, CanvasWidth() - 5); - Text({ m_Rect.left + 5, m_Rect.top + 9 }, m_Color, Result); + m_Dialog->SendMessage(DM_SETTEXTPTR, progress_items::pr_total_bytes, UNSAFE_CSTR(Result)); - if (!m_Time.empty()) + if (m_Total) { - const size_t Width = m_Rect.width() - 10; - const auto XPos = m_Rect.left + 5; - const auto YPos = m_Rect.top + (m_Total? 12 : 11); + const auto TotalProgress = make_progressbar(m_TotalBarSize, m_TotalPercent, true, true); + m_Dialog->SendMessage(DM_SETTEXTPTR, progress_items::pr_total_progress, UNSAFE_CSTR(TotalProgress)); + } + if (!m_Time.empty()) + { + const auto Width = CanvasWidth(); const auto ConsumedSpace = m_Time.size() + 1 + m_TimeLeft.size() + 1 + m_Speed.size(); - const auto FillerWidth = ConsumedSpace >= Width? 0 : (Width - ConsumedSpace) / 2; + const auto RemainingSpace = ConsumedSpace > Width? 0 : Width - ConsumedSpace; + const auto FirstFillerWidth = RemainingSpace / 2; + const auto SecondFillerWidth = RemainingSpace - FirstFillerWidth; + + const auto Stat = cut_right( + concat( + fit_to_left(m_Time, m_Time.size() + 1 + FirstFillerWidth), + fit_to_left(m_TimeLeft, m_TimeLeft.size() + 1 + SecondFillerWidth), + m_Speed), + Width + ); - Text({ XPos, YPos }, m_Color, m_Time); - Text({ static_cast(XPos + m_Time.size() + 1 + FillerWidth), YPos }, m_Color, m_TimeLeft); - Text({ static_cast(m_Rect.right + 1 - 5 - m_Speed.size()), YPos }, m_Color, m_Speed); + m_Dialog->SendMessage(DM_SETTEXTPTR, progress_items::pr_stats, UNSAFE_CSTR(Stat)); } if (m_Total || (m_Files.Total == 1)) @@ -180,8 +277,6 @@ void copy_progress::Flush() msg(m_Move? lng::MCopyMovingTitle : lng::MCopyCopyingTitle)) ); } - - Global->ScrBuf->Flush(); } void copy_progress::reset_current() @@ -235,41 +330,6 @@ void copy_progress::add_total_bytes(unsigned long long const Value) m_BytesTotal.Total += Value; } -void copy_progress::CreateBackground() -{ - const auto& Title = msg(m_Move? lng::MMoveDlgTitle : lng::MCopyDlgTitle); - - std::vector Items = - { - msg(m_Move? lng::MCopyMoving :lng::MCopyCopying), - {}, // source name - msg(lng::MCopyTo), - {}, // dest path - make_progressbar(m_CurrentBarSize, m_CurrentPercent, true, !m_Total), - L'\x1' + msg(lng::MCopyDlgTotal), - {}, // files [total] - {} // bytes [total] - }; - - // total progress bar - if (m_Total) - { - Items.emplace_back(make_progressbar(m_TotalBarSize, m_TotalPercent, true, true)); - } - - // time & speed - if (m_ShowTime) - { - Items.emplace_back(L"\x1"sv); - Items.emplace_back(); - } - - m_Rect = Message(MSG_LEFTALIGN | MSG_NOFLUSH, - Title, - std::move(Items), - {}).GetPosition(); -} - void copy_progress::SetNames(const string& Src, const string& Dst) { if (m_ShowTime && !m_Files.Copied) diff --git a/far/copy_progress.hpp b/far/copy_progress.hpp index 5214d573b1..5f28f3baf2 100644 --- a/far/copy_progress.hpp +++ b/far/copy_progress.hpp @@ -37,6 +37,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "wakeful.hpp" #include "datetime.hpp" #include "plugin.hpp" +#include "windowsfwd.hpp" // Platform: @@ -53,6 +54,7 @@ class copy_progress: noncopyable { public: copy_progress(bool Move, bool Total, bool Time); + ~copy_progress(); bool IsCancelled() const { return m_IsCancelled; } bool IsTotalVisible() const { return m_Total; } @@ -80,7 +82,6 @@ class copy_progress: noncopyable private: bool CheckEsc(); void Flush(); - void CreateBackground(); void SetCurrentProgress(unsigned long long CompletedSize, unsigned long long TotalSize); void SetTotalProgress(unsigned long long CompletedSize, unsigned long long TotalSize); void UpdateTime(unsigned long long SizeDone, unsigned long long SizeToGo); @@ -88,7 +89,6 @@ class copy_progress: noncopyable std::chrono::steady_clock::time_point m_CopyStartTime; taskbar::indeterminate m_TB; wakeful m_Wakeful; - small_rectangle m_Rect{}; size_t m_CurrentBarSize; int m_CurrentPercent{}; @@ -100,7 +100,6 @@ class copy_progress: noncopyable bool m_Total; bool m_ShowTime; bool m_IsCancelled{}; - FarColor m_Color; time_check m_TimeCheck; time_check m_SpeedUpdateCheck; string m_Src, m_Dst; @@ -125,6 +124,8 @@ class copy_progress: noncopyable 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/dialog.cpp b/far/dialog.cpp index 8f8c58ef9d..f3a1db8f67 100644 --- a/far/dialog.cpp +++ b/far/dialog.cpp @@ -445,7 +445,7 @@ void Dialog::CheckDialogCoord() // X2 при этом = ширине диалога. if (m_Where.left == -1) { - m_Where.left = (ScrX - m_Where.right + 1) / 2; + m_Where.left = (ScrX + 1 - m_Where.right) / 2; m_Where.right += m_Where.left - 1; } @@ -453,7 +453,7 @@ void Dialog::CheckDialogCoord() // Y2 при этом = высоте диалога. if (m_Where.top == -1) { - m_Where.top = (ScrY - m_Where.bottom + 1) / 2; + m_Where.top = (ScrY + 1 - m_Where.bottom) / 2; m_Where.bottom += m_Where.top - 1; } } diff --git a/far/editor.cpp b/far/editor.cpp index e767021a6b..4587c69f18 100644 --- a/far/editor.cpp +++ b/far/editor.cpp @@ -6941,7 +6941,6 @@ namespace editor_progress::editor_progress(string_view const Title, string_view const Msg, size_t const Percent) { - auto ProgressDlgItems = MakeDialogItems( { { DI_DOUBLEBOX, {{ 3, 1 }, { DlgW - 4, DlgH - 2 }}, DIF_NONE, Title, }, diff --git a/far/manager.cpp b/far/manager.cpp index c9deb018e2..ad76e02463 100644 --- a/far/manager.cpp +++ b/far/manager.cpp @@ -930,7 +930,6 @@ void Manager::DeleteCommit(const window_ptr& Param) Param->OnDestroy(); const auto WindowIndex=IndexOf(Param); - assert(-1!=WindowIndex); if (-1!=WindowIndex) { @@ -969,9 +968,7 @@ void Manager::DeleteCommit(const window_ptr& Param) m_Executed.erase(stop); } - [[maybe_unused]] - const auto size = m_Added.erase(Param); - assert(size==1); + m_Added.erase(Param); } void Manager::ActivateCommit(const window_ptr& Param) diff --git a/far/message.cpp b/far/message.cpp index 5eaa293f26..1e13ec22d8 100644 --- a/far/message.cpp +++ b/far/message.cpp @@ -286,7 +286,7 @@ void Message::Init( int MessageWidth = static_cast(MaxLength + 6 + 2 + 2); // 6 for frame, 2 for border, 2 for inner margin if (MessageWidth < ScrX) { - m_Position.left = (ScrX - MessageWidth) / 2 + 1; + m_Position.left = (ScrX + 1 - MessageWidth) / 2; } else { @@ -515,22 +515,13 @@ void Message::Init( макроса запретом отрисовки (bugz#533). */ - if (!(Flags & MSG_NOFLUSH)) - { - if (Global->ScrBuf->GetLockCount()>0 && !Global->CtrlObject->Macro.PeekKey()) - Global->ScrBuf->SetLockCount(0); + if (Global->ScrBuf->GetLockCount()>0 && !Global->CtrlObject->Macro.PeekKey()) + Global->ScrBuf->SetLockCount(0); - Global->ScrBuf->Flush(); - } + Global->ScrBuf->Flush(); } } - -rectangle Message::GetPosition() const -{ - return m_Position; -} - /* $ 12.03.2002 VVM Новая функция - пользователь попытался прервать операцию. Зададим вопрос. diff --git a/far/message.hpp b/far/message.hpp index c753cccf91..ac3b88595d 100644 --- a/far/message.hpp +++ b/far/message.hpp @@ -59,7 +59,6 @@ enum MSG_KILLSAVESCREEN = 28_bit, MSG_NOPLUGINS = 29_bit, - MSG_NOFLUSH = 30_bit, }; class Plugin; @@ -111,7 +110,6 @@ class Message }; result GetExitCode() const {return static_cast(m_ExitCode);} - rectangle GetPosition() const; operator result() const { return GetExitCode(); } private: diff --git a/far/platform.com.cpp b/far/platform.com.cpp index d36644c5e8..89e0a12d01 100644 --- a/far/platform.com.cpp +++ b/far/platform.com.cpp @@ -191,7 +191,6 @@ namespace os::com string Description; if (!reg::key::classes_root.get(Type, {}, Description)) { - LOGWARNING(L"classes_root.get({}): {}"sv, Type, last_error()); return {}; } diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 0bd4af7d6f..e885b56e61 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -5854 +5855