Commit | Line | Data |
---|---|---|
1479465f GJ |
1 | /* |
2 | * dselect - Debian package maintenance user interface | |
3 | * pkgtop.cc - handles (re)draw of package list windows colheads, list, thisstate | |
4 | * | |
5 | * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk> | |
6 | * Copyright © 2007-2014 Guillem Jover <guillem@debian.org> | |
7 | * | |
8 | * This is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | * | |
13 | * This is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
20 | */ | |
21 | ||
22 | #include <config.h> | |
23 | #include <compat.h> | |
24 | ||
25 | #include <assert.h> | |
26 | #include <string.h> | |
27 | #include <stdio.h> | |
28 | ||
29 | #include <dpkg/i18n.h> | |
30 | #include <dpkg/c-ctype.h> | |
31 | #include <dpkg/dpkg.h> | |
32 | #include <dpkg/dpkg-db.h> | |
33 | ||
34 | #include "dselect.h" | |
35 | #include "pkglist.h" | |
36 | ||
37 | static const char * | |
38 | pkgprioritystring(const struct pkginfo *pkg) | |
39 | { | |
40 | if (pkg->priority == PKG_PRIO_UNSET) { | |
41 | return nullptr; | |
42 | } else if (pkg->priority == PKG_PRIO_OTHER) { | |
43 | return pkg->otherpriority; | |
44 | } else { | |
45 | assert(pkg->priority <= PKG_PRIO_UNKNOWN); | |
46 | return gettext(prioritystrings[pkg->priority]); | |
47 | } | |
48 | } | |
49 | ||
50 | int packagelist::describemany(char buf[], const char *prioritystring, | |
51 | const char *section, | |
52 | const struct perpackagestate *pps) { | |
53 | const char *ssostring, *ssoabbrev; | |
54 | int statindent; | |
55 | ||
56 | statindent= 0; | |
57 | ssostring = nullptr; | |
58 | ssoabbrev= _("All"); | |
59 | switch (statsortorder) { | |
60 | case sso_avail: | |
61 | if (pps->ssavail == -1) break; | |
62 | ssostring= ssastrings[pps->ssavail]; | |
63 | ssoabbrev= ssaabbrevs[pps->ssavail]; | |
64 | statindent++; | |
65 | break; | |
66 | case sso_state: | |
67 | if (pps->ssstate == -1) break; | |
68 | ssostring= sssstrings[pps->ssstate]; | |
69 | ssoabbrev= sssabbrevs[pps->ssstate]; | |
70 | statindent++; | |
71 | break; | |
72 | case sso_unsorted: | |
73 | break; | |
74 | default: | |
75 | internerr("unknown statsortrder %d", statsortorder); | |
76 | } | |
77 | ||
78 | if (!prioritystring) { | |
79 | if (!section) { | |
80 | strcpy(buf, ssostring ? gettext(ssostring) : _("All packages")); | |
81 | return statindent; | |
82 | } else { | |
83 | if (!*section) { | |
84 | sprintf(buf,_("%s packages without a section"),gettext(ssoabbrev)); | |
85 | } else { | |
86 | sprintf(buf,_("%s packages in section %s"),gettext(ssoabbrev),section); | |
87 | } | |
88 | return statindent+1; | |
89 | } | |
90 | } else { | |
91 | if (!section) { | |
92 | sprintf(buf,_("%s %s packages"),gettext(ssoabbrev),prioritystring); | |
93 | return statindent+1; | |
94 | } else { | |
95 | if (!*section) { | |
96 | sprintf(buf,_("%s %s packages without a section"),gettext(ssoabbrev),prioritystring); | |
97 | } else { | |
98 | sprintf(buf,_("%s %s packages in section %s"),gettext(ssoabbrev),prioritystring,section); | |
99 | } | |
100 | return statindent+2; | |
101 | } | |
102 | } | |
103 | } | |
104 | ||
105 | void packagelist::redrawthisstate() { | |
106 | if (!thisstate_height) return; | |
107 | mywerase(thisstatepad); | |
108 | ||
109 | const char *section= table[cursorline]->pkg->section; | |
110 | const char *priority= pkgprioritystring(table[cursorline]->pkg); | |
111 | char *buf= new char[500+ | |
112 | max((table[cursorline]->pkg->set->name ? | |
113 | strlen(table[cursorline]->pkg->set->name) : 0), | |
114 | (section ? strlen(section) : 0) + | |
115 | (priority ? strlen(priority) : 0))]; | |
116 | ||
117 | if (table[cursorline]->pkg->set->name) { | |
118 | sprintf(buf, | |
119 | _("%-*s %s%s%s; %s (was: %s). %s"), | |
120 | col_package.width, | |
121 | table[cursorline]->pkg->set->name, | |
122 | gettext(statusstrings[table[cursorline]->pkg->status]), | |
123 | ((eflagstrings[table[cursorline]->pkg->eflag][0]==' ') && | |
124 | (eflagstrings[table[cursorline]->pkg->eflag][1]=='\0')) ? "" : " - ", | |
125 | gettext(eflagstrings[table[cursorline]->pkg->eflag]), | |
126 | gettext(wantstrings[table[cursorline]->selected]), | |
127 | gettext(wantstrings[table[cursorline]->original]), | |
128 | priority); | |
129 | } else { | |
130 | describemany(buf,priority,section,table[cursorline]->pkg->clientdata); | |
131 | } | |
132 | mvwaddnstr(thisstatepad,0,0, buf, total_width); | |
133 | pnoutrefresh(thisstatepad, 0,leftofscreen, thisstate_row,0, | |
134 | thisstate_row, min(total_width - 1, xmax - 1)); | |
135 | ||
136 | delete[] buf; | |
137 | } | |
138 | ||
139 | void packagelist::redraw1itemsel(int index, int selected) { | |
140 | int i, indent, j; | |
141 | const char *p; | |
142 | const struct pkginfo *pkg= table[index]->pkg; | |
143 | int screenline = index - topofscreen; | |
144 | ||
145 | wattrset(listpad, part_attr[selected ? listsel : list]); | |
146 | ||
147 | if (pkg->set->name) { | |
148 | if (verbose) { | |
149 | draw_column_item(col_status_hold, screenline, | |
150 | gettext(eflagstrings[pkg->eflag])); | |
151 | ||
152 | draw_column_sep(col_status_status, screenline); | |
153 | draw_column_item(col_status_status, screenline, | |
154 | gettext(statusstrings[pkg->status])); | |
155 | ||
156 | draw_column_sep(col_status_old_want, screenline); | |
157 | draw_column_item(col_status_old_want, screenline, | |
158 | /* FIXME: keep this? */ | |
159 | /*table[index]->original == table[index]->selected ? "(same)" | |
160 | : */gettext(wantstrings[table[index]->original])); | |
161 | ||
162 | draw_column_sep(col_status_new_want, screenline); | |
163 | wattrset(listpad, part_attr[selected ? selstatesel : selstate]); | |
164 | draw_column_item(col_status_new_want, screenline, | |
165 | gettext(wantstrings[table[index]->selected])); | |
166 | ||
167 | wattrset(listpad, part_attr[selected ? listsel : list]); | |
168 | ||
169 | draw_column_sep(col_priority, screenline); | |
170 | draw_column_item(col_priority, screenline, | |
171 | pkg->priority == PKG_PRIO_OTHER ? | |
172 | pkg->otherpriority : | |
173 | gettext(prioritystrings[pkg->priority])); | |
174 | } else { | |
175 | mvwaddch(listpad, screenline, 0, eflagchars[pkg->eflag]); | |
176 | waddch(listpad, statuschars[pkg->status]); | |
177 | waddch(listpad, | |
178 | /* FIXME: keep this feature? */ | |
179 | /*table[index]->original == table[index]->selected ? ' ' | |
180 | : */wantchars[table[index]->original]); | |
181 | ||
182 | wattrset(listpad, part_attr[selected ? selstatesel : selstate]); | |
183 | waddch(listpad, wantchars[table[index]->selected]); | |
184 | wattrset(listpad, part_attr[selected ? listsel : list]); | |
185 | ||
186 | wmove(listpad, screenline, col_priority.x - 1); | |
187 | waddch(listpad, ' '); | |
188 | if (pkg->priority == PKG_PRIO_OTHER) { | |
189 | for (i = col_priority.width, p = pkg->otherpriority; | |
190 | i > 0 && *p; | |
191 | i--, p++) | |
192 | waddch(listpad, c_tolower(*p)); | |
193 | while (i-- > 0) waddch(listpad,' '); | |
194 | } else { | |
195 | wprintw(listpad, "%-*.*s", col_priority.width, col_priority.width, | |
196 | gettext(priorityabbrevs[pkg->priority])); | |
197 | } | |
198 | } | |
199 | ||
200 | draw_column_sep(col_section, screenline); | |
201 | draw_column_item(col_section, screenline, | |
202 | pkg->section ? pkg->section : "?"); | |
203 | ||
204 | draw_column_sep(col_package, screenline); | |
205 | draw_column_item(col_package, screenline, | |
206 | pkg->set->name); | |
207 | ||
208 | waddch(listpad, ' '); | |
209 | ||
210 | if (col_archinstalled.width) { | |
211 | draw_column_sep(col_archinstalled, screenline); | |
212 | draw_column_item(col_archinstalled, screenline, pkg->installed.arch->name); | |
213 | ||
214 | waddch(listpad, ' '); | |
215 | } | |
216 | if (col_archavailable.width) { | |
217 | draw_column_sep(col_archavailable, screenline); | |
218 | draw_column_item(col_archavailable, screenline, pkg->available.arch->name); | |
219 | ||
220 | waddch(listpad, ' '); | |
221 | } | |
222 | ||
223 | if (col_versioninstalled.width) { | |
224 | draw_column_item(col_versioninstalled, screenline, | |
225 | versiondescribe(&pkg->installed.version, vdew_nonambig)); | |
226 | waddch(listpad, ' '); | |
227 | } | |
228 | if (col_versionavailable.width) { | |
229 | if (dpkg_version_is_informative(&pkg->available.version) && | |
230 | dpkg_version_compare(&pkg->available.version, | |
231 | &pkg->installed.version) > 0) | |
232 | wattrset(listpad, part_attr[selected ? selstatesel : selstate]); | |
233 | draw_column_item(col_versionavailable, screenline, | |
234 | versiondescribe(&pkg->available.version, vdew_nonambig)); | |
235 | wattrset(listpad, part_attr[selected ? listsel : list]); | |
236 | waddch(listpad,' '); | |
237 | } | |
238 | ||
239 | i = col_description.width; | |
240 | p = pkg->available.description ? pkg->available.description : | |
241 | pkg->installed.description ? pkg->installed.description : ""; | |
242 | while (i>0 && *p && *p != '\n') { waddnstr(listpad,p,1); i--; p++; } | |
243 | } else { | |
244 | const char *section= pkg->section; | |
245 | const char *priority= pkgprioritystring(pkg); | |
246 | ||
247 | char *buf= new char[500+ | |
248 | (section ? strlen(section) : 0) + | |
249 | (priority ? strlen(priority) : 0)]; | |
250 | ||
251 | indent= describemany(buf,priority,section,pkg->clientdata); | |
252 | ||
253 | mvwaddstr(listpad, screenline, 0, " "); | |
254 | i= total_width-7; | |
255 | j= (indent<<1) + 1; | |
256 | while (j-- >0) { waddch(listpad,ACS_HLINE); i--; } | |
257 | waddch(listpad,' '); | |
258 | ||
259 | wattrset(listpad, part_attr[selected ? selstatesel : selstate]); | |
260 | p= buf; | |
261 | while (i>0 && *p) { waddnstr(listpad, p,1); p++; i--; } | |
262 | wattrset(listpad, part_attr[selected ? listsel : list]); | |
263 | ||
264 | waddch(listpad,' '); | |
265 | j= (indent<<1) + 1; | |
266 | while (j-- >0) { waddch(listpad,ACS_HLINE); i--; } | |
267 | ||
268 | delete[] buf; | |
269 | } | |
270 | ||
271 | while (i>0) { waddch(listpad,' '); i--; } | |
272 | } | |
273 | ||
274 | void packagelist::redrawcolheads() { | |
275 | if (colheads_height) { | |
276 | wattrset(colheadspad, part_attr[colheads]); | |
277 | mywerase(colheadspad); | |
278 | if (verbose) { | |
279 | wmove(colheadspad,0,0); | |
280 | for (int i = 0; i < col_status_old_want.width; i++) | |
281 | waddch(colheadspad, '.'); | |
282 | draw_column_head(col_status_hold); | |
283 | draw_column_head(col_status_status); | |
284 | draw_column_head(col_status_old_want); | |
285 | draw_column_head(col_status_new_want); | |
286 | } else { | |
287 | draw_column_head(col_status); | |
288 | } | |
289 | ||
290 | draw_column_head(col_section); | |
291 | draw_column_head(col_priority); | |
292 | draw_column_head(col_package); | |
293 | ||
294 | if (col_archinstalled.width) | |
295 | draw_column_head(col_archinstalled); | |
296 | if (col_archavailable.width) | |
297 | draw_column_head(col_archavailable); | |
298 | ||
299 | if (col_versioninstalled.width) | |
300 | draw_column_head(col_versioninstalled); | |
301 | if (col_versionavailable.width) | |
302 | draw_column_head(col_versionavailable); | |
303 | ||
304 | draw_column_head(col_description); | |
305 | } | |
306 | refreshcolheads(); | |
307 | } |