]> git.saurik.com Git - apt.git/blob - apt-pkg/iprogress.cc
4de8c0492f6a580185c6f4187c153248912ea4b0
[apt.git] / apt-pkg / iprogress.cc
1 #include <apt-pkg/iprogress.h>
2 #include <apt-pkg/strutl.h>
3
4 #include <termios.h>
5 #include <sys/ioctl.h>
6
7 namespace APT {
8 namespace Progress {
9
10 static void SetupTerminalScrollArea(int nr_rows)
11 {
12 // scroll down a bit to avoid visual glitch when the screen
13 // area shrinks by one row
14 std::cout << "\n";
15
16 // save cursor
17 std::cout << "\033[s";
18
19 // set scroll region (this will place the cursor in the top left)
20 std::cout << "\033[1;" << nr_rows - 1 << "r";
21
22 // restore cursor but ensure its inside the scrolling area
23 std::cout << "\033[u";
24 static const char *move_cursor_up = "\033[1A";
25 std::cout << move_cursor_up;
26 std::flush(std::cout);
27 }
28
29 PackageManagerFancy::PackageManagerFancy()
30 : nr_terminal_rows(-1)
31 {
32 struct winsize win;
33 if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0)
34 {
35 nr_terminal_rows = win.ws_row;
36 }
37 }
38
39 void PackageManagerFancy::Started()
40 {
41 SetupTerminalScrollArea(nr_terminal_rows);
42 }
43
44 void PackageManagerFancy::Finished()
45 {
46 SetupTerminalScrollArea(nr_terminal_rows + 1);
47
48 // override the progress line (sledgehammer)
49 static const char* clear_screen_below_cursor = "\033[J";
50 std::cout << clear_screen_below_cursor;
51 }
52
53 void PackageManagerFancy::StatusChanged(std::string PackageName,
54 unsigned int StepsDone,
55 unsigned int TotalSteps)
56 {
57 int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1);
58 float percentage = StepsDone/(float)TotalSteps * 100.0;
59
60 if(percentage < (last_reported_progress + reporting_steps))
61 return;
62
63 std::string progress_str;
64 strprintf(progress_str, "Progress: [%3i%%]", (int)percentage);
65
66 int row = nr_terminal_rows;
67
68 static string save_cursor = "\033[s";
69 static string restore_cursor = "\033[u";
70
71 static string set_bg_color = "\033[42m"; // green
72 static string set_fg_color = "\033[30m"; // black
73
74 static string restore_bg = "\033[49m";
75 static string restore_fg = "\033[39m";
76
77 std::cout << save_cursor
78 // move cursor position to last row
79 << "\033[" << row << ";0f"
80 << set_bg_color
81 << set_fg_color
82 << progress_str
83 << restore_cursor
84 << restore_bg
85 << restore_fg;
86 std::flush(std::cout);
87 last_reported_progress = percentage;
88 }
89
90 void PackageManagerText::StatusChanged(std::string PackageName,
91 unsigned int StepsDone,
92 unsigned int TotalSteps)
93 {
94 int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1);
95 float percentage = StepsDone/(float)TotalSteps * 100.0;
96
97 if(percentage < (last_reported_progress + reporting_steps))
98 return;
99
100 std::string progress_str;
101 strprintf(progress_str, "Progress: [%3i%%]", (int)percentage);
102
103 std::cout << progress_str << "\r\n";
104 std::flush(std::cout);
105
106 last_reported_progress = percentage;
107 }
108
109
110 }; // namespace progress
111 }; // namespace apt