summaryrefslogtreecommitdiff
path: root/apt-pkg/iprogress.cc
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2013-10-11 19:27:23 +0200
committerMichael Vogt <mvo@debian.org>2013-10-11 19:27:23 +0200
commit31f97d7b862ccf3de93b30a15f24d76e806031a3 (patch)
treebe7d38556a459169f083becb8ade1627520a5c5b /apt-pkg/iprogress.cc
parent3921580c0b7ab67abb6eb5374af94d8951c525fe (diff)
first iteration of install progress refactor
Diffstat (limited to 'apt-pkg/iprogress.cc')
-rw-r--r--apt-pkg/iprogress.cc111
1 files changed, 111 insertions, 0 deletions
diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc
new file mode 100644
index 000000000..4de8c0492
--- /dev/null
+++ b/apt-pkg/iprogress.cc
@@ -0,0 +1,111 @@
+#include <apt-pkg/iprogress.h>
+#include <apt-pkg/strutl.h>
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+namespace APT {
+namespace Progress {
+
+static void SetupTerminalScrollArea(int nr_rows)
+{
+ // scroll down a bit to avoid visual glitch when the screen
+ // area shrinks by one row
+ std::cout << "\n";
+
+ // save cursor
+ std::cout << "\033[s";
+
+ // set scroll region (this will place the cursor in the top left)
+ std::cout << "\033[1;" << nr_rows - 1 << "r";
+
+ // restore cursor but ensure its inside the scrolling area
+ std::cout << "\033[u";
+ static const char *move_cursor_up = "\033[1A";
+ std::cout << move_cursor_up;
+ std::flush(std::cout);
+}
+
+PackageManagerFancy::PackageManagerFancy()
+ : nr_terminal_rows(-1)
+{
+ struct winsize win;
+ if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0)
+ {
+ nr_terminal_rows = win.ws_row;
+ }
+}
+
+void PackageManagerFancy::Started()
+{
+ SetupTerminalScrollArea(nr_terminal_rows);
+}
+
+void PackageManagerFancy::Finished()
+{
+ SetupTerminalScrollArea(nr_terminal_rows + 1);
+
+ // override the progress line (sledgehammer)
+ static const char* clear_screen_below_cursor = "\033[J";
+ std::cout << clear_screen_below_cursor;
+}
+
+void PackageManagerFancy::StatusChanged(std::string PackageName,
+ unsigned int StepsDone,
+ unsigned int TotalSteps)
+{
+ int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1);
+ float percentage = StepsDone/(float)TotalSteps * 100.0;
+
+ if(percentage < (last_reported_progress + reporting_steps))
+ return;
+
+ std::string progress_str;
+ strprintf(progress_str, "Progress: [%3i%%]", (int)percentage);
+
+ int row = nr_terminal_rows;
+
+ static string save_cursor = "\033[s";
+ static string restore_cursor = "\033[u";
+
+ static string set_bg_color = "\033[42m"; // green
+ static string set_fg_color = "\033[30m"; // black
+
+ static string restore_bg = "\033[49m";
+ static string restore_fg = "\033[39m";
+
+ std::cout << save_cursor
+ // move cursor position to last row
+ << "\033[" << row << ";0f"
+ << set_bg_color
+ << set_fg_color
+ << progress_str
+ << restore_cursor
+ << restore_bg
+ << restore_fg;
+ std::flush(std::cout);
+ last_reported_progress = percentage;
+}
+
+void PackageManagerText::StatusChanged(std::string PackageName,
+ unsigned int StepsDone,
+ unsigned int TotalSteps)
+{
+ int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1);
+ float percentage = StepsDone/(float)TotalSteps * 100.0;
+
+ if(percentage < (last_reported_progress + reporting_steps))
+ return;
+
+ std::string progress_str;
+ strprintf(progress_str, "Progress: [%3i%%]", (int)percentage);
+
+ std::cout << progress_str << "\r\n";
+ std::flush(std::cout);
+
+ last_reported_progress = percentage;
+}
+
+
+}; // namespace progress
+}; // namespace apt