From 602f98fe671a56724f2febcceb7b03b0da80a51c Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Fri, 16 Apr 2021 18:41:44 -0700 Subject: [PATCH] FileManager: Estimate transfer time Use the total bytes transferred count to estimate the time left for the copy operation to finish. With the estimate label, the two progress bars were deemed superfluous, so the only remaining progress bar is the overall copy progress, that is updated more frequently. (The same progress is also shown in the task bar, so you can minimize the window and still be informed of the progress.) --- .../FileManager/FileOperationProgress.gml | 19 +++---- .../FileOperationProgressWidget.cpp | 55 ++++++++++++++++--- .../FileManager/FileOperationProgressWidget.h | 4 ++ 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/Userland/Applications/FileManager/FileOperationProgress.gml b/Userland/Applications/FileManager/FileOperationProgress.gml index ab7012deff..c1aaada483 100644 --- a/Userland/Applications/FileManager/FileOperationProgress.gml +++ b/Userland/Applications/FileManager/FileOperationProgress.gml @@ -29,6 +29,7 @@ text_alignment: "CenterLeft" font_weight: "Bold" fixed_height: 32 + name: "files_copied_label" } @GUI::HorizontalSeparator { @@ -36,7 +37,7 @@ } @GUI::Widget { - fixed_height: 32 + fixed_height: 22 layout: @GUI::HorizontalBoxLayout { } @@ -55,28 +56,22 @@ } } - @GUI::Progressbar { - fixed_height: 22 - name: "current_file_progressbar" - min: 0 - } - @GUI::Widget { - fixed_height: 32 + fixed_height: 22 layout: @GUI::HorizontalBoxLayout { } @GUI::Label { - text: "Overall progress: " + text: "Time left: " font_weight: "Bold" text_alignment: "CenterLeft" - fixed_width: 120 + fixed_width: 80 } @GUI::Label { - name: "overall_progress_label" - text: "Placeholder" + name: "estimated_time_label" + text: "Estimating..." text_alignment: "CenterLeft" } } diff --git a/Userland/Applications/FileManager/FileOperationProgressWidget.cpp b/Userland/Applications/FileManager/FileOperationProgressWidget.cpp index 5adbc0711f..e79f56c0e1 100644 --- a/Userland/Applications/FileManager/FileOperationProgressWidget.cpp +++ b/Userland/Applications/FileManager/FileOperationProgressWidget.cpp @@ -86,6 +86,8 @@ FileOperationProgressWidget::FileOperationProgressWidget(NonnullRefPtrclose(); } -void FileOperationProgressWidget::did_progress([[maybe_unused]] off_t bytes_done, [[maybe_unused]] off_t total_byte_count, size_t files_done, size_t total_file_count, off_t current_file_done, off_t current_file_size, const StringView& current_file_name) +String FileOperationProgressWidget::estimate_time(off_t bytes_done, off_t total_byte_count) { + int elapsed = m_elapsed_timer.elapsed() / 1000; + + if (bytes_done == 0 || elapsed < 3) + return "Estimating..."; + + off_t bytes_left = total_byte_count - bytes_done; + int seconds_remaining = (bytes_left * elapsed) / bytes_done; + + if (seconds_remaining < 30) + return String::formatted("{} seconds", 5 + seconds_remaining - seconds_remaining % 5); + if (seconds_remaining < 60) + return "About a minute"; + if (seconds_remaining < 90) + return "Over a minute"; + if (seconds_remaining < 120) + return "Less than two minutes"; + + time_t minutes_remaining = seconds_remaining / 60; + seconds_remaining %= 60; + + if (minutes_remaining < 60) { + if (seconds_remaining < 30) + return String::formatted("About {} minutes", minutes_remaining); + return String::formatted("Over {} minutes", minutes_remaining); + } + + time_t hours_remaining = minutes_remaining / 60; + minutes_remaining %= 60; + + return String::formatted("{} hours and {} minutes", hours_remaining, minutes_remaining); +} + +void FileOperationProgressWidget::did_progress(off_t bytes_done, off_t total_byte_count, size_t files_done, size_t total_file_count, [[maybe_unused]] off_t current_file_done, [[maybe_unused]] off_t current_file_size, const StringView& current_file_name) +{ + auto& files_copied_label = *find_descendant_of_type_named("files_copied_label"); auto& current_file_label = *find_descendant_of_type_named("current_file_label"); - auto& current_file_progressbar = *find_descendant_of_type_named("current_file_progressbar"); - auto& overall_progress_label = *find_descendant_of_type_named("overall_progress_label"); auto& overall_progressbar = *find_descendant_of_type_named("overall_progressbar"); + auto& estimated_time_label = *find_descendant_of_type_named("estimated_time_label"); current_file_label.set_text(current_file_name); - current_file_progressbar.set_max(current_file_size); - current_file_progressbar.set_value(current_file_done); - overall_progress_label.set_text(String::formatted("{} of {}", files_done, total_file_count)); - overall_progressbar.set_max(total_file_count); - overall_progressbar.set_value(files_done); + files_copied_label.set_text(String::formatted("Copying file {} of {}", files_done, total_file_count)); + estimated_time_label.set_text(estimate_time(bytes_done, total_byte_count)); + + if (total_byte_count) { + window()->set_progress(100.0f * bytes_done / total_byte_count); + overall_progressbar.set_max(total_byte_count); + overall_progressbar.set_value(bytes_done); + } } void FileOperationProgressWidget::close_pipe() diff --git a/Userland/Applications/FileManager/FileOperationProgressWidget.h b/Userland/Applications/FileManager/FileOperationProgressWidget.h index 8c47b67bfd..fcebebb02e 100644 --- a/Userland/Applications/FileManager/FileOperationProgressWidget.h +++ b/Userland/Applications/FileManager/FileOperationProgressWidget.h @@ -26,6 +26,7 @@ #pragma once +#include #include namespace FileManager { @@ -45,6 +46,9 @@ private: void close_pipe(); + String estimate_time(off_t bytes_done, off_t total_byte_count); + Core::ElapsedTimer m_elapsed_timer; + RefPtr m_notifier; RefPtr m_helper_pipe; };