dpkg (1.18.25) stretch; urgency=medium
[dpkg] / dselect / basecmds.cc
CommitLineData
1479465f
GJ
1/*
2 * dselect - Debian package maintenance user interface
3 * basecmds.cc - base list keyboard commands display
4 *
5 * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2000,2001 Wichert Akkerman <wakkerma@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 <string.h>
26#include <stdio.h>
27
28#include <dpkg/i18n.h>
29#include <dpkg/dpkg.h>
30#include <dpkg/dpkg-db.h>
31
32#include "dselect.h"
33#include "helpmsgs.h"
34
35void baselist::kd_scrollon() {
36 topofscreen += list_height;
37 if (topofscreen > nitems - list_height) topofscreen= nitems - list_height;
38 if (topofscreen < 0) topofscreen= 0;
39 if (cursorline < topofscreen)
40 setcursor(topofscreen);
41 refreshlist();
42}
43
44void baselist::kd_scrollon1() {
45 if (topofscreen >= nitems - list_height) return;
46 topofscreen++;
47 if (cursorline < topofscreen)
48 setcursor(topofscreen);
49 refreshlist();
50}
51
52void baselist::kd_scrollback() {
53 topofscreen -= list_height;
54 if (topofscreen < 0) topofscreen= 0;
55 if (cursorline >= topofscreen + list_height)
56 setcursor(topofscreen + list_height - 1);
57 refreshlist();
58}
59
60void baselist::kd_scrollback1() {
61 if (topofscreen <= 0) return;
62 topofscreen--;
63 if (cursorline >= topofscreen + list_height)
64 setcursor(topofscreen + list_height - 1);
65 refreshlist();
66}
67
68void baselist::kd_top() {
69 topofscreen= 0; setcursor(0);
70}
71
72void baselist::kd_bottom() {
73 topofscreen= nitems - list_height;
74 if (topofscreen < 0) topofscreen= 0;
75 setcursor(min(topofscreen + list_height - 1, nitems - 1));
76}
77
78void baselist::kd_redraw() {
79//#define RFSH(x) werase(x); redrawwin(x)
80// RFSH(listpad);
81// RFSH(infopad);
82// RFSH(colheadspad);
83// RFSH(thisstatepad);
84// RFSH(titlewin);
85// RFSH(whatinfowin); /* FIXME: why does ncurses need this? */
86 clearok(curscr,TRUE);
87 redrawall();
88 debug(dbg_general, "baselist[%p]::kd_redraw() done", this);
89}
90
91void baselist::kd_searchagain() {
92 if (!searchstring[0]) { beep(); return; }
93 dosearch();
94}
95
96bool
97baselist::checksearch(char *str)
98{
99 return true;
100}
101
102bool
103baselist::matchsearch(int index)
104{
105 int lendiff, searchlen, i;
106 const char *name;
107
108 name = itemname(index);
109 if (!name)
110 return false; /* Skip things without a name (separators). */
111
112 searchlen=strlen(searchstring);
113 lendiff = strlen(name) - searchlen;
114 for (i=0; i<=lendiff; i++)
115 if (strncasecmp(name + i, searchstring, searchlen) == 0)
116 return true;
117
118 return false;
119}
120
121void baselist::kd_search() {
122 char newsearchstring[128];
123 strcpy(newsearchstring,searchstring);
124 werase(querywin);
125 mvwaddstr(querywin,0,0, _("Search for ? "));
126 echo(); /* FIXME: ncurses documentation or implementation. */
127 if (wgetnstr(querywin,newsearchstring,sizeof(newsearchstring)-1) == ERR)
128 searchstring[0]= 0;
129 raise(SIGWINCH); /* FIXME: ncurses and xterm arrow keys. */
130 noecho(); /* FIXME: ncurses. */
131 if (whatinfo_height) { touchwin(whatinfowin); refreshinfo(); }
132 else if (info_height) { touchwin(infopad); refreshinfo(); }
133 else if (thisstate_height) redrawthisstate();
134 else { touchwin(listpad); refreshlist(); }
135 if (newsearchstring[0]) {
136 if (!checksearch(newsearchstring)) {
137 beep();
138 return;
139 }
140 strcpy(searchstring,newsearchstring);
141 dosearch();
142 } else
143 kd_searchagain();
144}
145
146void
147baselist::displayerror(const char *str)
148{
149 const char *pr = _("Error: ");
150 int prlen=strlen(pr);
151
152 beep();
153 werase(querywin);
154 mvwaddstr(querywin,0,0,pr);
155 mvwaddstr(querywin,0,prlen,str);
156 wgetch(querywin);
157 if (whatinfo_height) { touchwin(whatinfowin); refreshinfo(); }
158 else if (info_height) { touchwin(infopad); refreshinfo(); }
159 else if (thisstate_height) redrawthisstate();
160}
161
162
163void baselist::displayhelp(const struct helpmenuentry *helpmenu, int key) {
164 int maxx, maxy, i, nextkey;
165
166 getmaxyx(stdscr,maxy,maxx);
167 wbkgdset(stdscr, ' ' | part_attr[helpscreen]);
168 clearok(stdscr,TRUE);
169 for (;;) {
170 werase(stdscr);
171 const struct helpmenuentry *hme = helpmenu;
172 while (hme->key && hme->key != key)
173 hme++;
174 if (hme->key) {
175 int x, y DPKG_ATTR_UNUSED;
176
177 attrset(part_attr[helpscreen]);
178 mvaddstr(1,0, gettext(hme->msg->text));
179 attrset(part_attr[title]);
180 mvaddstr(0,0, _("Help: "));
181 addstr(gettext(hme->msg->title));
182 getyx(stdscr,y,x);
183 while (++x<maxx) addch(' ');
184 attrset(part_attr[thisstate]);
185 mvaddstr(maxy-1,0,
186_("Press ? for help menu, . for next topic, <space> to exit help."));
187 getyx(stdscr,y,x);
188 while (++x<maxx) addch(' ');
189 move(maxy,maxx);
190 attrset(A_NORMAL);
191 nextkey= hme[1].key;
192 } else {
193 mvaddstr(1,1, _("Help information is available under the following topics:"));
194 for (i=0, hme=helpmenu; hme->key; hme++,i++) {
195 attrset(A_BOLD);
196 mvaddch(i+3,3, hme->key);
197 attrset(A_NORMAL);
198 mvaddstr(i+3,6, gettext(hme->msg->title));
199 }
200 mvaddstr(i+4,1,
201 _("Press a key from the list above, <space> or 'q' to exit help,\n"
202 " or '.' (full stop) to read each help page in turn. "));
203 nextkey= helpmenu[0].key;
204 }
205 refresh();
206 key= getch();
207 if (key == EOF) ohshite(_("error reading keyboard in help"));
208 if (key == ' ' || key == 'q') {
209 break;
210 } else if (key == '?' || key == 'h') {
211 key= 0;
212 } else if (key == '.') {
213 key= nextkey;
214 }
215 }
216 werase(stdscr);
217 clearok(stdscr,TRUE);
218 wnoutrefresh(stdscr);
219
220 redrawtitle();
221 refreshcolheads();
222 refreshlist();
223 redrawthisstate();
224 refreshinfo();
225 wnoutrefresh(whatinfowin);
226}
227
228void baselist::kd_help() {
229 displayhelp(helpmenulist(),0);
230}
231
232void baselist::setcursor(int index) {
233 if (listpad && cursorline != -1) {
234 redrawitemsrange(cursorline,cursorline+1);
235 redraw1itemsel(cursorline,0);
236 }
237 if (cursorline != index) infotopofscreen= 0;
238 cursorline= index;
239 if (listpad) {
240 redrawitemsrange(cursorline,cursorline+1);
241 redraw1itemsel(cursorline,1);
242 refreshlist();
243 redrawthisstate();
244 }
245 redrawinfo();
246}
247
248void baselist::kd_down() {
249 int ncursor= cursorline;
250 // scroll by one line unless the bottom is already visible
251 // or we're in the top half of the screen ...
252 if (topofscreen < nitems - list_height &&
253 ncursor >= topofscreen + list_height - 3) topofscreen++;
254 // move cursor if there are any more ...
255 if (cursorline+1 < nitems) ncursor++;
256 setcursor(ncursor);
257}
258
259void baselist::kd_up() {
260 int ncursor= cursorline;
261 // scroll by one line if there are any lines not shown yet
262 // and we're not in the bottom half the screen ...
263 if (topofscreen > 0 &&
264 ncursor <= topofscreen + 2) topofscreen--;
265 // move cursor if there are any to move it to ...
266 if (cursorline > 0) ncursor--;
267 setcursor(ncursor);
268}
269
270void baselist::kd_iscrollon() {
271 infotopofscreen += info_height;
272 if (infotopofscreen > infolines - info_height)
273 infotopofscreen= infolines - info_height;
274 if (infotopofscreen < 0) infotopofscreen= 0;
275 refreshinfo();
276}
277
278void baselist::kd_iscrollback() {
279 infotopofscreen -= info_height;
280 if (infotopofscreen < 0) infotopofscreen= 0;
281 refreshinfo();
282}
283
284void baselist::kd_iscrollon1() {
285 if (infotopofscreen >= infolines - info_height) return;
286 infotopofscreen++; refreshinfo();
287}
288
289void baselist::kd_iscrollback1() {
290 if (infotopofscreen <= 0) return;
291 infotopofscreen--; refreshinfo();
292}
293
294void baselist::kd_panon() {
295 leftofscreen += xmax/3;
296 if (leftofscreen > total_width - xmax) leftofscreen= total_width - xmax;
297 if (leftofscreen < 0) leftofscreen= 0;
298 refreshcolheads(); refreshlist(); redrawthisstate(); refreshinfo();
299}
300
301void baselist::kd_panback() {
302 leftofscreen -= xmax/3;
303 if (leftofscreen < 0) leftofscreen= 0;
304 refreshcolheads(); refreshlist(); redrawthisstate(); refreshinfo();
305}
306
307void baselist::kd_panon1() {
308 leftofscreen++;
309 if (leftofscreen > total_width - xmax) leftofscreen= total_width - xmax;
310 if (leftofscreen < 0) leftofscreen= 0;
311 refreshcolheads(); refreshlist(); redrawthisstate(); refreshinfo();
312}
313
314void baselist::kd_panback1() {
315 leftofscreen--;
316 if (leftofscreen < 0) leftofscreen= 0;
317 refreshcolheads(); refreshlist(); redrawthisstate(); refreshinfo();
318}