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.
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
)))
42 if (comparewith
->section
&&
43 strcasecmp(comparewith
->section
,
50 void packagelist::affectedrange(int *startp
, int *endp
) {
51 if (table
[cursorline
]->pkg
->name
) {
57 for (index
= cursorline
; index
< nitems
&& !table
[index
]->pkg
->name
; index
++);
58 if (index
>= nitems
) {
59 *startp
= *endp
= cursorline
;
63 while (index
< nitems
&& matches(table
[index
]->pkg
,table
[cursorline
]->pkg
)) 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;
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
) {
89 if (!readwrite
) { beep(); return; }
92 redrawitemsrange(cursorline
,cursorline
+1);
93 table
[cursorline
]->selected
= reallywant(nwarg
,table
[cursorline
]);
94 redraw1item(cursorline
);
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
))
108 sub
->add(table
[index
]->pkg
,nw
);
111 repeatedlydisplay(sub
,dp_may
,this);
112 for (index
=top
; index
< bot
; 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;
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");
152 void packagelist::kd_swaporder() {
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");
163 void packagelist::resortredisplay() {
164 const char *oldname
= table
[cursorline
]->pkg
->name
;
170 for (index
=0; index
<nitems
; index
++) {
171 if (table
[index
]->pkg
->name
&& !strcasecmp(oldname
,table
[index
]->pkg
->name
)) {
177 topofscreen
= newcursor
-1;
178 if (topofscreen
> nitems
- list_height
) topofscreen
= nitems
-list_height
;
179 if (topofscreen
< 0) topofscreen
= 0;
183 ldrawnstart
= ldrawnend
= -1;
185 setcursor(newcursor
);
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");
198 ldrawnstart
= ldrawnend
= -1;
201 redrawitemsrange(topofscreen
,lesserint(topofscreen
+list_height
,nitems
));
205 void packagelist::kd_verbose() {
209 ldrawnstart
= ldrawnend
= -1;
212 redrawitemsrange(topofscreen
,lesserint(topofscreen
+list_height
,nitems
));
216 void packagelist::kd_quit_noop() { }
218 void packagelist::kd_revert_abort() {
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() {
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() {
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;
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;
257 redraw1item(cursorline
);
263 void packagelist::kd_info() {
265 showinfo
= 2; kd_toggleinfo();