]>
Commit | Line | Data |
---|---|---|
23c9e63c | 1 | /* |
3467d79f | 2 | * Copyright (c) 2000, 2001 Red Hat, Inc. |
23c9e63c DD |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by DJ Delorie <dj@cygnus.com> | |
13 | * | |
14 | */ | |
15 | ||
16 | /* The purpose of this file is to let the user choose which packages | |
17 | to install, and which versions of the package when more than one | |
18 | version is provided. The "trust" level serves as an indication as | |
19 | to which version should be the default choice. At the moment, all | |
20 | we do is compare with previously installed packages to skip any | |
21 | that are already installed (by setting the action to ACTION_SAME). | |
22 | While the "trust" stuff is supported, it's not really implemented | |
23 | yet. We always prefer the "current" option. In the future, this | |
24 | file might have a user dialog added to let the user choose to not | |
25 | install packages, or to install packages that aren't installed by | |
26 | default. */ | |
27 | ||
f557695e RC |
28 | static char *cvsid = |
29 | "\n%%% $Id$\n"; | |
8507f105 | 30 | |
23c9e63c DD |
31 | #include "win32.h" |
32 | #include <stdio.h> | |
713bbe5f | 33 | #include <stdlib.h> |
60c632b3 | 34 | #include <io.h> |
713bbe5f DD |
35 | #include <ctype.h> |
36 | ||
23c9e63c DD |
37 | #include "dialog.h" |
38 | #include "resource.h" | |
39 | #include "state.h" | |
40 | #include "ini.h" | |
41 | #include "concat.h" | |
42 | #include "msg.h" | |
89b1a15b | 43 | #include "log.h" |
4a83b7b0 | 44 | #include "find.h" |
fb087b80 | 45 | #include "filemanip.h" |
a351e48c | 46 | #include "mount.h" |
8f53e82a | 47 | #include "choose.h" |
23c9e63c | 48 | |
60c632b3 CV |
49 | #include "port.h" |
50 | ||
ee411d77 CF |
51 | #define alloca __builtin_alloca |
52 | ||
60c632b3 | 53 | #define HMARGIN 10 |
3b9077d4 DD |
54 | #define ROW_MARGIN 5 |
55 | #define ICON_MARGIN 4 | |
08f8c762 | 56 | #define NEW_COL_SIZE_SLOP (ICON_MARGIN + 11) |
3b9077d4 DD |
57 | |
58 | #define CHECK_SIZE 11 | |
713bbe5f | 59 | |
713bbe5f DD |
60 | static int initialized = 0; |
61 | ||
713bbe5f DD |
62 | static int scroll_ulc_x, scroll_ulc_y; |
63 | ||
42bf5b92 | 64 | static HWND lv, nextbutton, choose_inst_text; |
713bbe5f DD |
65 | static TEXTMETRIC tm; |
66 | static int header_height; | |
67 | static HANDLE sysfont; | |
68 | static int row_height; | |
3b9077d4 | 69 | static HANDLE bm_spin, bm_rtarrow, bm_checkyes, bm_checkno, bm_checkna; |
713bbe5f | 70 | static HDC bitmap_dc; |
8f53e82a | 71 | static view *chooser = NULL; |
06560feb | 72 | static trusts deftrust = TRUST_UNKNOWN; |
8f53e82a RC |
73 | |
74 | static struct _header pkg_headers[] = { | |
f557695e RC |
75 | {"Current", 7, 0, 0}, |
76 | {"New", 3, 0, 0}, | |
77 | {"Src?", 4, 0, 0}, | |
78 | {"Category", 8, 0, 0}, | |
79 | {"Package", 7, 0, 0}, | |
80 | {0, 0, 0, 0} | |
8f53e82a | 81 | }; |
713bbe5f | 82 | |
8f53e82a | 83 | static struct _header cat_headers[] = { |
f557695e RC |
84 | {"Category", 8, 0, 0}, |
85 | {"Current", 7, 0, 0}, | |
86 | {"New", 3, 0, 0}, | |
87 | {"Src?", 4, 0, 0}, | |
88 | {"Package", 7, 0, 0}, | |
89 | {0, 0, 0, 0} | |
713bbe5f DD |
90 | }; |
91 | ||
f557695e | 92 | static int add_required (Package * pkg); |
8f53e82a RC |
93 | static void set_view_mode (HWND h, views mode); |
94 | ||
c46a33a9 | 95 | static bool |
f557695e | 96 | isinstalled (Package * pkg, int trust) |
c46a33a9 | 97 | { |
1fb09149 CF |
98 | if (source == IDC_SOURCE_DOWNLOAD) |
99 | return pkg->info[trust].install_exists < 0; | |
100 | else | |
101 | return pkg->installed && pkg->info[trust].version && | |
f557695e | 102 | strcasecmp (pkg->installed->version, pkg->info[trust].version) == 0; |
c46a33a9 | 103 | } |
6a748750 | 104 | |
68b27c12 | 105 | /* Set the next action given a current action. */ |
c46a33a9 | 106 | static void |
f557695e | 107 | set_action (Package * pkg, bool preinc) |
c46a33a9 | 108 | { |
f557695e | 109 | /* preinc is only used by 'click' */ |
c46a33a9 | 110 | if (!pkg->action || preinc) |
3467d79f CF |
111 | { |
112 | ((int) pkg->action)++; | |
113 | pkg->srcpicked = 0; | |
114 | } | |
68b27c12 CF |
115 | |
116 | /* Exercise the action state machine. */ | |
c46a33a9 CF |
117 | for (;; ((int) pkg->action)++) |
118 | switch (pkg->action) | |
6a748750 | 119 | { |
c46a33a9 CF |
120 | case ACTION_ERROR: |
121 | case ACTION_UNKNOWN: | |
122 | pkg->action = (actions) (ACTION_CURR - 1); | |
123 | break; | |
124 | case ACTION_LAST: | |
125 | pkg->action = ACTION_PREV; | |
126 | /* fall through intentionally */ | |
127 | case ACTION_PREV: | |
128 | case ACTION_CURR: | |
129 | case ACTION_TEST: | |
68b27c12 CF |
130 | /* Try to find the next best action. We may not have all of |
131 | prev, curr, or test but we should have at least one of those. */ | |
f557695e | 132 | Info * inf; |
c46a33a9 CF |
133 | inf = pkg->info + pkg->action; |
134 | if (inf->version && inf->install_exists) | |
135 | { | |
136 | if (isinstalled (pkg, pkg->action)) | |
137 | (int) pkg->action += ACTION_SAME; | |
138 | return; | |
139 | } | |
f557695e RC |
140 | /* the passed in trust level is missing... */ |
141 | if (!preinc /* auto set */ | |
142 | && pkg->installed | |
143 | && pkg->action > ACTION_CURR) /* There is no current version */ | |
144 | (int)pkg->action = ACTION_SAME_CURR; | |
c46a33a9 | 145 | break; |
f557695e RC |
146 | /* ACTION_SAME_* are used when the installed version is the same |
147 | as the given action. */ | |
c46a33a9 CF |
148 | case ACTION_SAME_CURR: |
149 | case ACTION_SAME_TEST: | |
f557695e | 150 | if (!preinc) /* Previously set to this value */ |
e98d90bd | 151 | return; |
c46a33a9 CF |
152 | (int) pkg->action -= ACTION_SAME + 1; /* revert to ACTION_CURR, etc. */ |
153 | break; | |
154 | case ACTION_SAME_PREV: | |
f557695e | 155 | if (!preinc) /* Previously set to this value */ |
e98d90bd | 156 | return; |
c46a33a9 | 157 | pkg->action = ACTION_UNINSTALL; |
f557695e | 158 | /* Fall through intentionally */ |
c46a33a9 | 159 | case ACTION_UNINSTALL: |
1fb09149 | 160 | if (source != IDC_SOURCE_DOWNLOAD && pkg->installed) |
c46a33a9 | 161 | return; |
3467d79f | 162 | break; |
3ae6c15c | 163 | case ACTION_REDO: |
1fb09149 | 164 | { |
06560feb | 165 | if (isinstalled (pkg, deftrust)) |
1fb09149 | 166 | { |
06560feb | 167 | pkg->trust = deftrust; |
1fb09149 CF |
168 | return; |
169 | } | |
170 | } | |
3467d79f | 171 | break; |
c46a33a9 | 172 | case ACTION_SRC_ONLY: |
1fb09149 | 173 | { |
06560feb | 174 | if (pkg->info[deftrust].source_exists) |
1fb09149 | 175 | { |
06560feb | 176 | pkg->trust = deftrust; |
1fb09149 CF |
177 | pkg->srcpicked = 1; |
178 | return; | |
179 | } | |
180 | } | |
c46a33a9 CF |
181 | break; |
182 | case ACTION_SAME_LAST: | |
183 | pkg->action = ACTION_SKIP; | |
184 | /* Fall through intentionally */ | |
185 | case ACTION_SKIP: | |
8114d309 | 186 | if (!pkg->installed) |
3467d79f CF |
187 | return; |
188 | break; | |
c46a33a9 CF |
189 | default: |
190 | log (0, "should never get here %d\n", pkg->action); | |
6a748750 | 191 | } |
c46a33a9 | 192 | } |
713bbe5f | 193 | |
8f53e82a | 194 | static int |
f557695e | 195 | add_required (Package * pkg) |
8f53e82a RC |
196 | { |
197 | Dependency *dp; | |
198 | Package *required; | |
199 | int c; | |
200 | int changed = 0; | |
201 | dp = pkg->required; | |
202 | switch (pkg->action) | |
203 | { | |
204 | case ACTION_UNINSTALL: | |
205 | case ACTION_ERROR: | |
206 | case ACTION_UNKNOWN: | |
207 | case ACTION_SRC_ONLY: | |
208 | case ACTION_SKIP: | |
209 | return 0; | |
210 | default: | |
211 | break; | |
212 | } | |
213 | while (dp) | |
214 | { | |
f557695e | 215 | if ((required = getpkgbyname (dp->package)) == NULL) |
1fb09149 | 216 | { |
f557695e | 217 | dp = dp->next; |
1fb09149 CF |
218 | continue; |
219 | } | |
8f53e82a | 220 | switch (required->action) |
1fb09149 | 221 | { |
8f53e82a RC |
222 | case ACTION_PREV: |
223 | case ACTION_CURR: | |
224 | case ACTION_TEST: | |
225 | case ACTION_LAST: | |
226 | case ACTION_SAME_CURR: | |
227 | case ACTION_SAME_TEST: | |
228 | case ACTION_SAME_PREV: | |
229 | case ACTION_REDO: | |
230 | case ACTION_SAME_LAST: | |
231 | /* we are installing a user selected version */ | |
232 | break; | |
f557695e | 233 | |
8f53e82a RC |
234 | case ACTION_UNINSTALL: |
235 | /* it's already installed - leave it */ | |
3467d79f | 236 | required->action = (actions) required->installed_ix; |
8f53e82a | 237 | break; |
878faffd RC |
238 | case ACTION_SKIP: |
239 | case ACTION_SRC_ONLY: | |
240 | if (required->installed) | |
241 | break; | |
8f53e82a RC |
242 | case ACTION_ERROR: |
243 | case ACTION_UNKNOWN: | |
8f53e82a | 244 | /* the current install will fail */ |
f557695e RC |
245 | required->action = ACTION_UNKNOWN; /* this find prev, then curr, then test. */ |
246 | set_action (required, 0); /* we need a find_best that gets installed, */ | |
247 | changed++; /* then current, then prev, then test */ | |
8f53e82a RC |
248 | chooser->insert_pkg (required); |
249 | break; | |
250 | default: | |
2dada532 | 251 | log (0, "invalid state %d\n", required->action); |
8f53e82a RC |
252 | } |
253 | changed += add_required (required); | |
f557695e | 254 | dp = dp->next; |
8f53e82a RC |
255 | } |
256 | return changed; | |
257 | } | |
258 | ||
68b27c12 | 259 | /* Return an appropriate caption given the current action. */ |
c46a33a9 | 260 | const char * |
f557695e | 261 | choose_caption (Package * pkg) |
c46a33a9 CF |
262 | { |
263 | set_action (pkg, 0); | |
264 | switch (pkg->action) | |
265 | { | |
266 | case ACTION_PREV: | |
267 | case ACTION_CURR: | |
268 | case ACTION_TEST: | |
269 | pkg->trust = (trusts) pkg->action; | |
270 | return pkg->info[pkg->trust].version; | |
271 | case ACTION_SAME_PREV: | |
272 | case ACTION_SAME_CURR: | |
273 | case ACTION_SAME_TEST: | |
274 | return "Keep"; | |
275 | case ACTION_UNINSTALL: | |
276 | return "Uninstall"; | |
277 | case ACTION_REDO: | |
e98d90bd | 278 | return source == IDC_SOURCE_DOWNLOAD ? "Retrieve" : "Reinstall"; |
c46a33a9 CF |
279 | case ACTION_SRC_ONLY: |
280 | if (pkg->installed && pkg->installed->source_exists) | |
281 | return "Redo Source"; | |
282 | else | |
283 | return "Source"; | |
284 | case ACTION_SKIP: | |
285 | return "Skip"; | |
286 | } | |
f557695e | 287 | return "???"; |
c46a33a9 | 288 | } |
713bbe5f DD |
289 | |
290 | static void | |
291 | paint (HWND hwnd) | |
23c9e63c | 292 | { |
713bbe5f DD |
293 | HDC hdc; |
294 | PAINTSTRUCT ps; | |
295 | int x, y, i, j, ii; | |
23c9e63c | 296 | |
713bbe5f | 297 | hdc = BeginPaint (hwnd, &ps); |
23c9e63c | 298 | |
713bbe5f | 299 | SelectObject (hdc, sysfont); |
fb087b80 | 300 | SetBkColor (hdc, GetSysColor (COLOR_WINDOW)); |
9eeb0e83 | 301 | SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)); |
23c9e63c | 302 | |
713bbe5f DD |
303 | RECT cr; |
304 | GetClientRect (hwnd, &cr); | |
305 | ||
306 | POINT p; | |
307 | ||
308 | x = cr.left - scroll_ulc_x; | |
309 | y = cr.top - scroll_ulc_y + header_height; | |
310 | ||
311 | ||
f557695e | 312 | for (i = 0; i <= chooser->last_col; i++) |
23c9e63c | 313 | { |
2dada532 CF |
314 | TextOut (hdc, x + chooser->headers[i].x, 3, chooser->headers[i].text, |
315 | chooser->headers[i].slen); | |
f557695e | 316 | MoveToEx (hdc, x + chooser->headers[i].x, header_height - 3, &p); |
2dada532 | 317 | LineTo (hdc, x + chooser->headers[i].x + chooser->headers[i].width, |
f557695e | 318 | header_height - 3); |
713bbe5f DD |
319 | } |
320 | ||
f557695e RC |
321 | IntersectClipRect (hdc, cr.left, cr.top + header_height, cr.right, |
322 | cr.bottom); | |
713bbe5f | 323 | |
8f53e82a | 324 | for (ii = 0; ii < chooser->nlines; ii++) |
f557695e RC |
325 | chooser->lines[ii].paint (hdc, x, y, ii, |
326 | (chooser->get_view_mode () == | |
327 | VIEW_CATEGORY) ? 0 : 1); | |
5f48f258 | 328 | |
8f53e82a | 329 | if (chooser->nlines == 0) |
5f48f258 DD |
330 | { |
331 | static char *msg = "Nothing to Install/Update"; | |
60c632b3 | 332 | if (source == IDC_SOURCE_DOWNLOAD) |
47f8d8b3 | 333 | msg = "Nothing to Download"; |
5f48f258 DD |
334 | TextOut (hdc, HMARGIN, header_height, msg, strlen (msg)); |
335 | } | |
fb087b80 | 336 | |
713bbe5f DD |
337 | EndPaint (hwnd, &ps); |
338 | } | |
339 | ||
340 | static void | |
341 | scroll_common (HWND hwnd, int which, int *var, int code) | |
342 | { | |
343 | int v = *var; | |
23c9e63c | 344 | |
713bbe5f DD |
345 | SCROLLINFO si; |
346 | si.cbSize = sizeof (si); | |
347 | si.fMask = SIF_ALL; | |
348 | GetScrollInfo (hwnd, which, &si); | |
349 | ||
350 | switch (code) | |
23c9e63c | 351 | { |
713bbe5f DD |
352 | case SB_THUMBTRACK: |
353 | si.nPos = si.nTrackPos; | |
354 | break; | |
355 | case SB_THUMBPOSITION: | |
356 | break; | |
357 | case SB_BOTTOM: | |
358 | si.nPos = si.nMax; | |
359 | break; | |
360 | case SB_TOP: | |
361 | si.nPos = 0; | |
362 | break; | |
363 | case SB_LINEDOWN: | |
364 | si.nPos += row_height; | |
365 | break; | |
366 | case SB_LINEUP: | |
367 | si.nPos -= row_height; | |
368 | break; | |
369 | case SB_PAGEDOWN: | |
f557695e | 370 | si.nPos += si.nPage * 9 / 10; |
713bbe5f DD |
371 | break; |
372 | case SB_PAGEUP: | |
f557695e | 373 | si.nPos -= si.nPage * 9 / 10; |
713bbe5f DD |
374 | break; |
375 | } | |
376 | ||
f557695e | 377 | if ((int) si.nPos < 0) |
713bbe5f DD |
378 | si.nPos = 0; |
379 | if (si.nPos + si.nPage > si.nMax) | |
380 | si.nPos = si.nMax - si.nPage; | |
381 | ||
382 | si.fMask = SIF_POS; | |
383 | SetScrollInfo (hwnd, which, &si, TRUE); | |
384 | ||
385 | int ox = scroll_ulc_x; | |
386 | int oy = scroll_ulc_y; | |
387 | *var = si.nPos; | |
388 | ||
389 | RECT cr, sr; | |
390 | GetClientRect (hwnd, &cr); | |
391 | sr = cr; | |
392 | sr.top += header_height; | |
393 | ScrollWindow (hwnd, ox - scroll_ulc_x, oy - scroll_ulc_y, &sr, &sr); | |
394 | sr.bottom = sr.top; | |
395 | sr.top = cr.top; | |
396 | ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr); | |
397 | } | |
398 | ||
399 | static LRESULT CALLBACK | |
400 | list_vscroll (HWND hwnd, HWND hctl, UINT code, int pos) | |
401 | { | |
402 | scroll_common (hwnd, SB_VERT, &scroll_ulc_y, code); | |
2399c54d | 403 | return 0; |
713bbe5f DD |
404 | } |
405 | ||
406 | static LRESULT CALLBACK | |
407 | list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos) | |
408 | { | |
409 | scroll_common (hwnd, SB_HORZ, &scroll_ulc_x, code); | |
2399c54d | 410 | return 0; |
713bbe5f DD |
411 | } |
412 | ||
413 | static LRESULT CALLBACK | |
414 | list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode) | |
415 | { | |
f557695e | 416 | int row, refresh; |
713bbe5f | 417 | |
8f53e82a | 418 | if (chooser->nlines == 0) |
8cfbc487 DD |
419 | return 0; |
420 | ||
713bbe5f DD |
421 | if (y < header_height) |
422 | return 0; | |
423 | x += scroll_ulc_x; | |
424 | y += scroll_ulc_y - header_height; | |
425 | ||
f557695e | 426 | row = (y + ROW_MARGIN / 2) / row_height; |
713bbe5f | 427 | |
42a99ed1 | 428 | if (row < 0 || row >= chooser->nlines) |
713bbe5f DD |
429 | return 0; |
430 | ||
42a99ed1 | 431 | refresh = chooser->click (row, x); |
f557695e | 432 | |
8f53e82a RC |
433 | if (refresh) |
434 | { | |
435 | RECT r; | |
436 | GetClientRect (lv, &r); | |
437 | SCROLLINFO si; | |
438 | memset (&si, 0, sizeof (si)); | |
439 | si.cbSize = sizeof (si); | |
f557695e | 440 | si.fMask = SIF_ALL; /* SIF_RANGE was giving strange behaviour */ |
8f53e82a | 441 | si.nMin = 0; |
713bbe5f | 442 | |
8f53e82a RC |
443 | si.nMax = chooser->nlines * row_height; |
444 | si.nPage = r.bottom - header_height; | |
42a99ed1 RC |
445 | |
446 | /* if we are under the minimum display count , | |
447 | * set the offset to 0 | |
448 | */ | |
449 | if (si.nMax <= si.nPage) | |
450 | scroll_ulc_y = 0; | |
8f53e82a | 451 | si.nPos = scroll_ulc_y; |
42a99ed1 | 452 | |
8f53e82a | 453 | SetScrollInfo (lv, SB_VERT, &si, TRUE); |
3b9077d4 | 454 | |
8f53e82a | 455 | InvalidateRect (lv, &r, TRUE); |
713bbe5f | 456 | |
8f53e82a RC |
457 | } |
458 | else | |
459 | { | |
460 | RECT rect; | |
461 | rect.left = chooser->headers[chooser->new_col].x - scroll_ulc_x; | |
462 | rect.right = chooser->headers[chooser->src_col + 1].x - scroll_ulc_x; | |
42a99ed1 | 463 | rect.top = header_height + row * row_height - scroll_ulc_y; |
8f53e82a RC |
464 | rect.bottom = rect.top + row_height; |
465 | InvalidateRect (hwnd, &rect, TRUE); | |
466 | } | |
2399c54d | 467 | return 0; |
713bbe5f DD |
468 | } |
469 | ||
470 | static LRESULT CALLBACK | |
471 | listview_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |
472 | { | |
6a748750 CF |
473 | switch (message) |
474 | { | |
475 | case WM_HSCROLL: | |
476 | return HANDLE_WM_HSCROLL (hwnd, wParam, lParam, list_hscroll); | |
477 | case WM_VSCROLL: | |
478 | return HANDLE_WM_VSCROLL (hwnd, wParam, lParam, list_vscroll); | |
479 | case WM_LBUTTONDOWN: | |
480 | return HANDLE_WM_LBUTTONDOWN (hwnd, wParam, lParam, list_click); | |
481 | case WM_PAINT: | |
482 | paint (hwnd); | |
483 | return 0; | |
484 | default: | |
485 | return DefWindowProc (hwnd, message, wParam, lParam); | |
486 | } | |
713bbe5f DD |
487 | } |
488 | ||
489 | static void | |
490 | register_windows (HINSTANCE hinst) | |
491 | { | |
492 | WNDCLASSEX wcex; | |
493 | static int done = 0; | |
494 | ||
495 | if (done) | |
496 | return; | |
497 | done = 1; | |
498 | ||
499 | memset (&wcex, 0, sizeof (wcex)); | |
500 | wcex.cbSize = sizeof (WNDCLASSEX); | |
501 | wcex.style = CS_HREDRAW | CS_VREDRAW; | |
502 | wcex.lpfnWndProc = listview_proc; | |
503 | wcex.hInstance = hinst; | |
504 | wcex.hIcon = LoadIcon (0, IDI_APPLICATION); | |
505 | wcex.hCursor = LoadCursor (0, IDC_ARROW); | |
6a748750 | 506 | wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); |
713bbe5f DD |
507 | wcex.lpszClassName = "listview"; |
508 | ||
509 | RegisterClassEx (&wcex); | |
510 | } | |
511 | ||
512 | static void | |
f557695e RC |
513 | note_width (struct _header *hdrs, HDC dc, char *string, int addend, |
514 | int column) | |
713bbe5f DD |
515 | { |
516 | if (!string) | |
517 | return; | |
518 | SIZE s; | |
519 | GetTextExtentPoint32 (dc, string, strlen (string), &s); | |
8f53e82a RC |
520 | if (hdrs[column].width < s.cx + addend) |
521 | hdrs[column].width = s.cx + addend; | |
713bbe5f DD |
522 | } |
523 | ||
fb087b80 | 524 | static int |
f557695e | 525 | check_existence (Info * inf, int check_src) |
60c632b3 CV |
526 | { |
527 | if (source == IDC_SOURCE_NETINST) | |
6a748750 | 528 | return 1; |
60c632b3 | 529 | if (source == IDC_SOURCE_CWD) |
f557695e | 530 | return 0; /* should have already been determined */ |
c46a33a9 CF |
531 | if (check_src) |
532 | return (inf->source && _access (inf->source, 0) == 0) ? -1 : 1; | |
533 | else | |
534 | return (inf->install && _access (inf->install, 0) == 0) ? -1 : 1; | |
60c632b3 CV |
535 | return 0; |
536 | } | |
537 | ||
68b27c12 CF |
538 | /* Iterate over the package list, setting the "existence" flags |
539 | for the source or binary. */ | |
60c632b3 CV |
540 | static void |
541 | set_existence () | |
542 | { | |
f557695e | 543 | for (Package * pkg = package; pkg->name; pkg++) |
c46a33a9 CF |
544 | if (!pkg->exclude) |
545 | { | |
546 | int exists = 0; | |
f557695e | 547 | for (Info * inf = pkg->infoscan; inf < pkg->infoend; inf++) |
c46a33a9 | 548 | { |
c46a33a9 CF |
549 | if (inf->install_exists) |
550 | exists = 1; | |
551 | else | |
552 | exists |= inf->install_exists = check_existence (inf, 0); | |
553 | if (inf->source_exists) | |
554 | exists = 1; | |
555 | else | |
556 | exists |= inf->source_exists = check_existence (inf, 1); | |
557 | } | |
f557695e | 558 | if (source != IDC_SOURCE_DOWNLOAD && !exists) |
c46a33a9 CF |
559 | pkg->exclude = EXCLUDE_NOT_FOUND; |
560 | } | |
713bbe5f DD |
561 | } |
562 | ||
8f53e82a RC |
563 | static void |
564 | fill_missing_category () | |
565 | { | |
f557695e | 566 | for (Package * pkg = package; pkg->name; pkg++) |
969a294c | 567 | if (!pkg->exclude && !pkg->category) |
8f53e82a RC |
568 | add_category (pkg, register_category ("Misc")); |
569 | } | |
570 | ||
3467d79f | 571 | static actions |
f557695e | 572 | keep_or_skip (Package * pkg) |
3467d79f CF |
573 | { |
574 | if (pkg->installed) | |
575 | return (actions) pkg->installed_ix; | |
576 | return ACTION_SKIP; | |
577 | } | |
578 | ||
713bbe5f | 579 | static void |
c46a33a9 | 580 | default_trust (HWND h, trusts trust) |
713bbe5f DD |
581 | { |
582 | int i, t, c; | |
583 | ||
06560feb | 584 | deftrust = trust; |
f557695e | 585 | for (Package * pkg = package; pkg->name; pkg++) |
969a294c CF |
586 | if (!pkg->exclude) |
587 | { | |
588 | pkg->action = (actions) trust; | |
f557695e | 589 | if (!pkg->installed && pkg->category |
c8fea72a | 590 | && !(getpackagecategorybyname (pkg, "Base") |
f557695e | 591 | || getpackagecategorybyname (pkg, "Misc"))) |
969a294c CF |
592 | pkg->action = keep_or_skip (pkg); |
593 | set_action (pkg, 0); | |
594 | } | |
713bbe5f DD |
595 | RECT r; |
596 | GetClientRect (h, &r); | |
597 | InvalidateRect (h, &r, TRUE); | |
598 | if (nextbutton) | |
599 | SetFocus (nextbutton); | |
600 | } | |
601 | ||
8f53e82a | 602 | void |
f557695e | 603 | pick_line::set_line (Package * _pkg) |
8f53e82a RC |
604 | { |
605 | pkg = _pkg; | |
606 | cat = NULL; | |
607 | } | |
608 | ||
609 | void | |
f557695e | 610 | pick_line::set_line (Category * _cat) |
8f53e82a RC |
611 | { |
612 | cat = _cat; | |
613 | pkg = NULL; | |
614 | } | |
615 | ||
616 | void | |
617 | pick_line::paint (HDC hdc, int x, int y, int row, int show_cat) | |
618 | { | |
619 | int r = y + row * row_height; | |
620 | int by = r + tm.tmHeight - 11; | |
621 | if (pkg) | |
622 | { | |
623 | if (pkg->installed) | |
1fb09149 CF |
624 | { |
625 | TextOut (hdc, x + chooser->headers[chooser->current_col].x, r, | |
626 | pkg->installed->version, strlen (pkg->installed->version)); | |
627 | SelectObject (bitmap_dc, bm_rtarrow); | |
628 | BitBlt (hdc, x + chooser->headers[chooser->current_col].x | |
f557695e RC |
629 | + chooser->headers[0].width + ICON_MARGIN / 2 |
630 | + HMARGIN / 2, by, 11, 11, bitmap_dc, 0, 0, SRCCOPY); | |
1fb09149 | 631 | } |
8f53e82a RC |
632 | |
633 | const char *s = choose_caption (pkg); | |
2dada532 | 634 | TextOut (hdc, x + chooser->headers[chooser->new_col].x |
f557695e | 635 | + NEW_COL_SIZE_SLOP, r, s, strlen (s)); |
8f53e82a RC |
636 | SelectObject (bitmap_dc, bm_spin); |
637 | BitBlt (hdc, x + chooser->headers[chooser->new_col].x, by, 11, 11, | |
1fb09149 | 638 | bitmap_dc, 0, 0, SRCCOPY); |
8f53e82a RC |
639 | |
640 | HANDLE check_bm; | |
06560feb | 641 | if (!pkg->info[pkg->trust].source_exists |
f557695e RC |
642 | || (pkg->action != ACTION_REDO |
643 | && pkg->action != (actions) pkg->trust)) | |
1fb09149 | 644 | check_bm = bm_checkna; |
14cfffa5 | 645 | else if (pkg->srcpicked) |
1fb09149 | 646 | check_bm = bm_checkyes; |
8f53e82a | 647 | else |
1fb09149 | 648 | check_bm = bm_checkno; |
8f53e82a RC |
649 | |
650 | SelectObject (bitmap_dc, check_bm); | |
651 | BitBlt (hdc, x + chooser->headers[chooser->src_col].x, by, 11, 11, | |
1fb09149 | 652 | bitmap_dc, 0, 0, SRCCOPY); |
8f53e82a | 653 | |
2dada532 | 654 | /* shows "first" category - do we want to show any? */ |
8f53e82a | 655 | if (pkg->category && show_cat) |
2dada532 CF |
656 | TextOut (hdc, x + chooser->headers[chooser->cat_col].x, r, |
657 | pkg->category->name, strlen (pkg->category->name)); | |
8f53e82a | 658 | |
308d6f3e | 659 | if (!pkg->sdesc) |
1fb09149 | 660 | s = pkg->name; |
308d6f3e CF |
661 | else |
662 | { | |
663 | static char buf[512]; | |
f557695e RC |
664 | strcpy (buf, pkg->name); |
665 | strcat (buf, ": "); | |
666 | strcat (buf, pkg->sdesc); | |
308d6f3e CF |
667 | s = buf; |
668 | } | |
f557695e RC |
669 | TextOut (hdc, x + chooser->headers[chooser->pkg_col].x, r, s, |
670 | strlen (s)); | |
8f53e82a RC |
671 | } |
672 | else if (cat) | |
2dada532 CF |
673 | TextOut (hdc, x + chooser->headers[chooser->cat_col].x, r, cat->name, |
674 | strlen (cat->name)); | |
8f53e82a RC |
675 | } |
676 | ||
677 | int | |
678 | pick_line::click (int x) | |
679 | { | |
680 | if (pkg) | |
681 | { | |
3467d79f | 682 | if (pkg->info[pkg->trust].source_exists |
f557695e RC |
683 | && x >= chooser->headers[chooser->src_col].x - HMARGIN / 2 |
684 | && x <= chooser->headers[chooser->src_col + 1].x - HMARGIN / 2) | |
06560feb | 685 | pkg->srcpicked ^= 1; |
8f53e82a | 686 | |
3467d79f | 687 | if (x >= chooser->headers[chooser->new_col].x - (HMARGIN / 2) |
f557695e | 688 | && x <= chooser->headers[chooser->new_col + 1].x - HMARGIN / 2) |
3467d79f CF |
689 | { |
690 | set_action (pkg, 1); | |
691 | /* Add any packages that are needed by this package */ | |
f557695e | 692 | return add_required (pkg); |
3467d79f | 693 | } |
8f53e82a RC |
694 | } |
695 | else if (cat) | |
696 | { | |
697 | /* handle the catalog being clicked ... does this belong up a level.. ? */ | |
698 | } | |
f557695e | 699 | |
8f53e82a RC |
700 | return 0; |
701 | } | |
702 | ||
703 | _view::_view (views _mode, HDC dc) | |
704 | { | |
705 | lines = NULL; | |
706 | nlines = 0; | |
707 | view_mode = VIEW_PACKAGE; | |
708 | set_headers (); | |
709 | init_headers (dc); | |
710 | view_mode = VIEW_CATEGORY; | |
711 | set_headers (); | |
712 | init_headers (dc); | |
713 | ||
714 | view_mode = _mode; | |
715 | set_headers (); | |
716 | } | |
717 | ||
718 | void | |
719 | _view::set_view_mode (views _mode) | |
720 | { | |
721 | if (_mode == NVIEW) | |
f557695e | 722 | view_mode = VIEW_PACKAGE_FULL; |
8f53e82a RC |
723 | else |
724 | view_mode = _mode; | |
725 | set_headers (); | |
726 | } | |
727 | ||
728 | char * | |
729 | _view::mode_caption () | |
730 | { | |
731 | switch (view_mode) | |
732 | { | |
f557695e RC |
733 | case VIEW_UNKNOWN: |
734 | return ""; | |
735 | case VIEW_PACKAGE_FULL: | |
736 | return "Full"; | |
737 | case VIEW_PACKAGE: | |
738 | return "Partial"; | |
739 | case VIEW_CATEGORY: | |
740 | return "Category"; | |
741 | default: | |
742 | return ""; | |
8f53e82a RC |
743 | } |
744 | } | |
745 | ||
746 | void | |
747 | _view::set_headers (void) | |
748 | { | |
749 | switch (view_mode) | |
750 | { | |
751 | case VIEW_UNKNOWN: | |
752 | return; | |
f557695e RC |
753 | case VIEW_PACKAGE_FULL: |
754 | case VIEW_PACKAGE: | |
8f53e82a RC |
755 | headers = pkg_headers; |
756 | current_col = 0; | |
757 | new_col = 1; | |
758 | src_col = 2; | |
759 | cat_col = 3; | |
760 | pkg_col = 4; | |
761 | last_col = 4; | |
762 | break; | |
763 | case VIEW_CATEGORY: | |
764 | headers = cat_headers; | |
765 | current_col = 1; | |
766 | new_col = 2; | |
767 | src_col = 3; | |
768 | cat_col = 0; | |
769 | pkg_col = 4; | |
770 | last_col = 4; | |
771 | default: | |
772 | return; | |
773 | } | |
774 | } | |
775 | ||
776 | void | |
777 | _view::init_headers (HDC dc) | |
713bbe5f | 778 | { |
c46a33a9 | 779 | int i; |
c46a33a9 | 780 | |
8f53e82a RC |
781 | for (i = 0; headers[i].text; i++) |
782 | headers[i].width = 0; | |
c46a33a9 | 783 | |
8f53e82a RC |
784 | for (i = 0; headers[i].text; i++) |
785 | note_width (headers, dc, headers[i].text, 0, i); | |
f557695e | 786 | for (Package * pkg = package; pkg->name; pkg++) |
8f53e82a RC |
787 | { |
788 | if (pkg->installed) | |
1fb09149 CF |
789 | { |
790 | note_width (headers, dc, pkg->installed->version, 0, current_col); | |
791 | note_width (headers, dc, pkg->installed->version, NEW_COL_SIZE_SLOP, | |
3467d79f | 792 | new_col); |
1fb09149 | 793 | } |
f557695e | 794 | for (Info * inf = pkg->infoscan; inf < pkg->infoend; inf++) |
1fb09149 | 795 | note_width (headers, dc, inf->version, NEW_COL_SIZE_SLOP, new_col); |
f557695e | 796 | for (Category * cat = pkg->category; cat; cat = cat->next) |
8f53e82a | 797 | note_width (headers, dc, cat->name, 0, cat_col); |
f557695e RC |
798 | if (!pkg->sdesc) |
799 | note_width (headers, dc, pkg->name, 0, pkg_col); | |
800 | else | |
801 | { | |
802 | static char buf[512]; | |
803 | strcpy (buf, pkg->name); | |
804 | strcat (buf, ": "); | |
805 | strcat (buf, pkg->sdesc); | |
806 | note_width (headers, dc, buf, 0, pkg_col); | |
807 | } | |
8f53e82a RC |
808 | } |
809 | note_width (headers, dc, "keep", NEW_COL_SIZE_SLOP, new_col); | |
810 | note_width (headers, dc, "uninstall", NEW_COL_SIZE_SLOP, new_col); | |
811 | ||
f557695e RC |
812 | headers[0].x = HMARGIN / 2; |
813 | for (i = 1; i <= last_col; i++) | |
814 | headers[i].x = headers[i - 1].x + headers[i - 1].width + ((i == new_col) ? | |
815 | NEW_COL_SIZE_SLOP | |
816 | : 0) + HMARGIN; | |
8f53e82a RC |
817 | } |
818 | ||
819 | void | |
f557695e | 820 | _view::insert_pkg (Package * pkg) |
8f53e82a RC |
821 | { |
822 | pick_line line; | |
969a294c CF |
823 | if (pkg->exclude) |
824 | return; | |
8f53e82a RC |
825 | line.set_line (pkg); |
826 | if (view_mode != VIEW_CATEGORY) | |
827 | { | |
828 | if (lines == NULL) | |
1fb09149 | 829 | { |
3467d79f CF |
830 | lines = (pick_line *) calloc (npackages + ncategories, |
831 | sizeof (pick_line)); | |
8f53e82a RC |
832 | nlines = 0; |
833 | insert_at (0, line); | |
1fb09149 | 834 | } |
8f53e82a RC |
835 | else |
836 | insert_under (0, line); | |
837 | } | |
838 | else | |
839 | { | |
840 | // assert (lines); /* protect against a coding change in future */ | |
f557695e | 841 | for (Category * cat = pkg->category; cat; cat = cat->next) |
8f53e82a RC |
842 | { |
843 | /* insert the package under this category in the list. If this category is not | |
844 | visible, add it */ | |
f557695e | 845 | int n = 0; |
8f53e82a RC |
846 | while (n < nlines) |
847 | { | |
848 | /* this should be a generic call to list_sort_cmp */ | |
849 | if (lines[n].get_category () | |
850 | && cat->name == lines[n].get_category ()->name) | |
3bcf85be | 851 | { |
8f53e82a | 852 | insert_under (n, line); |
3bcf85be RC |
853 | n = nlines; |
854 | } | |
8f53e82a RC |
855 | n++; |
856 | } | |
857 | if (n == nlines) | |
858 | { | |
859 | /* the category wasn't visible - insert at the end */ | |
860 | insert_category (cat, CATEGORY_COLLAPSED); | |
861 | insert_pkg (pkg); | |
862 | } | |
863 | } | |
864 | } | |
865 | } | |
866 | ||
867 | void | |
f557695e | 868 | _view::insert_category (Category * cat, int collapsed) |
8f53e82a RC |
869 | { |
870 | pick_line line; | |
871 | line.set_line (cat); | |
872 | if (lines == NULL) | |
873 | { | |
f557695e RC |
874 | lines = |
875 | (pick_line *) malloc ((npackages + ncategories) * sizeof (pick_line)); | |
876 | memset (lines, '\0', (npackages + ncategories) * sizeof (pick_line)); | |
8f53e82a RC |
877 | nlines = 0; |
878 | insert_at (0, line); | |
879 | if (!collapsed) | |
f557695e RC |
880 | for (CategoryPackage * catpkg = cat->packages; catpkg; |
881 | catpkg = catpkg->next) | |
969a294c | 882 | insert_pkg (getpkgbyname (catpkg->pkgname)); |
8f53e82a RC |
883 | } |
884 | else | |
885 | { | |
f557695e | 886 | int n = 0; |
8f53e82a | 887 | while (n < nlines) |
1fb09149 CF |
888 | { |
889 | /* this should be a generic call to list_sort_cmp */ | |
890 | if (lines[n].get_category () | |
891 | && strcasecmp (cat->name, lines[n].get_category ()->name) < 0) | |
892 | { | |
8f53e82a RC |
893 | insert_at (n, line); |
894 | if (!collapsed) | |
f557695e RC |
895 | for (CategoryPackage * catpkg = cat->packages; catpkg; |
896 | catpkg = catpkg->next) | |
969a294c | 897 | insert_pkg (getpkgbyname (catpkg->pkgname)); |
1fb09149 CF |
898 | n = nlines; |
899 | } | |
900 | else if (lines[n].get_category () == cat) | |
901 | n = nlines; | |
902 | n++; | |
8f53e82a | 903 | |
1fb09149 | 904 | } |
8f53e82a | 905 | if (n == nlines) |
1fb09149 CF |
906 | { |
907 | /* insert at the end */ | |
8f53e82a RC |
908 | insert_at (n, line); |
909 | if (!collapsed) | |
f557695e RC |
910 | for (CategoryPackage * catpkg = cat->packages; catpkg; |
911 | catpkg = catpkg->next) | |
969a294c | 912 | insert_pkg (getpkgbyname (catpkg->pkgname)); |
1fb09149 | 913 | } |
8f53e82a RC |
914 | } |
915 | } | |
916 | ||
917 | /* insert a new line at line n */ | |
918 | void | |
919 | _view::insert_at (int n, pick_line line) | |
920 | { | |
921 | if (n < 0 || n > nlines) | |
922 | return; | |
923 | memmove (&lines[n + 1], &lines[n], (nlines - n) * sizeof (pick_line)); | |
924 | lines[n] = line; | |
925 | nlines++; | |
926 | } | |
927 | ||
928 | /* insert a new line in the chooser, at the next depth in from linen */ | |
929 | void | |
930 | _view::insert_under (int linen, pick_line line) | |
931 | { | |
932 | int n; | |
933 | /* special case - empty view */ | |
934 | if (nlines == 0) | |
935 | { | |
936 | insert_at (0, line); | |
937 | return; | |
938 | } | |
f97a1ece RC |
939 | /* perhaps these two are equivalent. FIXME: check for potential insert_under (0,.. calls */ |
940 | else if (linen > nlines) | |
941 | { | |
942 | insert_at (nlines, line); | |
943 | return; | |
944 | } | |
8f53e82a RC |
945 | /* part 1 - find the appropriate bucket beginning */ |
946 | if (lines[linen].get_category ()) | |
947 | { | |
948 | n = linen + 1; | |
949 | } | |
950 | else if (lines[linen].get_pkg ()) | |
951 | { | |
952 | n = linen; | |
953 | /* walk up to the beginning of the bucket */ | |
954 | while (n > 0 && lines[n - 1].get_pkg ()) | |
955 | n--; | |
956 | } | |
f97a1ece RC |
957 | else |
958 | { | |
959 | /* nlines != 0 and lines[linen] is not a category or a package! */ | |
960 | return; | |
961 | } | |
8f53e82a RC |
962 | /* part 2 - insert in sorted order in the bucket */ |
963 | while (n < nlines) | |
964 | { | |
965 | if (lines[n].get_category () || (lines[n].get_pkg () | |
f557695e RC |
966 | && strcasecmp (line.get_pkg ()->name, |
967 | lines[n].get_pkg ()-> | |
968 | name) < 0)) | |
8f53e82a RC |
969 | { |
970 | insert_at (n, line); | |
971 | n = nlines; | |
972 | } | |
973 | else if (lines[n].get_pkg () == line.get_pkg ()) | |
974 | { | |
975 | n = nlines; | |
976 | } | |
977 | n++; | |
978 | } | |
979 | if (n == nlines) | |
980 | { | |
981 | /* insert at the end of this bucket */ | |
982 | insert_at (n, line); | |
983 | } | |
984 | } | |
985 | ||
986 | void | |
987 | _view::clear_view (void) | |
988 | { | |
989 | nlines = 0; | |
990 | } | |
991 | ||
992 | static views | |
f557695e | 993 | viewsplusplus (views theview) |
8f53e82a RC |
994 | { |
995 | switch (theview) | |
996 | { | |
f557695e RC |
997 | case VIEW_UNKNOWN: |
998 | return VIEW_PACKAGE_FULL; | |
999 | case VIEW_PACKAGE_FULL: | |
1000 | return VIEW_PACKAGE; | |
1001 | case VIEW_PACKAGE: | |
1002 | return VIEW_CATEGORY; | |
1003 | case VIEW_CATEGORY: | |
1004 | return NVIEW; | |
1005 | default: | |
1006 | return VIEW_UNKNOWN; | |
8f53e82a RC |
1007 | } |
1008 | } | |
1009 | ||
1010 | int | |
1011 | _view::click (int row, int x) | |
1012 | { | |
1013 | if (row > nlines) | |
1014 | return 0; | |
1015 | if (lines[row].get_pkg ()) | |
1016 | return lines[row].click (x); | |
1017 | else | |
1018 | { | |
1019 | /* if we are the last line or the next line is a category too, expand */ | |
f557695e | 1020 | if (row == (nlines - 1) || lines[row + 1].get_category ()) |
8f53e82a RC |
1021 | { |
1022 | int count = nlines; | |
f557695e RC |
1023 | for (CategoryPackage * catpkg = |
1024 | lines[row].get_category ()->packages; catpkg; | |
1025 | catpkg = catpkg->next) | |
8f53e82a | 1026 | { |
f557695e | 1027 | Package *pkg = getpkgbyname (catpkg->pkgname); |
8f53e82a RC |
1028 | int n = row + 1; |
1029 | pick_line line; | |
1030 | line.set_line (pkg); | |
1031 | /* this is a nasty hack. It will go away when the hierarchy is coded */ | |
1032 | while (n < nlines) | |
1fb09149 | 1033 | { |
8f53e82a | 1034 | if (lines[n].get_category () || (lines[n].get_pkg () |
f557695e RC |
1035 | && strcasecmp (pkg->name, |
1036 | lines[n]. | |
1037 | get_pkg ()-> | |
1038 | name) < 0)) | |
8f53e82a RC |
1039 | { |
1040 | insert_at (n, line); | |
1041 | n = nlines; | |
1042 | } | |
1043 | else if (lines[n].get_pkg () == pkg) | |
1044 | { | |
1045 | n = nlines; | |
1046 | } | |
1047 | n++; | |
1048 | } | |
1049 | if (n == nlines) | |
1050 | { | |
1051 | /* insert at the end of this category */ | |
1052 | insert_at (n, line); | |
f557695e | 1053 | n = nlines + 1; |
8f53e82a RC |
1054 | } |
1055 | } | |
1056 | return nlines - count; | |
1057 | } | |
1058 | else | |
1059 | /* contract */ | |
1060 | { | |
1061 | int count = 0, n = row + 1; | |
f557695e | 1062 | while (n < nlines & !lines[n].get_category ()) |
8f53e82a | 1063 | { |
f557695e RC |
1064 | memmove (&lines[n], &lines[n + 1], |
1065 | (nlines - n) * sizeof (pick_line)); | |
8f53e82a RC |
1066 | nlines--; |
1067 | count++; | |
1068 | } | |
42a99ed1 | 1069 | return -count; |
8f53e82a RC |
1070 | } |
1071 | } | |
1072 | } | |
1073 | ||
1074 | ||
1075 | static void | |
1076 | set_view_mode (HWND h, views mode) | |
1077 | { | |
1078 | int i; | |
1079 | chooser->set_view_mode (mode); | |
1080 | ||
1081 | chooser->clear_view (); | |
f557695e | 1082 | for (Package * pkg = package; pkg->name; pkg++) |
c46a33a9 | 1083 | if (!pkg->exclude) |
3467d79f | 1084 | set_action (pkg, 0); |
713bbe5f | 1085 | |
8f53e82a RC |
1086 | switch (chooser->get_view_mode ()) |
1087 | { | |
1088 | case VIEW_PACKAGE: | |
f557695e RC |
1089 | for (Package * pkg = package; pkg->name; pkg++) |
1090 | if (!pkg->exclude && !is_full_action (pkg)) | |
1091 | chooser->insert_pkg (pkg); | |
8f53e82a RC |
1092 | break; |
1093 | case VIEW_PACKAGE_FULL: | |
f557695e RC |
1094 | for (Package * pkg = package; pkg->name; pkg++) |
1095 | if (!pkg->exclude) | |
1096 | chooser->insert_pkg (pkg); | |
8f53e82a RC |
1097 | break; |
1098 | case VIEW_CATEGORY: | |
1099 | /* start collapsed. TODO: make this a chooser flag */ | |
f557695e | 1100 | for (Category * cat = category; cat; cat = cat->next) |
8f53e82a RC |
1101 | chooser->insert_category (cat, CATEGORY_COLLAPSED); |
1102 | break; | |
1103 | default: | |
1104 | break; | |
1105 | } | |
1106 | ||
713bbe5f DD |
1107 | RECT r; |
1108 | GetClientRect (h, &r); | |
1109 | SCROLLINFO si; | |
1110 | memset (&si, 0, sizeof (si)); | |
1111 | si.cbSize = sizeof (si); | |
1112 | si.fMask = SIF_ALL; | |
1113 | si.nMin = 0; | |
f557695e RC |
1114 | si.nMax = |
1115 | chooser->headers[chooser->last_col].x + | |
1116 | chooser->headers[chooser->last_col].width + HMARGIN; | |
713bbe5f DD |
1117 | si.nPage = r.right; |
1118 | SetScrollInfo (h, SB_HORZ, &si, TRUE); | |
1119 | ||
8f53e82a | 1120 | si.nMax = chooser->nlines * row_height; |
713bbe5f DD |
1121 | si.nPage = r.bottom - header_height; |
1122 | SetScrollInfo (h, SB_VERT, &si, TRUE); | |
1123 | ||
1124 | scroll_ulc_x = scroll_ulc_y = 0; | |
1125 | ||
1126 | InvalidateRect (h, &r, TRUE); | |
1127 | ||
1128 | if (nextbutton) | |
1129 | SetFocus (nextbutton); | |
1130 | } | |
1131 | ||
713bbe5f | 1132 | static void |
f557695e | 1133 | create_listview (HWND dlg, RECT * r) |
713bbe5f DD |
1134 | { |
1135 | int i, t; | |
1136 | lv = CreateWindowEx (WS_EX_CLIENTEDGE, | |
47f8d8b3 CF |
1137 | "listview", |
1138 | "listviewwindow", | |
1139 | WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, | |
1140 | r->left, r->top, | |
f557695e | 1141 | r->right - r->left + 1, r->bottom - r->top + 1, |
47f8d8b3 | 1142 | dlg, |
f557695e RC |
1143 | (HMENU) MAKEINTRESOURCE (IDC_CHOOSE_LIST), |
1144 | hinstance, 0); | |
713bbe5f | 1145 | ShowWindow (lv, SW_SHOW); |
713bbe5f DD |
1146 | HDC dc = GetDC (lv); |
1147 | sysfont = GetStockObject (DEFAULT_GUI_FONT); | |
1148 | SelectObject (dc, sysfont); | |
1149 | GetTextMetrics (dc, &tm); | |
1150 | header_height = tm.tmHeight + 5 + 3; | |
1151 | ||
1152 | bitmap_dc = CreateCompatibleDC (dc); | |
1153 | ||
1154 | row_height = (tm.tmHeight + tm.tmExternalLeading + ROW_MARGIN); | |
1155 | int irh = tm.tmExternalLeading + tm.tmDescent + 11 + ROW_MARGIN; | |
1156 | if (row_height < irh) | |
1157 | row_height = irh; | |
1158 | ||
8f53e82a | 1159 | chooser = new (view) (VIEW_CATEGORY, dc); |
713bbe5f | 1160 | |
713bbe5f | 1161 | default_trust (lv, TRUST_CURR); |
9307254d | 1162 | set_view_mode (lv, VIEW_CATEGORY); |
f557695e RC |
1163 | if (!SetDlgItemText (dlg, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ())) |
1164 | log (LOG_BABBLE, "Failed to set View button caption %d", GetLastError ()); | |
1165 | for (Package * foo = package; foo->name; foo++) | |
1166 | add_required (foo); | |
60c632b3 CV |
1167 | static int ta[] = { IDC_CHOOSE_CURR, 0 }; |
1168 | rbset (dlg, ta, IDC_CHOOSE_CURR); | |
d07591a3 DD |
1169 | |
1170 | ReleaseDC (lv, dc); | |
713bbe5f DD |
1171 | } |
1172 | ||
1173 | static BOOL | |
1174 | dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) | |
1175 | { | |
1176 | switch (id) | |
1177 | { | |
713bbe5f DD |
1178 | case IDC_CHOOSE_PREV: |
1179 | default_trust (lv, TRUST_PREV); | |
f557695e RC |
1180 | for (Package * foo = package; foo->name; foo++) |
1181 | add_required (foo); | |
8f53e82a | 1182 | set_view_mode (lv, chooser->get_view_mode ()); |
713bbe5f DD |
1183 | break; |
1184 | case IDC_CHOOSE_CURR: | |
1185 | default_trust (lv, TRUST_CURR); | |
f557695e RC |
1186 | for (Package * foo = package; foo->name; foo++) |
1187 | add_required (foo); | |
8f53e82a | 1188 | set_view_mode (lv, chooser->get_view_mode ()); |
713bbe5f DD |
1189 | break; |
1190 | case IDC_CHOOSE_EXP: | |
1191 | default_trust (lv, TRUST_TEST); | |
f557695e RC |
1192 | for (Package * foo = package; foo->name; foo++) |
1193 | add_required (foo); | |
8f53e82a | 1194 | set_view_mode (lv, chooser->get_view_mode ()); |
713bbe5f | 1195 | break; |
8f53e82a RC |
1196 | case IDC_CHOOSE_VIEW: |
1197 | set_view_mode (lv, viewsplusplus (chooser->get_view_mode ())); | |
f557695e RC |
1198 | if (!SetDlgItemText |
1199 | (h, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ())) | |
1200 | log (LOG_BABBLE, "Failed to set View button caption %d", | |
1201 | GetLastError ()); | |
713bbe5f DD |
1202 | break; |
1203 | ||
1204 | case IDOK: | |
1205 | if (source == IDC_SOURCE_CWD) | |
47f8d8b3 | 1206 | NEXT (IDD_S_INSTALL); |
713bbe5f | 1207 | else |
47f8d8b3 | 1208 | NEXT (IDD_S_DOWNLOAD); |
713bbe5f DD |
1209 | break; |
1210 | ||
1211 | case IDC_BACK: | |
1212 | initialized = 0; | |
1213 | if (source == IDC_SOURCE_CWD) | |
45c2d7d3 | 1214 | NEXT (IDD_LOCAL_DIR); |
713bbe5f | 1215 | else |
47f8d8b3 | 1216 | NEXT (IDD_SITE); |
713bbe5f DD |
1217 | break; |
1218 | ||
1219 | case IDCANCEL: | |
1220 | NEXT (0); | |
1221 | break; | |
1222 | } | |
1223 | } | |
23c9e63c | 1224 | |
713bbe5f | 1225 | static void |
f557695e | 1226 | GetParentRect (HWND parent, HWND child, RECT * r) |
713bbe5f DD |
1227 | { |
1228 | POINT p; | |
1229 | GetWindowRect (child, r); | |
1230 | p.x = r->left; | |
1231 | p.y = r->top; | |
1232 | ScreenToClient (parent, &p); | |
1233 | r->left = p.x; | |
1234 | r->top = p.y; | |
1235 | p.x = r->right; | |
1236 | p.y = r->bottom; | |
1237 | ScreenToClient (parent, &p); | |
1238 | r->right = p.x; | |
1239 | r->bottom = p.y; | |
1240 | } | |
1241 | ||
1242 | static BOOL CALLBACK | |
1243 | dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) | |
1244 | { | |
1245 | int i, j; | |
1246 | HWND frame; | |
1247 | RECT r; | |
1248 | switch (message) | |
1249 | { | |
1250 | case WM_INITDIALOG: | |
1251 | nextbutton = GetDlgItem (h, IDOK); | |
1252 | frame = GetDlgItem (h, IDC_LISTVIEW_POS); | |
f557695e | 1253 | choose_inst_text = GetDlgItem (h, IDC_CHOOSE_INST_TEXT); |
42bf5b92 | 1254 | if (source == IDC_SOURCE_DOWNLOAD) |
47f8d8b3 | 1255 | SetWindowText (choose_inst_text, "Select packages to download "); |
42bf5b92 | 1256 | else |
47f8d8b3 | 1257 | SetWindowText (choose_inst_text, "Select packages to install "); |
713bbe5f DD |
1258 | GetParentRect (h, frame, &r); |
1259 | r.top += 2; | |
1260 | r.bottom -= 2; | |
1261 | create_listview (h, &r); | |
1262 | #if 0 | |
1263 | load_dialog (h); | |
1264 | #endif | |
42a99ed1 | 1265 | return TRUE; |
713bbe5f DD |
1266 | case WM_COMMAND: |
1267 | return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd); | |
1268 | } | |
1269 | return FALSE; | |
1270 | } | |
1271 | ||
c46a33a9 CF |
1272 | char * |
1273 | base (const char *s) | |
5f48f258 DD |
1274 | { |
1275 | if (!s) | |
1276 | return 0; | |
c46a33a9 | 1277 | const char *rv = s; |
5f48f258 DD |
1278 | while (*s) |
1279 | { | |
1280 | if ((*s == '/' || *s == ':' || *s == '\\') && s[1]) | |
47f8d8b3 | 1281 | rv = s + 1; |
5f48f258 DD |
1282 | s++; |
1283 | } | |
c46a33a9 | 1284 | return (char *) rv; |
fb087b80 CF |
1285 | } |
1286 | ||
1287 | int | |
1288 | find_tar_ext (const char *path) | |
1289 | { | |
1290 | char *p = strchr (path, '\0') - 7; | |
1291 | if (p <= path) | |
1292 | return 0; | |
1293 | if (*p == '.') | |
1294 | { | |
1295 | if (strcmp (p, ".tar.gz") != 0) | |
47f8d8b3 | 1296 | return 0; |
60c632b3 | 1297 | } |
fb087b80 CF |
1298 | else if (--p <= path || strcmp (p, ".tar.bz2") != 0) |
1299 | return 0; | |
1300 | ||
1301 | return p - path; | |
60c632b3 | 1302 | } |
5f48f258 | 1303 | |
68b27c12 | 1304 | /* Parse a filename into package, version, and extension components. */ |
85b43844 | 1305 | int |
f557695e | 1306 | parse_filename (const char *in_fn, fileparse & f) |
4a83b7b0 | 1307 | { |
85b43844 CF |
1308 | char *p, *ver; |
1309 | char fn[strlen (in_fn) + 1]; | |
fb087b80 | 1310 | |
85b43844 CF |
1311 | strcpy (fn, in_fn); |
1312 | int n = find_tar_ext (fn); | |
fb087b80 | 1313 | |
85b43844 CF |
1314 | if (!n) |
1315 | return 0; | |
fb087b80 | 1316 | |
85b43844 CF |
1317 | strcpy (f.tail, fn + n); |
1318 | fn[n] = '\0'; | |
1319 | f.pkg[0] = f.what[0] = '\0'; | |
1320 | p = base (fn); | |
1321 | for (ver = p; *ver; ver++) | |
1322 | if (*ver == '-' || *ver == '_') | |
1323 | if (isdigit (ver[1])) | |
1324 | { | |
1325 | *ver++ = 0; | |
1326 | strcpy (f.pkg, p); | |
1327 | break; | |
1328 | } | |
1329 | else if (strcasecmp (ver, "-src") == 0 || | |
1330 | strcasecmp (ver, "-patch") == 0) | |
1331 | { | |
1332 | *ver++ = 0; | |
1333 | strcpy (f.pkg, p); | |
1334 | strcpy (f.what, strlwr (ver)); | |
1335 | strcpy (f.pkgtar, p); | |
1336 | strcat (f.pkgtar, f.tail); | |
1337 | ver = strchr (ver, '\0'); | |
1338 | break; | |
1339 | } | |
fb087b80 | 1340 | |
85b43844 CF |
1341 | if (!f.pkg[0]) |
1342 | strcpy (f.pkg, p); | |
fb087b80 | 1343 | |
85b43844 | 1344 | if (!f.what[0]) |
60c632b3 | 1345 | { |
85b43844 CF |
1346 | p = strchr (ver, '\0'); |
1347 | strcpy (f.pkgtar, in_fn); | |
1348 | if ((p -= 4) >= ver && strcasecmp (p, "-src") == 0) | |
47f8d8b3 | 1349 | { |
85b43844 CF |
1350 | strcpy (f.what, "src"); |
1351 | *p = '\0'; | |
1352 | p = f.pkgtar + (p - fn) + 4; | |
1353 | memcpy (p - 4, p, strlen (p)); | |
47f8d8b3 | 1354 | } |
85b43844 | 1355 | else if ((p -= 2) >= ver && strcasecmp (p, "-patch") == 0) |
47f8d8b3 | 1356 | { |
85b43844 CF |
1357 | strcpy (f.what, "patch"); |
1358 | *p = '\0'; | |
1359 | p = f.pkgtar + (p - fn) + 6; | |
1360 | memcpy (p - 6, p, strlen (p)); | |
47f8d8b3 | 1361 | } |
60c632b3 | 1362 | } |
85b43844 CF |
1363 | |
1364 | strcpy (f.ver, *ver ? ver : "0.0"); | |
1365 | return 1; | |
1366 | } | |
1367 | ||
68b27c12 | 1368 | /* Return a pointer to a package given the name. */ |
c46a33a9 CF |
1369 | Package * |
1370 | getpkgbyname (const char *pkgname) | |
1371 | { | |
f557695e | 1372 | for (Package * pkg = package; pkg->name; pkg++) |
9c0a9876 CF |
1373 | if (strcasecmp (pkg->name, pkgname) == 0) |
1374 | return pkg; | |
c46a33a9 CF |
1375 | |
1376 | return NULL; | |
1377 | } | |
1378 | ||
8f53e82a RC |
1379 | /* Return a pointer to a category given the name. */ |
1380 | Category * | |
1381 | getcategorybyname (const char *categoryname) | |
1382 | { | |
f557695e | 1383 | for (Category * cat = category; cat; cat = cat->next) |
8f53e82a RC |
1384 | if (strcasecmp (cat->name, categoryname) == 0) |
1385 | return cat; | |
1386 | ||
1387 | return NULL; | |
1388 | } | |
1389 | ||
1390 | /* Return a pointer to a category of a given package given the name. */ | |
1391 | Category * | |
f557695e | 1392 | getpackagecategorybyname (Package * pkg, const char *categoryname) |
8f53e82a | 1393 | { |
f557695e | 1394 | for (Category * cat = pkg->category; cat; cat = cat->next) |
8f53e82a RC |
1395 | if (strcasecmp (cat->name, categoryname) == 0) |
1396 | return cat; | |
1397 | ||
1398 | return NULL; | |
1399 | } | |
1400 | ||
1b13eeec CF |
1401 | /* Find out where to put existing tar file in local directory in |
1402 | known package array. */ | |
85b43844 CF |
1403 | static void |
1404 | scan2 (char *path, unsigned int size) | |
1405 | { | |
1406 | Package *pkg; | |
1407 | fileparse f; | |
1408 | ||
1409 | if (!parse_filename (path, f)) | |
1410 | return; | |
1411 | ||
2dada532 | 1412 | if (f.what[0] != '\0' && f.what[0] != 's') |
85b43844 CF |
1413 | return; |
1414 | ||
c46a33a9 CF |
1415 | pkg = getpkgbyname (f.pkg); |
1416 | if (pkg == NULL) | |
85b43844 CF |
1417 | return; |
1418 | ||
1b13eeec CF |
1419 | /* Scan existing package list looking for a match between a known |
1420 | package from setup.ini and a tar archive on disk. | |
1421 | While scanning, keep track of appropriate "holes" in the trust | |
1422 | table where a tar file could be put if no known entry | |
1423 | exists. | |
1424 | ||
1425 | So, if setup.ini knows that ash-20010425-1.tar.gz is the current | |
1426 | version and there is an ash-20010426-1.tar.gz in the current directory, | |
1427 | the 20010426 version will be placed in the "test" slot, assuming that | |
1428 | there is no test version listed in setup.ini. */ | |
1429 | ||
80429b97 | 1430 | Info *hole = NULL; |
1b13eeec CF |
1431 | Info *maybe_hole = NULL; |
1432 | int cmp = 0; | |
f557695e | 1433 | for (Info * inf = pkg->infoscan; inf < pkg->infoend; inf++) |
1b13eeec CF |
1434 | if (!inf->version || inf->derived) |
1435 | { | |
1436 | if (cmp > 0) | |
1437 | hole = inf; | |
f54385f6 | 1438 | else if (cmp == 0) |
1b13eeec CF |
1439 | maybe_hole = inf; |
1440 | } | |
1441 | else if ((cmp = strcasecmp (f.ver, inf->version)) == 0) | |
c46a33a9 CF |
1442 | { |
1443 | if (f.what[0] == 's') | |
1444 | inf->source_exists = -1; | |
1445 | else | |
1446 | inf->install_exists = -1; | |
1447 | return; | |
1448 | } | |
1b13eeec CF |
1449 | else if (!hole && maybe_hole && cmp < 0) |
1450 | hole = maybe_hole; | |
1451 | else | |
1452 | maybe_hole = NULL; | |
1453 | ||
1454 | /* If maybe_hole != NULL, then we should be sitting at the "test" | |
1455 | trust entry. Use that if there was nothing at all in the | |
1456 | known package list. */ | |
1457 | if (!hole && maybe_hole) | |
1458 | hole = maybe_hole; | |
1459 | ||
1460 | /* If !hole, we didn't find this version in the known packages array | |
1461 | and there was no place to put it. */ | |
1462 | if (!hole) | |
1463 | return; | |
c46a33a9 | 1464 | |
1b13eeec CF |
1465 | /* The derived flag is set when we place info about a file in a slot |
1466 | iff there was nothing known about the file in the known package | |
1467 | array. We try to put the highest numbered versions in the "empty" | |
1468 | slots. */ | |
1469 | if (hole->derived) | |
80429b97 | 1470 | { |
1b13eeec CF |
1471 | cmp = strcasecmp (f.ver, hole->version) < 0; |
1472 | if (cmp < 0) | |
1473 | return; | |
1474 | ||
1475 | if (cmp > 0) | |
80429b97 | 1476 | { |
1b13eeec CF |
1477 | free (hole->version); |
1478 | if (hole->source) | |
1479 | free (hole->source); | |
1480 | else | |
1481 | free (hole->install); | |
80429b97 CF |
1482 | } |
1483 | } | |
1b13eeec CF |
1484 | |
1485 | /* Fill in the "hole", setting a flag that we derived this location | |
1486 | from context rather than from setup.ini. */ | |
1487 | hole->derived = 1; | |
1488 | hole->version = strdup (f.ver); | |
1489 | if (!hole->source && f.what[0] == 's') | |
1490 | { | |
1491 | hole->source = strdup (path); | |
1492 | hole->source_exists = -1; | |
1493 | hole->source_size = size; | |
1494 | } | |
1495 | else | |
1496 | { | |
1497 | hole->install = strdup (path); | |
1498 | hole->install_exists = -1; | |
1499 | hole->install_size = size; | |
1500 | } | |
4a83b7b0 DD |
1501 | } |
1502 | ||
1503 | static void | |
1504 | scan_downloaded_files () | |
1505 | { | |
1506 | find (".", scan2); | |
1507 | } | |
1508 | ||
3ae6c15c | 1509 | _Info::_Info (const char *_install, const char *_version, int _install_size, |
f557695e | 1510 | const char *_source, int _source_size) |
3ae6c15c CF |
1511 | { |
1512 | memset (this, 0, sizeof (*this)); | |
1513 | install = strdup (_install); | |
1514 | version = strdup (_version); | |
1515 | install_size = _install_size; | |
86202506 | 1516 | if (_source) |
3ae6c15c | 1517 | { |
86202506 | 1518 | source = strdup (_source); |
3ae6c15c CF |
1519 | source_size = _source_size; |
1520 | } | |
1521 | } | |
1522 | ||
713bbe5f DD |
1523 | static void |
1524 | read_installed_db () | |
1525 | { | |
1526 | int i; | |
85b43844 | 1527 | if (!get_root_dir ()) |
713bbe5f DD |
1528 | return; |
1529 | ||
c46a33a9 | 1530 | char line[1000], pkgname[1000], inst[1000], src[1000]; |
713bbe5f DD |
1531 | int instsz, srcsz; |
1532 | ||
a351e48c | 1533 | FILE *db = fopen (cygpath ("/etc/setup/installed.db", 0), "rt"); |
713bbe5f DD |
1534 | if (!db) |
1535 | return; | |
1536 | ||
1537 | while (fgets (line, 1000, db)) | |
1538 | { | |
c46a33a9 | 1539 | int parseable; |
713bbe5f DD |
1540 | src[0] = 0; |
1541 | srcsz = 0; | |
c46a33a9 | 1542 | sscanf (line, "%s %s %d %s %d", pkgname, inst, &instsz, src, &srcsz); |
713bbe5f | 1543 | |
c46a33a9 CF |
1544 | Package *pkg = getpkgbyname (pkgname); |
1545 | fileparse f; | |
1546 | parseable = parse_filename (inst, f); | |
1547 | ||
1548 | if (pkg == NULL) | |
1549 | { | |
1550 | if (!parseable) | |
1551 | continue; | |
1552 | pkg = new_package (pkgname); | |
1553 | pkg->info[TRUST_CURR].version = strdup (f.ver); | |
1554 | pkg->info[TRUST_CURR].install = strdup (inst); | |
1555 | pkg->info[TRUST_CURR].install_size = instsz; | |
f97a1ece | 1556 | if (src[0] && srcsz) |
c46a33a9 CF |
1557 | { |
1558 | pkg->info[TRUST_CURR].source = strdup (src); | |
1559 | pkg->info[TRUST_CURR].source_size = srcsz; | |
1560 | } | |
1561 | pkg->installed_ix = TRUST_CURR; | |
e98d90bd CF |
1562 | /* Exists on local system but not on download system */ |
1563 | pkg->exclude = EXCLUDE_NOT_FOUND; | |
c46a33a9 CF |
1564 | } |
1565 | ||
3ae6c15c | 1566 | pkg->installed = new Info (inst, f.ver, instsz); |
c46a33a9 CF |
1567 | |
1568 | if (!pkg->installed_ix) | |
3ae6c15c | 1569 | for (trusts t = TRUST_PREV; t < NTRUST; ((int) t)++) |
f557695e RC |
1570 | if (pkg->info[t].install |
1571 | && strcmp (f.ver, pkg->info[t].version) == 0) | |
c46a33a9 CF |
1572 | { |
1573 | pkg->installed_ix = t; | |
1574 | break; | |
1575 | } | |
23c9e63c | 1576 | } |
713bbe5f DD |
1577 | fclose (db); |
1578 | } | |
1579 | ||
1b1b33ac DD |
1580 | int |
1581 | package_sort (const void *va, const void *vb) | |
1582 | { | |
f557695e RC |
1583 | Package *a = (Package *) va; |
1584 | Package *b = (Package *) vb; | |
8f53e82a | 1585 | return strcasecmp (a->name, b->name); |
1b1b33ac DD |
1586 | } |
1587 | ||
713bbe5f DD |
1588 | void |
1589 | do_choose (HINSTANCE h) | |
1590 | { | |
c46a33a9 | 1591 | int rv; |
713bbe5f DD |
1592 | |
1593 | nextbutton = 0; | |
1594 | bm_spin = LoadImage (h, MAKEINTRESOURCE (IDB_SPIN), IMAGE_BITMAP, 0, 0, 0); | |
f557695e | 1595 | bm_rtarrow = LoadImage (h, MAKEINTRESOURCE (IDB_RTARROW), IMAGE_BITMAP, |
1fb09149 | 1596 | 0, 0, 0); |
713bbe5f | 1597 | |
26a27c14 | 1598 | bm_checkyes = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_YES), IMAGE_BITMAP, |
1fb09149 | 1599 | 0, 0, 0); |
26a27c14 | 1600 | bm_checkno = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_NO), IMAGE_BITMAP, |
f557695e | 1601 | 0, 0, 0); |
26a27c14 | 1602 | bm_checkna = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_NA), IMAGE_BITMAP, |
f557695e | 1603 | 0, 0, 0); |
3b9077d4 | 1604 | |
713bbe5f DD |
1605 | register_windows (h); |
1606 | ||
60c632b3 | 1607 | if (source == IDC_SOURCE_DOWNLOAD || source == IDC_SOURCE_CWD) |
4a83b7b0 | 1608 | scan_downloaded_files (); |
fb087b80 | 1609 | |
60c632b3 CV |
1610 | read_installed_db (); |
1611 | set_existence (); | |
8f53e82a | 1612 | fill_missing_category (); |
713bbe5f | 1613 | |
e98d90bd CF |
1614 | qsort (package, npackages, sizeof (package[0]), package_sort); |
1615 | ||
713bbe5f DD |
1616 | rv = DialogBox (h, MAKEINTRESOURCE (IDD_CHOOSE), 0, dialog_proc); |
1617 | if (rv == -1) | |
1618 | fatal (IDS_DIALOG_FAILED); | |
1619 | ||
89b1a15b | 1620 | log (LOG_BABBLE, "Chooser results..."); |
f557695e | 1621 | for (Package * pkg = package; pkg->name; pkg++) |
89b1a15b | 1622 | { |
f557695e | 1623 | static char *infos[] = { "nada", "prev", "curr", "test" }; |
c46a33a9 CF |
1624 | const char *trust = ((pkg->trust == TRUST_PREV) ? "prev" |
1625 | : (pkg->trust == TRUST_CURR) ? "curr" | |
f557695e | 1626 | : (pkg->trust == TRUST_TEST) ? "test" : "unknown"); |
c46a33a9 CF |
1627 | const char *action = choose_caption (pkg); |
1628 | const char *installed = ((pkg->installed_ix == -1) ? "none" | |
1629 | : (pkg->installed_ix == TRUST_PREV) ? "prev" | |
1630 | : (pkg->installed_ix == TRUST_CURR) ? "curr" | |
1631 | : (pkg->installed_ix == TRUST_TEST) ? "test" | |
47f8d8b3 | 1632 | : "unknown"); |
c46a33a9 | 1633 | const char *excluded = (pkg->exclude ? "yes" : "no"); |
89b1a15b | 1634 | |
2dada532 CF |
1635 | log (LOG_BABBLE, "[%s] action=%s trust=%s installed=%s excluded=%s" |
1636 | " src?=%s", | |
1637 | pkg->name, action, trust, installed, excluded, | |
1638 | pkg->srcpicked ? "yes" : "no"); | |
1639 | if (pkg->category) | |
1640 | { | |
1641 | /* List categories the package belongs to */ | |
1642 | char *categories = ""; | |
f557695e | 1643 | int categories_len = 0; |
2dada532 CF |
1644 | Category *cp; |
1645 | for (cp = pkg->category; cp; cp = cp->next) | |
1646 | if (cp->name) | |
1647 | categories_len += strlen (cp->name) + 2; | |
1648 | ||
1649 | if (categories_len > 0) | |
1650 | { | |
1651 | categories = (char *) malloc (categories_len); | |
f557695e | 1652 | strcpy (categories, pkg->category->name); |
2dada532 CF |
1653 | for (cp = pkg->category->next; cp; cp = cp->next) |
1654 | if (cp->name) | |
1655 | { | |
1656 | strcat (categories, ", "); | |
1657 | strcat (categories, cp->name); | |
1658 | } | |
1659 | log (LOG_BABBLE, " categories=%s", categories); | |
1660 | free (categories); | |
1661 | } | |
1662 | } | |
1663 | if (pkg->required) | |
1664 | { | |
1665 | /* List other packages this package depends on */ | |
1666 | char *requires = ""; | |
f557695e | 1667 | int requires_len = 0; |
2dada532 CF |
1668 | Dependency *dp; |
1669 | for (dp = pkg->required; dp; dp = dp->next) | |
1670 | if (dp->package) | |
1671 | requires_len += strlen (dp->package) + 2; | |
1672 | ||
1673 | if (requires_len > 0) | |
1674 | { | |
1675 | requires = (char *) malloc (requires_len); | |
f557695e | 1676 | strcpy (requires, pkg->required->package); |
2dada532 CF |
1677 | for (dp = pkg->required->next; dp; dp = dp->next) |
1678 | if (dp->package) | |
1679 | { | |
1680 | strcat (requires, ", "); | |
1681 | strcat (requires, dp->package); | |
1682 | } | |
1683 | log (LOG_BABBLE, " requires=%s", requires); | |
1684 | free (requires); | |
1685 | } | |
1686 | } | |
1687 | ||
c46a33a9 | 1688 | for (int t = 1; t < NTRUST; t++) |
47f8d8b3 | 1689 | { |
c46a33a9 | 1690 | if (pkg->info[t].install) |
2dada532 | 1691 | log (LOG_BABBLE, " [%s] ver=%s\n" |
f557695e RC |
1692 | " inst=%s %d exists=%s\n" |
1693 | " src=%s %d exists=%s", | |
47f8d8b3 | 1694 | infos[t], |
f557695e RC |
1695 | pkg->info[t].version ? : "(none)", |
1696 | pkg->info[t].install ? : "(none)", | |
c46a33a9 | 1697 | pkg->info[t].install_size, |
3467d79f | 1698 | (pkg->info[t].install_exists) ? "yes" : "no", |
f557695e | 1699 | pkg->info[t].source ? : "(none)", |
c46a33a9 | 1700 | pkg->info[t].source_size, |
2dada532 | 1701 | (pkg->info[t].source_exists) ? "yes" : "no"); |
47f8d8b3 | 1702 | } |
89b1a15b | 1703 | } |
713bbe5f | 1704 | } |