feat: add backup progress estimation with time remaining
- Add estimate_backup_size() using du -sb before rsync starts - Parse transfer speed from rsync output (KB/s, MB/s, GB/s) - Calculate remaining time based on speed and remaining bytes - Show estimated time remaining and size progress in UI - Add format_time_remaining() for human-readable time display - New UI elements: backup_time_label_ and backup_size_label_
This commit is contained in:
+42
-2
@@ -46,13 +46,32 @@ MainWindow::MainWindow(Config& config)
|
||||
|
||||
/* Update backup progress window */
|
||||
if (self->backup_win_) {
|
||||
if (p.bytes_total > 0) {
|
||||
double frac = (double)p.bytes_transferred / p.bytes_total;
|
||||
if (p.estimated_total_size > 0) {
|
||||
double frac = (p.estimated_total_size > 0) ? (double)p.bytes_transferred / p.estimated_total_size : 0;
|
||||
if (frac > 1.0) frac = 1.0;
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(self->backup_progress_), frac);
|
||||
char pct[32];
|
||||
snprintf(pct, sizeof(pct), "%.0f%%", frac * 100);
|
||||
gtk_label_set_text(GTK_LABEL(self->backup_status_label_), pct);
|
||||
|
||||
char size_info[128];
|
||||
snprintf(size_info, sizeof(size_info), "%s / %s",
|
||||
format_size(p.bytes_transferred).c_str(),
|
||||
format_size(p.estimated_total_size).c_str());
|
||||
gtk_label_set_text(GTK_LABEL(self->backup_size_label_), size_info);
|
||||
}
|
||||
|
||||
if (p.estimated_remaining > 0 && p.estimated_remaining < 86400 * 365) {
|
||||
std::string time_str = self->rsync_.format_time_remaining(p.estimated_remaining);
|
||||
gtk_label_set_text(GTK_LABEL(self->backup_time_label_), time_str.c_str());
|
||||
} else if (p.elapsed_seconds > 0) {
|
||||
char elapsed_buf[64];
|
||||
int mins = (int)(p.elapsed_seconds / 60);
|
||||
int secs = (int)(p.elapsed_seconds) % 60;
|
||||
snprintf(elapsed_buf, sizeof(elapsed_buf), "Elapsed: %dm %02ds", mins, secs);
|
||||
gtk_label_set_text(GTK_LABEL(self->backup_time_label_), elapsed_buf);
|
||||
}
|
||||
|
||||
if (!p.log_line.empty()) {
|
||||
const char* tag = nullptr;
|
||||
if (p.log_line.find("[error]") != std::string::npos) tag = "error";
|
||||
@@ -65,6 +84,7 @@ MainWindow::MainWindow(Config& config)
|
||||
gtk_label_set_text(GTK_LABEL(self->backup_cmd_label_), cmd_display.c_str());
|
||||
}
|
||||
else if (p.log_line.find("[restore") != std::string::npos) tag = "info";
|
||||
else if (p.log_line.find("[info]") != std::string::npos) tag = "info";
|
||||
self->append_backup_line(p.log_line, tag);
|
||||
}
|
||||
if (p.finished) {
|
||||
@@ -682,6 +702,8 @@ void MainWindow::open_backup_window(const std::string& description) {
|
||||
gtk_text_buffer_set_text(buf, "", -1);
|
||||
gtk_label_set_text(GTK_LABEL(backup_cmd_label_), "");
|
||||
gtk_label_set_text(GTK_LABEL(backup_status_label_), "Running...");
|
||||
gtk_label_set_text(GTK_LABEL(backup_time_label_), "");
|
||||
gtk_label_set_text(GTK_LABEL(backup_size_label_), "");
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(backup_progress_), 0.0);
|
||||
gtk_button_set_label(GTK_BUTTON(backup_cancel_btn_), "Cancel");
|
||||
gtk_widget_show_all(backup_win_);
|
||||
@@ -768,6 +790,22 @@ void MainWindow::open_backup_window(const std::string& description) {
|
||||
gtk_box_pack_start(GTK_BOX(prog_box), backup_status_label_, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), prog_box, FALSE, FALSE, 0);
|
||||
|
||||
/* Time and size info */
|
||||
GtkWidget* info_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 16);
|
||||
backup_time_label_ = gtk_label_new("");
|
||||
gtk_widget_set_halign(backup_time_label_, GTK_ALIGN_START);
|
||||
PangoAttrList* info_attrs = pango_attr_list_new();
|
||||
pango_attr_list_insert(info_attrs, pango_attr_family_new("monospace"));
|
||||
gtk_label_set_attributes(GTK_LABEL(backup_time_label_), info_attrs);
|
||||
gtk_box_pack_start(GTK_BOX(info_box), backup_time_label_, TRUE, TRUE, 0);
|
||||
|
||||
backup_size_label_ = gtk_label_new("");
|
||||
gtk_widget_set_halign(backup_size_label_, GTK_ALIGN_END);
|
||||
gtk_label_set_attributes(GTK_LABEL(backup_size_label_), info_attrs);
|
||||
pango_attr_list_unref(info_attrs);
|
||||
gtk_box_pack_start(GTK_BOX(info_box), backup_size_label_, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), info_box, FALSE, FALSE, 0);
|
||||
|
||||
/* Buttons */
|
||||
GtkWidget* btn_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_widget_set_halign(btn_box, GTK_ALIGN_END);
|
||||
@@ -809,6 +847,8 @@ void MainWindow::close_backup_window() {
|
||||
backup_cmd_label_ = nullptr;
|
||||
backup_progress_ = nullptr;
|
||||
backup_status_label_ = nullptr;
|
||||
backup_time_label_ = nullptr;
|
||||
backup_size_label_ = nullptr;
|
||||
backup_cancel_btn_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user