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