dpkg (1.2.12); priority=LOW
[dpkg.git] / dselect / pkgcmds.cc
blob26a32566e9e17f8e46e46ddcc40ab9007ba2b09f
1 /*
2 * dselect - Debian GNU/Linux package maintenance user interface
3 * pkgcmds.cc - package list keyboard commands
5 * Copyright (C) 1994,1995 Ian Jackson <iwj10@cus.cam.ac.uk>
7 * This is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public
18 * License along with this; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <stdio.h>
23 #include <string.h>
24 #include <ncurses.h>
25 #include <assert.h>
26 #include <signal.h>
28 extern "C" {
29 #include "config.h"
30 #include "dpkg.h"
31 #include "dpkg-db.h"
33 #include "dselect.h"
34 #include "pkglist.h"
36 static int matches(struct pkginfo *pkg, struct pkginfo *comparewith) {
37 if (comparewith->priority != pkginfo::pri_unset &&
38 (comparewith->priority != pkg->priority ||
39 comparewith->priority == pkginfo::pri_other &&
40 strcasecmp(comparewith->otherpriority,pkg->otherpriority)))
41 return 0;
42 if (comparewith->section &&
43 strcasecmp(comparewith->section,
44 pkg->section ?
45 pkg->section : ""))
46 return 0;
47 return 1;
50 void packagelist::affectedrange(int *startp, int *endp) {
51 if (table[cursorline]->pkg->name) {
52 *startp= cursorline;
53 *endp= cursorline+1;
54 return;
56 int index;
57 for (index= cursorline; index < nitems && !table[index]->pkg->name; index++);
58 if (index >= nitems) {
59 *startp= *endp= cursorline;
60 return;
62 *startp= index;
63 while (index < nitems && matches(table[index]->pkg,table[cursorline]->pkg)) index++;
64 *endp= index;
67 void packagelist::movecursorafter(int ncursor) {
68 if (ncursor >= nitems) ncursor= nitems-1;
69 topofscreen += ncursor-cursorline;
70 if (topofscreen > nitems - list_height) topofscreen= nitems - list_height;
71 if (topofscreen < 0) topofscreen= 0;
72 setcursor(ncursor);
73 refreshlist(); redrawthisstate();
76 pkginfo::pkgwant packagelist::reallywant(pkginfo::pkgwant nwarg,
77 struct perpackagestate *pkgstate) {
78 if (nwarg != pkginfo::want_sentinel) return nwarg;
79 pkginfo::pkgstatus status= pkgstate->pkg->status;
80 if (status == pkginfo::stat_notinstalled) return pkginfo::want_purge;
81 if (status == pkginfo::stat_configfiles) return pkginfo::want_deinstall;
82 return pkginfo::want_install;
85 void packagelist::setwant(pkginfo::pkgwant nwarg) {
86 int index, top, bot;
87 pkginfo::pkgwant nw;
89 if (!readwrite) { beep(); return; }
91 if (recursive) {
92 redrawitemsrange(cursorline,cursorline+1);
93 table[cursorline]->selected= reallywant(nwarg,table[cursorline]);
94 redraw1item(cursorline);
95 top= cursorline;
96 bot= cursorline+1;
97 } else {
98 packagelist *sub= new packagelist(bindings,0);
100 affectedrange(&top,&bot);
101 for (index= top; index < bot; index++) {
102 if (!table[index]->pkg->name) continue;
103 nw= reallywant(nwarg,table[index]);
104 if (table[index]->selected == nw ||
105 (table[index]->selected == pkginfo::want_purge &&
106 nw == pkginfo::want_deinstall))
107 continue;
108 sub->add(table[index]->pkg,nw);
111 repeatedlydisplay(sub,dp_may,this);
112 for (index=top; index < bot; index++)
113 redraw1item(index);
115 movecursorafter(bot);
118 void packagelist::kd_select() { setwant(pkginfo::want_install); }
119 void packagelist::kd_hold() { setwant(pkginfo::want_hold); }
120 void packagelist::kd_deselect() { setwant(pkginfo::want_deinstall); }
121 void packagelist::kd_unhold() { setwant(pkginfo::want_sentinel); }
122 void packagelist::kd_purge() { setwant(pkginfo::want_purge); }
124 int would_like_to_install(pkginfo::pkgwant wantvalue, pkginfo *pkg) {
125 /* Returns: 1 for yes, 0 for no, -1 for if they want to preserve an error condition. */
126 if (debug) fprintf(debug,"would_like_to_install(%d, %s) status %d\n",
127 wantvalue,pkg->name,pkg->status);
129 if (wantvalue == pkginfo::want_install) return 1;
130 if (wantvalue != pkginfo::want_hold) return 0;
131 if (pkg->status == pkginfo::stat_installed) return 1;
132 if (pkg->status == pkginfo::stat_notinstalled ||
133 pkg->status == pkginfo::stat_configfiles) return 0;
134 return -1;
137 const char *packagelist::itemname(int index) {
138 return table[index]->pkg->name;
141 void packagelist::kd_swapstatorder() {
142 if (sortorder == so_unsorted) return;
143 switch (statsortorder) {
144 case sso_avail: statsortorder= sso_state; break;
145 case sso_state: statsortorder= sso_unsorted; break;
146 case sso_unsorted: statsortorder= sso_avail; break;
147 default: internerr("unknown statsort in kd_swapstatorder");
149 resortredisplay();
152 void packagelist::kd_swaporder() {
153 switch (sortorder) {
154 case so_priority: sortorder= so_section; break;
155 case so_section: sortorder= so_alpha; break;
156 case so_alpha: sortorder= so_priority; break;
157 case so_unsorted: return;
158 default: internerr("unknown sort in kd_swaporder");
160 resortredisplay();
163 void packagelist::resortredisplay() {
164 const char *oldname= table[cursorline]->pkg->name;
165 sortmakeheads();
166 int newcursor;
167 newcursor= 0;
168 if (oldname) {
169 int index;
170 for (index=0; index<nitems; index++) {
171 if (table[index]->pkg->name && !strcasecmp(oldname,table[index]->pkg->name)) {
172 newcursor= index;
173 break;
177 topofscreen= newcursor-1;
178 if (topofscreen > nitems - list_height) topofscreen= nitems-list_height;
179 if (topofscreen < 0) topofscreen= 0;
180 setwidths();
181 redrawtitle();
182 redrawcolheads();
183 ldrawnstart= ldrawnend= -1;
184 cursorline= -1;
185 setcursor(newcursor);
186 refreshlist();
189 void packagelist::kd_versiondisplay() {
190 switch (versiondisplayopt) {
191 case vdo_both: versiondisplayopt= vdo_none; break;
192 case vdo_none: versiondisplayopt= vdo_available; break;
193 case vdo_available: versiondisplayopt= vdo_both; break;
194 default: internerr("unknown versiondisplayopt in kd_versiondisplay");
196 setwidths();
197 leftofscreen= 0;
198 ldrawnstart= ldrawnend= -1;
199 redrawtitle();
200 redrawcolheads();
201 redrawitemsrange(topofscreen,lesserint(topofscreen+list_height,nitems));
202 refreshlist();
205 void packagelist::kd_verbose() {
206 verbose= !verbose;
207 setwidths();
208 leftofscreen= 0;
209 ldrawnstart= ldrawnend= -1;
210 redrawtitle();
211 redrawcolheads();
212 redrawitemsrange(topofscreen,lesserint(topofscreen+list_height,nitems));
213 refreshlist();
216 void packagelist::kd_quit_noop() { }
218 void packagelist::kd_revert_abort() {
219 int index;
220 for (index=0; index<nitems; index++) {
221 if (table[index]->pkg->name)
222 table[index]->selected= table[index]->original;
223 ldrawnstart= ldrawnend= -1;
225 refreshlist(); redrawthisstate();
228 void packagelist::kd_revertdirect() {
229 int index;
230 for (index=0; index<nitems; index++) {
231 if (table[index]->pkg->name)
232 table[index]->selected= table[index]->direct;
233 ldrawnstart= ldrawnend= -1;
235 refreshlist(); redrawthisstate();
238 void packagelist::kd_revertsuggest() {
239 int index;
240 for (index=0; index<nitems; index++) {
241 if (table[index]->pkg->name)
242 table[index]->selected= table[index]->suggested;
243 ldrawnstart= ldrawnend= -1;
245 refreshlist(); redrawthisstate();
248 /* fixme: configurable purge/deselect */
250 void packagelist::kd_toggleinfo() {
251 showinfo= (showinfo+2) % 3;
252 setheights();
253 if (cursorline >= topofscreen+list_height) topofscreen += list_height;
254 if (topofscreen > nitems - list_height) topofscreen= nitems-list_height;
255 if (topofscreen < 0) topofscreen= 0;
256 infotopofscreen= 0;
257 redraw1item(cursorline);
258 refreshlist();
259 redrawthisstate();
260 redrawinfo();
263 void packagelist::kd_info() {
264 if (!showinfo) {
265 showinfo= 2; kd_toggleinfo();
266 } else {
267 currentinfo++;
268 infotopofscreen=0;
269 redrawinfo();