2 * dselect - Debian package maintenance user interface
3 * pkgcmds.cc - package list keyboard commands
5 * Copyright © 1994,1995 Ian Jackson <ian@chiark.greenend.org.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 published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This is distributed in the hope that it will be useful,
13 * but 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 License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <dpkg/dpkg.h>
28 #include <dpkg/dpkg-db.h>
34 packagelist::affectedmatches(struct pkginfo
*pkg
, struct pkginfo
*comparewith
) {
35 switch (statsortorder
) {
37 if (comparewith
->clientdata
->ssavail
!= pkg
->clientdata
->ssavail
)
41 if (comparewith
->clientdata
->ssstate
!= pkg
->clientdata
->ssstate
)
47 internerr("unknown statsortorder in affectedmatches");
49 if (comparewith
->priority
!= pkginfo::pri_unset
&&
50 (comparewith
->priority
!= pkg
->priority
||
51 (comparewith
->priority
== pkginfo::pri_other
&&
52 strcasecmp(comparewith
->otherpriority
, pkg
->otherpriority
))))
54 if (comparewith
->section
&&
55 strcasecmp(comparewith
->section
,
62 void packagelist::affectedrange(int *startp
, int *endp
) {
63 if (table
[cursorline
]->pkg
->name
) {
68 int index
= cursorline
;
69 while (index
< nitems
&& !table
[index
]->pkg
->name
)
71 if (index
>= nitems
) {
72 *startp
= *endp
= cursorline
;
76 while (index
< nitems
&& affectedmatches(table
[index
]->pkg
,table
[cursorline
]->pkg
))
81 void packagelist::movecursorafter(int ncursor
) {
82 if (ncursor
>= nitems
) ncursor
= nitems
-1;
83 topofscreen
+= ncursor
-cursorline
;
84 if (topofscreen
> nitems
- list_height
) topofscreen
= nitems
- list_height
;
85 if (topofscreen
< 0) topofscreen
= 0;
87 refreshlist(); redrawthisstate();
90 pkginfo::pkgwant
packagelist::reallywant(pkginfo::pkgwant nwarg
,
91 struct perpackagestate
*pkgstate
) {
92 if (nwarg
!= pkginfo::want_sentinel
) return nwarg
;
93 pkginfo::pkgstatus status
= pkgstate
->pkg
->status
;
94 if (status
== pkginfo::stat_notinstalled
) return pkginfo::want_purge
;
95 if (status
== pkginfo::stat_configfiles
) return pkginfo::want_deinstall
;
96 return pkginfo::want_install
;
99 void packagelist::setwant(pkginfo::pkgwant nwarg
) {
103 if (!readwrite
) { beep(); return; }
106 redrawitemsrange(cursorline
,cursorline
+1);
107 table
[cursorline
]->selected
= reallywant(nwarg
,table
[cursorline
]);
108 redraw1item(cursorline
);
112 packagelist
*sub
= new packagelist(bindings
,0);
114 affectedrange(&top
,&bot
);
115 for (index
= top
; index
< bot
; index
++) {
116 if (!table
[index
]->pkg
->name
) continue;
117 nw
= reallywant(nwarg
,table
[index
]);
118 if (table
[index
]->selected
== nw
||
119 (table
[index
]->selected
== pkginfo::want_purge
&&
120 nw
== pkginfo::want_deinstall
))
122 sub
->add(table
[index
]->pkg
,nw
);
125 repeatedlydisplay(sub
,dp_may
,this);
126 for (index
=top
; index
< bot
; index
++)
129 movecursorafter(bot
);
132 int manual_install
= 0;
134 void packagelist::kd_select() {
136 setwant(pkginfo::want_install
);
139 void packagelist::kd_hold() { setwant(pkginfo::want_hold
); }
140 void packagelist::kd_deselect() { setwant(pkginfo::want_deinstall
); }
141 void packagelist::kd_unhold() { setwant(pkginfo::want_sentinel
); }
142 void packagelist::kd_purge() { setwant(pkginfo::want_purge
); }
144 int would_like_to_install(pkginfo::pkgwant wantvalue
, pkginfo
*pkg
) {
145 /* Returns: 1 for yes, 0 for no, -1 for if they want to preserve an error condition. */
146 if (debug
) fprintf(debug
,"would_like_to_install(%d, %s) status %d\n",
147 wantvalue
,pkg
->name
,pkg
->status
);
149 if (wantvalue
== pkginfo::want_install
) return 1;
150 if (wantvalue
!= pkginfo::want_hold
) return 0;
151 if (pkg
->status
== pkginfo::stat_installed
) return 1;
152 if (pkg
->status
== pkginfo::stat_notinstalled
||
153 pkg
->status
== pkginfo::stat_configfiles
) return 0;
157 const char *packagelist::itemname(int index
) {
158 return table
[index
]->pkg
->name
;
161 void packagelist::kd_swapstatorder() {
162 if (sortorder
== so_unsorted
) return;
163 switch (statsortorder
) {
164 case sso_avail
: statsortorder
= sso_state
; break;
165 case sso_state
: statsortorder
= sso_unsorted
; break;
166 case sso_unsorted
: statsortorder
= sso_avail
; break;
167 default: internerr("unknown statsort in kd_swapstatorder");
172 void packagelist::kd_swaporder() {
174 case so_priority
: sortorder
= so_section
; break;
175 case so_section
: sortorder
= so_alpha
; break;
176 case so_alpha
: sortorder
= so_priority
; break;
177 case so_unsorted
: return;
178 default: internerr("unknown sort in kd_swaporder");
183 void packagelist::resortredisplay() {
184 const char *oldname
= table
[cursorline
]->pkg
->name
;
190 for (index
=0; index
<nitems
; index
++) {
191 if (table
[index
]->pkg
->name
&& !strcasecmp(oldname
,table
[index
]->pkg
->name
)) {
197 topofscreen
= newcursor
-1;
198 if (topofscreen
> nitems
- list_height
) topofscreen
= nitems
-list_height
;
199 if (topofscreen
< 0) topofscreen
= 0;
203 ldrawnstart
= ldrawnend
= -1;
205 setcursor(newcursor
);
209 void packagelist::kd_versiondisplay() {
210 switch (versiondisplayopt
) {
211 case vdo_both
: versiondisplayopt
= vdo_none
; break;
212 case vdo_none
: versiondisplayopt
= vdo_available
; break;
213 case vdo_available
: versiondisplayopt
= vdo_both
; break;
214 default: internerr("unknown versiondisplayopt in kd_versiondisplay");
218 ldrawnstart
= ldrawnend
= -1;
221 redrawitemsrange(topofscreen
, min(topofscreen
+ list_height
, nitems
));
225 void packagelist::kd_verbose() {
229 ldrawnstart
= ldrawnend
= -1;
232 redrawitemsrange(topofscreen
, min(topofscreen
+ list_height
, nitems
));
236 void packagelist::kd_quit_noop() { }
238 void packagelist::kd_revert_abort() {
240 for (index
=0; index
<nitems
; index
++) {
241 if (table
[index
]->pkg
->name
)
242 table
[index
]->selected
= table
[index
]->original
;
243 ldrawnstart
= ldrawnend
= -1;
245 refreshlist(); redrawthisstate();
248 void packagelist::kd_revertdirect() {
250 for (index
=0; index
<nitems
; index
++) {
251 if (table
[index
]->pkg
->name
)
252 table
[index
]->selected
= table
[index
]->direct
;
253 ldrawnstart
= ldrawnend
= -1;
255 refreshlist(); redrawthisstate();
258 void packagelist::kd_revertsuggest() {
260 for (index
=0; index
<nitems
; index
++) {
261 if (table
[index
]->pkg
->name
)
262 table
[index
]->selected
= table
[index
]->suggested
;
263 ldrawnstart
= ldrawnend
= -1;
265 refreshlist(); redrawthisstate();
269 packagelist::kd_revertinstalled()
273 for (i
= 0; i
< nitems
; i
++) {
274 if (table
[i
]->pkg
->name
)
275 table
[i
]->selected
= reallywant(pkginfo::want_sentinel
, table
[i
]);
276 ldrawnstart
= ldrawnend
= -1;
283 /* FIXME: configurable purge/deselect */
285 void packagelist::kd_toggleinfo() {
286 showinfo
= (showinfo
+2) % 3;
288 if (cursorline
>= topofscreen
+list_height
) topofscreen
+= list_height
;
289 if (topofscreen
> nitems
- list_height
) topofscreen
= nitems
-list_height
;
290 if (topofscreen
< 0) topofscreen
= 0;
292 redraw1item(cursorline
);
298 void packagelist::kd_info() {
300 showinfo
= 2; kd_toggleinfo();