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.)
This commit is contained in:
Leandro Pereira 2021-04-16 18:41:44 -07:00 committed by Linus Groh
parent 8d25290198
commit 602f98fe67
Notes: sideshowbarker 2024-07-18 19:32:04 +09:00
3 changed files with 58 additions and 20 deletions

View file

@ -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"
}
}

View file

@ -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()

View file

@ -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;
};