diff options
author | Leandro Pereira <leandro@hardinfo.org> | 2021-04-16 18:41:44 -0700 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-04-17 09:41:35 +0200 |
commit | 602f98fe671a56724f2febcceb7b03b0da80a51c (patch) | |
tree | 4bc68e65259da578f92f7082637868bf1da2f84c | |
parent | 8d2529019855f73a4c6cc8c9dafe2c0552089d2a (diff) | |
download | serenity-602f98fe671a56724f2febcceb7b03b0da80a51c.zip |
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.)
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(NonnullRefPtr<Core::Fil parts[7]); } }; + + m_elapsed_timer.start(); } FileOperationProgressWidget::~FileOperationProgressWidget() @@ -107,20 +109,57 @@ void FileOperationProgressWidget::did_error() window()->close(); } -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<GUI::Label>("files_copied_label"); auto& current_file_label = *find_descendant_of_type_named<GUI::Label>("current_file_label"); - auto& current_file_progressbar = *find_descendant_of_type_named<GUI::Progressbar>("current_file_progressbar"); - auto& overall_progress_label = *find_descendant_of_type_named<GUI::Label>("overall_progress_label"); auto& overall_progressbar = *find_descendant_of_type_named<GUI::Progressbar>("overall_progressbar"); + auto& estimated_time_label = *find_descendant_of_type_named<GUI::Label>("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 <LibCore/ElapsedTimer.h> #include <LibGUI/Widget.h> 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<Core::Notifier> m_notifier; RefPtr<Core::File> m_helper_pipe; }; |