]> cygwin.com Git - cygwin-apps/setup.git/blob - choose.cc
2002-01-09 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / choose.cc
1 /*
2 * Copyright (c) 2000, 2001 Red Hat, Inc.
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
28 #if 0
29 static const char *cvsid =
30 "\n%%% $Id$\n";
31 #endif
32
33 #include "win32.h"
34 #include <commctrl.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <io.h>
38 #include <ctype.h>
39 #include <process.h>
40
41 #include "dialog.h"
42 #include "resource.h"
43 #include "state.h"
44 #include "ini.h"
45 #include "concat.h"
46 #include "msg.h"
47 #include "log.h"
48 #include "find.h"
49 #include "filemanip.h"
50 #include "io_stream.h"
51 #include "propsheet.h"
52 #include "choose.h"
53 #include "category.h"
54
55 #include "package_db.h"
56 #include "package_meta.h"
57 #include "package_version.h"
58
59 #include "port.h"
60 #include "threebar.h"
61 extern ThreeBarProgressPage Progress;
62
63 #define alloca __builtin_alloca
64
65 #define HMARGIN 10
66 #define ROW_MARGIN 5
67 #define ICON_MARGIN 4
68 #define RTARROW_WIDTH 11
69 #define SPIN_WIDTH 11
70 #define NEW_COL_SIZE_SLOP (ICON_MARGIN + SPIN_WIDTH + RTARROW_WIDTH)
71
72 #define CHECK_SIZE 11
73
74 static int initialized = 0;
75
76 static int scroll_ulc_x, scroll_ulc_y;
77
78 static HWND lv, nextbutton, choose_inst_text;
79 static TEXTMETRIC tm;
80 static int header_height;
81 static HANDLE sysfont;
82 static int row_height;
83 static HANDLE bm_spin, bm_rtarrow, bm_checkyes, bm_checkno, bm_checkna;
84 static HDC bitmap_dc;
85 static view *chooser = NULL;
86 static trusts deftrust = TRUST_UNKNOWN;
87
88 static struct _header pkg_headers[] = {
89 {"Current", 7, 0, 0},
90 {"New", 3, 0, 0},
91 {"Src?", 4, 0, 0},
92 {"Category", 8, 0, 0},
93 {"Package", 7, 0, 0},
94 {0, 0, 0, 0}
95 };
96
97 static struct _header cat_headers[] = {
98 {"Category", 8, 0, 0},
99 {"Current", 7, 0, 0},
100 {"New", 3, 0, 0},
101 {"Src?", 4, 0, 0},
102 {"Package", 7, 0, 0},
103 {0, 0, 0, 0}
104 };
105
106 static void set_view_mode (HWND h, views mode);
107
108 packageversion *
109 pkgtrustp (packagemeta const &pkg, trusts const t)
110 {
111 return t == TRUST_PREV ? (pkg.prev ? pkg.prev : (pkg.curr ? pkg.curr : pkg.installed))
112 : t == TRUST_CURR ? (pkg.curr ? pkg.curr : pkg.installed)
113 : pkg.exp;
114 }
115
116 static int
117 add_required (packagemeta & pkg, size_t depth = 0)
118 {
119 Dependency *dp;
120 packagemeta *required;
121 int changed = 0;
122 if (!pkg.desired
123 || (pkg.desired != pkg.installed && !pkg.desired->binpicked))
124 /* uninstall || source only */
125 return 0;
126
127 dp = pkg.desired->required;
128 packagedb db;
129 /* cheap test for too much recursion */
130 if (depth > 5)
131 return 0;
132 while (dp)
133 {
134 if ((required = db.packages.getbykey (dp->package)) == NULL)
135 {
136 dp = dp->next;
137 changed++;
138 continue;
139 }
140 if (!required->desired)
141 {
142 /* it's set to uninstall */
143 required->set_action (pkgtrustp (*required, deftrust));
144 }
145 else if (required->desired != required->installed
146 && !required->desired->binpicked)
147 {
148 /* it's set to change to a different version source only */
149 required->desired->binpicked = 1;
150 }
151 /* does this requirement have requirements? */
152 changed += add_required (*required, depth + 1);
153 dp = dp->next;
154 }
155 return changed;
156 }
157
158 void
159 topbucket::paint (HDC hdc, int x, int y, int row, int show_cat)
160 {
161 int accum_row = row;
162 for (size_t n = 1; n <= bucket.number (); n++)
163 {
164 bucket[n]->paint (hdc, x, y, accum_row, show_cat);
165 accum_row += bucket[n]->itemcount ();
166 }
167 }
168
169 void
170 topbucket::empty (void)
171 {
172 while (bucket.number ())
173 {
174 pick_line *line = bucket.removebyindex (1);
175 delete line;
176 }
177 }
178
179 topbucket::~topbucket (void)
180 {
181 empty ();
182 }
183
184 int
185 topbucket::click (int const myrow, int const ClickedRow, int const x)
186 {
187 int accum_row = myrow;
188 for (size_t n = 1; n <= bucket.number (); n++)
189 {
190 accum_row += bucket[n]->itemcount ();
191 if (accum_row > ClickedRow)
192 return bucket[n]->click (accum_row - bucket[n]->itemcount (),
193 ClickedRow, x);
194 }
195 return 0;
196 }
197
198 static void
199 paint (HWND hwnd)
200 {
201 HDC hdc;
202 PAINTSTRUCT ps;
203 int x, y;
204
205 hdc = BeginPaint (hwnd, &ps);
206
207 SelectObject (hdc, sysfont);
208 SetBkColor (hdc, GetSysColor (COLOR_WINDOW));
209 SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT));
210
211 RECT cr;
212 GetClientRect (hwnd, &cr);
213
214 x = cr.left - scroll_ulc_x;
215 y = cr.top - scroll_ulc_y + header_height;
216
217 IntersectClipRect (hdc, cr.left, cr.top + header_height, cr.right,
218 cr.bottom);
219
220 chooser->contents.paint (hdc, x, y, 0, (chooser->get_view_mode () ==
221 VIEW_CATEGORY) ? 0 : 1);
222
223 if (chooser->contents.itemcount () == 0)
224 {
225 static const char *msg = "Nothing to Install/Update";
226 if (source == IDC_SOURCE_DOWNLOAD)
227 msg = "Nothing to Download";
228 TextOut (hdc, HMARGIN, header_height, msg, strlen (msg));
229 }
230
231 EndPaint (hwnd, &ps);
232 }
233
234 void
235 view::scroll (HWND hwnd, int which, int *var, int code)
236 {
237 SCROLLINFO si;
238 si.cbSize = sizeof (si);
239 si.fMask = SIF_ALL;
240 GetScrollInfo (hwnd, which, &si);
241
242 switch (code)
243 {
244 case SB_THUMBTRACK:
245 si.nPos = si.nTrackPos;
246 break;
247 case SB_THUMBPOSITION:
248 break;
249 case SB_BOTTOM:
250 si.nPos = si.nMax;
251 break;
252 case SB_TOP:
253 si.nPos = 0;
254 break;
255 case SB_LINEDOWN:
256 si.nPos += row_height;
257 break;
258 case SB_LINEUP:
259 si.nPos -= row_height;
260 break;
261 case SB_PAGEDOWN:
262 si.nPos += si.nPage * 9 / 10;
263 break;
264 case SB_PAGEUP:
265 si.nPos -= si.nPage * 9 / 10;
266 break;
267 }
268
269 if ((int) si.nPos < 0)
270 si.nPos = 0;
271 if (si.nPos + si.nPage > (unsigned int) si.nMax)
272 si.nPos = si.nMax - si.nPage;
273
274 si.fMask = SIF_POS;
275 SetScrollInfo (hwnd, which, &si, TRUE);
276
277 int ox = scroll_ulc_x;
278 int oy = scroll_ulc_y;
279 *var = si.nPos;
280
281 RECT cr, sr;
282 GetClientRect (hwnd, &cr);
283 sr = cr;
284 sr.top += header_height;
285 UpdateWindow (hwnd);
286 ScrollWindow (hwnd, ox - scroll_ulc_x, oy - scroll_ulc_y, &sr, &sr);
287 /*
288 sr.bottom = sr.top;
289 sr.top = cr.top;
290 ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
291 */
292 if (ox - scroll_ulc_x)
293 {
294 GetClientRect (listheader, &cr);
295 sr = cr;
296 // UpdateWindow (htmp);
297 MoveWindow (listheader, -scroll_ulc_x, 0,
298 chooser->headers[last_col].x +
299 chooser->headers[last_col].width, header_height, TRUE);
300 }
301 UpdateWindow (hwnd);
302 }
303
304 static LRESULT CALLBACK
305 list_vscroll (HWND hwnd, HWND hctl, UINT code, int pos)
306 {
307 chooser->scroll (hwnd, SB_VERT, &scroll_ulc_y, code);
308 return 0;
309 }
310
311 static LRESULT CALLBACK
312 list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos)
313 {
314 chooser->scroll (hwnd, SB_HORZ, &scroll_ulc_x, code);
315 return 0;
316 }
317
318 static LRESULT CALLBACK
319 list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode)
320 {
321 int row, refresh;
322
323 if (chooser->contents.itemcount () == 0)
324 return 0;
325
326 if (y < header_height)
327 return 0;
328 x += scroll_ulc_x;
329 y += scroll_ulc_y - header_height;
330
331 row = (y + ROW_MARGIN / 2) / row_height;
332
333 if (row < 0 || row >= chooser->contents.itemcount ())
334 return 0;
335
336 refresh = chooser->click (row, x);
337
338 if (refresh)
339 {
340 RECT r;
341 GetClientRect (lv, &r);
342 SCROLLINFO si;
343 memset (&si, 0, sizeof (si));
344 si.cbSize = sizeof (si);
345 si.fMask = SIF_ALL; /* SIF_RANGE was giving strange behaviour */
346 si.nMin = 0;
347
348 si.nMax = chooser->contents.itemcount () * row_height;
349 si.nPage = r.bottom - header_height;
350
351 /* if we are under the minimum display count ,
352 * set the offset to 0
353 */
354 if ((unsigned int) si.nMax <= si.nPage)
355 scroll_ulc_y = 0;
356 si.nPos = scroll_ulc_y;
357
358 SetScrollInfo (lv, SB_VERT, &si, TRUE);
359
360 InvalidateRect (lv, &r, TRUE);
361
362 }
363 else
364 {
365 RECT rect;
366 rect.left = chooser->headers[chooser->new_col].x - scroll_ulc_x;
367 rect.right = chooser->headers[chooser->src_col + 1].x - scroll_ulc_x;
368 rect.top = header_height + row * row_height - scroll_ulc_y;
369 rect.bottom = rect.top + row_height;
370 InvalidateRect (hwnd, &rect, TRUE);
371 }
372 return 0;
373 }
374
375 static LRESULT CALLBACK
376 listview_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
377 {
378 switch (message)
379 {
380 case WM_HSCROLL:
381 return HANDLE_WM_HSCROLL (hwnd, wParam, lParam, list_hscroll);
382 case WM_VSCROLL:
383 return HANDLE_WM_VSCROLL (hwnd, wParam, lParam, list_vscroll);
384 case WM_LBUTTONDOWN:
385 return HANDLE_WM_LBUTTONDOWN (hwnd, wParam, lParam, list_click);
386 case WM_PAINT:
387 paint (hwnd);
388 return 0;
389 case WM_NOTIFY:
390 {
391 // pnmh = (LPNMHDR) lParam
392 LPNMHEADER phdr = (LPNMHEADER) lParam;
393 switch (phdr->hdr.code)
394 {
395 case HDN_ITEMCHANGED:
396 if (phdr->hdr.hwndFrom == chooser->ListHeader ())
397 {
398 if (phdr->pitem && phdr->pitem->mask & HDI_WIDTH)
399 chooser->headers[phdr->iItem].width = phdr->pitem->cxy;
400 for (int i = 1; i <= chooser->last_col; i++)
401 chooser->headers[i].x =
402 chooser->headers[i - 1].x + chooser->headers[i - 1].width;
403 RECT r;
404 GetClientRect (hwnd, &r);
405 SCROLLINFO si;
406 si.cbSize = sizeof (si);
407 si.fMask = SIF_ALL;
408 GetScrollInfo (hwnd, SB_HORZ, &si);
409 int oldMax = si.nMax;
410 si.nMax =
411 chooser->headers[chooser->last_col].x +
412 chooser->headers[chooser->last_col].width;
413 if (si.nTrackPos && oldMax > si.nMax)
414 si.nTrackPos += si.nMax - oldMax;
415 si.nPage = r.right;
416 SetScrollInfo (hwnd, SB_HORZ, &si, TRUE);
417 InvalidateRect (hwnd, &r, TRUE);
418 if (si.nTrackPos && oldMax > si.nMax)
419 chooser->scroll (hwnd, SB_HORZ, &scroll_ulc_x,
420 SB_THUMBTRACK);
421 }
422 break;
423 default:
424 break;
425 }
426 }
427 default:
428 return DefWindowProc (hwnd, message, wParam, lParam);
429 }
430 }
431
432 static void
433 register_windows (HINSTANCE hinst)
434 {
435 WNDCLASSEX wcex;
436 static int done = 0;
437
438 if (done)
439 return;
440 done = 1;
441
442 memset (&wcex, 0, sizeof (wcex));
443 wcex.cbSize = sizeof (WNDCLASSEX);
444 wcex.style = CS_HREDRAW | CS_VREDRAW;
445 wcex.lpfnWndProc = listview_proc;
446 wcex.hInstance = hinst;
447 wcex.hIcon = LoadIcon (0, IDI_APPLICATION);
448 wcex.hCursor = LoadCursor (0, IDC_ARROW);
449 wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
450 wcex.lpszClassName = "listview";
451
452 RegisterClassEx (&wcex);
453 }
454
455 static void
456 note_width (struct _header *hdrs, HDC dc, const char *string, int addend,
457 int column)
458 {
459 if (!string)
460 {
461 if (hdrs[column].width < addend)
462 hdrs[column].width = addend;
463 return;
464 }
465 SIZE s;
466 GetTextExtentPoint32 (dc, string, strlen (string), &s);
467 if (hdrs[column].width < s.cx + addend)
468 hdrs[column].width = s.cx + addend;
469 }
470
471 static void
472 set_existence ()
473 {
474 packagedb db;
475 /* Remove packages that are in the db, not installed, and have no
476 mirror info. */
477 size_t n = 1;
478 while (n <= db.packages.number ())
479 {
480 packagemeta & pkg = *db.packages[n];
481 bool mirrors = false;
482 size_t o = 1;
483 while (o <= pkg.versions.number () && !mirrors)
484 {
485 packageversion & ver = *pkg.versions[o];
486 if (ver.bin.sites.number () || ver.bin.Cached () ||
487 ver.src.sites.number () || ver.src.Cached ())
488 mirrors = true;
489 ++o;
490 }
491 if (!pkg.installed && !mirrors)
492 {
493 packagemeta * pkgm = db.packages.removebyindex (n);
494 delete pkgm;
495 }
496 else
497 ++n;
498 }
499 }
500
501 static void
502 fill_missing_category ()
503 {
504 packagedb db;
505 for (size_t n = 1; n <= db.packages.number (); n++)
506 {
507 packagemeta & pkg = *db.packages[n];
508 if (!pkg.Categories.number ())
509 pkg.add_category (db.categories.registerbykey ("Misc"));
510 pkg.add_category (db.categories.registerbykey ("All"));
511 }
512 }
513
514 static void
515 default_trust (HWND h, trusts trust)
516 {
517 deftrust = trust;
518 packagedb db;
519 for (size_t n = 1; n <= db.packages.number (); n++)
520 {
521 packagemeta & pkg = *db.packages[n];
522 if (pkg.installed
523 || pkg.Categories.getbykey (db.categories.registerbykey ("Base"))
524 || pkg.Categories.getbykey (db.categories.registerbykey ("Misc")))
525 {
526 pkg.desired = pkgtrustp (pkg, trust);
527 if (pkg.desired)
528 {
529 pkg.desired->binpicked = pkg.desired == pkg.installed ? 0 : 1;
530 pkg.desired->srcpicked = 0;
531 }
532 }
533 else
534 pkg.desired = 0;
535 }
536 RECT r;
537 GetClientRect (h, &r);
538 InvalidateRect (h, &r, TRUE);
539 if (nextbutton)
540 SetFocus (nextbutton);
541 // and then do the same for categories with no packages.
542 size_t n = 1;
543 while (n <= db.categories.number ())
544 {
545 if (!db.categories[n]->packages)
546 {
547 Category * cat = db.categories.removebyindex (n);
548 delete cat;
549 }
550 else
551 ++n;
552 }
553 }
554
555 void
556 pick_pkg_line::paint (HDC hdc, int x, int y, int row, int show_cat)
557 {
558 int r = y + row * row_height;
559 int by = r + tm.tmHeight - 11;
560 int oldDC = SaveDC (hdc);
561 if (!oldDC)
562 return;
563 HRGN oldClip = CreateRectRgn (0, 0, 0, 0);
564 if (GetRandomRgn (hdc, oldClip, SYSRGN) == -1)
565 {
566 RestoreDC (hdc, oldDC);
567 return;
568 }
569 unsigned int regionsize = GetRegionData (oldClip, 0, 0);
570 LPRGNDATA oldClipData = (LPRGNDATA) malloc (regionsize);
571 if (GetRegionData (oldClip, regionsize, oldClipData) != regionsize)
572 {
573 RestoreDC (hdc, oldDC);
574 DeleteObject (oldClip);
575 return;
576 }
577 for (unsigned int n = 0; n < oldClipData->rdh.nCount; n++)
578 for (unsigned int t = 0; t < 2; t++)
579 ScreenToClient (WindowFromDC (hdc),
580 &((POINT *) oldClipData->Buffer)[t + n * 2]);
581
582 HRGN oldClip2 = ExtCreateRegion (NULL, regionsize, oldClipData);
583 SelectClipRgn (hdc, oldClip2);
584 if (pkg.installed)
585 {
586 IntersectClipRect (hdc, x + chooser->headers[chooser->current_col].x,
587 by,
588 x + chooser->headers[chooser->current_col].x +
589 chooser->headers[chooser->current_col].width,
590 by + 11);
591 TextOut (hdc,
592 x + chooser->headers[chooser->current_col].x + HMARGIN / 2, r,
593 pkg.installed->Canonical_version (),
594 strlen (pkg.installed->Canonical_version ()));
595 SelectObject (bitmap_dc, bm_rtarrow);
596 BitBlt (hdc, x + chooser->headers[chooser->new_col].x + HMARGIN / 2,
597 by, 11, 11, bitmap_dc, 0, 0, SRCCOPY);
598 SelectClipRgn (hdc, oldClip2);
599 }
600
601 const char *s = pkg.action_caption ();
602 IntersectClipRect (hdc, x + chooser->headers[chooser->new_col].x,
603 by,
604 x + chooser->headers[chooser->new_col].x +
605 chooser->headers[chooser->new_col].width, by + 11);
606 TextOut (hdc,
607 x + chooser->headers[chooser->new_col].x + HMARGIN / 2 +
608 NEW_COL_SIZE_SLOP, r, s, strlen (s));
609 SelectObject (bitmap_dc, bm_spin);
610 BitBlt (hdc,
611 x + chooser->headers[chooser->new_col].x + ICON_MARGIN / 2 +
612 RTARROW_WIDTH + HMARGIN / 2, by, 11, 11, bitmap_dc, 0, 0, SRCCOPY);
613 SelectClipRgn (hdc, oldClip2);
614
615 HANDLE check_bm;
616 if ( /* uninstall */ !pkg.desired ||
617 /* source only */ (!pkg.desired->binpicked
618 && pkg.desired->srcpicked) ||
619 /* when no source mirror available */
620 !pkg.desired->src.sites.number ())
621 check_bm = bm_checkna;
622 else if (pkg.desired->srcpicked)
623 check_bm = bm_checkyes;
624 else
625 check_bm = bm_checkno;
626
627 SelectObject (bitmap_dc, check_bm);
628 IntersectClipRect (hdc, x + chooser->headers[chooser->src_col].x, by,
629 x + chooser->headers[chooser->src_col].x +
630 chooser->headers[chooser->src_col].width, by + 11);
631 BitBlt (hdc, x + chooser->headers[chooser->src_col].x + HMARGIN / 2, by, 11,
632 11, bitmap_dc, 0, 0, SRCCOPY);
633 SelectClipRgn (hdc, oldClip2);
634
635 /* shows "first" category - do we want to show any? */
636 if (pkg.Categories.number () && show_cat)
637 {
638 IntersectClipRect (hdc, x + chooser->headers[chooser->cat_col].x, by,
639 x + chooser->headers[chooser->cat_col].x +
640 chooser->headers[chooser->cat_col].x, by + 11);
641 TextOut (hdc, x + chooser->headers[chooser->cat_col].x + HMARGIN / 2, r,
642 pkg.Categories[1]->key.name,
643 strlen (pkg.Categories[1]->key.name));
644 SelectClipRgn (hdc, oldClip2);
645 }
646
647 if (!pkg.SDesc ())
648 s = pkg.name;
649 else
650 {
651 static char buf[512];
652 strcpy (buf, pkg.name);
653 strcat (buf, ": ");
654 strcat (buf, pkg.SDesc ());
655 s = buf;
656 }
657 IntersectClipRect (hdc, x + chooser->headers[chooser->pkg_col].x, by,
658 x + chooser->headers[chooser->pkg_col].x +
659 chooser->headers[chooser->pkg_col].width, by + 11);
660 TextOut (hdc, x + chooser->headers[chooser->pkg_col].x + HMARGIN / 2, r, s,
661 strlen (s));
662 DeleteObject (oldClip);
663 DeleteObject (oldClip2);
664 RestoreDC (hdc, oldDC);
665 }
666
667 void
668 pick_category_line::paint (HDC hdc, int x, int y, int row, int show_cat)
669 {
670 int r = y + row * row_height;
671 if (show_label)
672 {
673 int by = r + tm.tmHeight - 11;
674 TextOut (hdc, x + chooser->headers[chooser->cat_col].x + HMARGIN / 2 + depth * 8,
675 r, cat.name, strlen (cat.name));
676 SIZE s;
677 GetTextExtentPoint32 (hdc, cat.name, strlen (cat.name), &s);
678 SelectObject (bitmap_dc, bm_spin);
679 BitBlt (hdc,
680 x + chooser->headers[chooser->cat_col].x +
681 s.cx + depth * 8 +
682 ICON_MARGIN +
683 HMARGIN / 2, by, 11, 11, bitmap_dc, 0, 0, SRCCOPY);
684 }
685 if (collapsed)
686 return;
687 int accum_row = row + (show_label ? 1 : 0);
688 for (size_t n = 1; n <= bucket.number (); n++)
689 {
690 bucket[n]->paint (hdc, x, y, accum_row, show_cat);
691 accum_row += bucket[n]->itemcount ();
692 }
693 }
694
695 int
696 pick_pkg_line::click (int const myrow, int const ClickedRow, int const x)
697 {
698 // assert (myrow == ClickedRow);
699 if (pkg.desired && pkg.desired->src.sites.number ()
700 && x >= chooser->headers[chooser->src_col].x - HMARGIN / 2
701 && x <= chooser->headers[chooser->src_col + 1].x - HMARGIN / 2)
702 pkg.desired->srcpicked ^= 1;
703
704 if (x >= chooser->headers[chooser->new_col].x - HMARGIN / 2
705 && x <= chooser->headers[chooser->new_col + 1].x - HMARGIN / 2)
706 {
707 pkg.set_action (pkgtrustp (pkg, deftrust));
708 /* Add any packages that are needed by this package */
709 return add_required (pkg);
710 }
711 return 0;
712 }
713
714 int
715 pick_category_line::click (int const myrow, int const ClickedRow, int const x)
716 {
717 if (myrow == ClickedRow && show_label)
718 {
719 collapsed = !collapsed;
720 int accum_row = 0;
721 for (size_t n = 1; n <= bucket.number (); n++)
722 accum_row += bucket[n]->itemcount ();
723 return collapsed ? accum_row : -accum_row;
724 }
725 else
726 {
727 int accum_row = myrow + (show_label ? 1 : 0);
728 for (size_t n = 1; n <= bucket.number (); n++)
729 {
730 if (accum_row + bucket[n]->itemcount () > ClickedRow)
731 return bucket[n]->click (accum_row, ClickedRow, x);
732 accum_row += bucket[n]->itemcount ();
733 }
734 return 0;
735 }
736 }
737
738 HWND DoCreateHeader (HWND hwndParent);
739
740 view::view (views _mode, HWND lv, Category &cat) :
741 contents (cat, 0, false, true), listview (lv)
742 {
743
744 HDC dc = GetDC (listview);
745 sysfont = GetStockObject (DEFAULT_GUI_FONT);
746 SelectObject (dc, sysfont);
747 GetTextMetrics (dc, &tm);
748
749 bitmap_dc = CreateCompatibleDC (dc);
750
751 row_height = (tm.tmHeight + tm.tmExternalLeading + ROW_MARGIN);
752 int
753 irh =
754 tm.
755 tmExternalLeading +
756 tm.
757 tmDescent +
758 11 +
759 ROW_MARGIN;
760 if (row_height < irh)
761 row_height = irh;
762
763 RECT rcParent;
764 HDLAYOUT hdl;
765 WINDOWPOS wp;
766
767 // Ensure that the common control DLL is loaded, and then create
768 // the header control.
769 INITCOMMONCONTROLSEX controlinfo =
770 {
771 sizeof (INITCOMMONCONTROLSEX), ICC_LISTVIEW_CLASSES};
772 InitCommonControlsEx (&controlinfo);
773
774 if ((listheader = CreateWindowEx (0, WC_HEADER, (LPCTSTR) NULL,
775 WS_CHILD | WS_BORDER | CCS_NORESIZE |
776 // | HDS_BUTTONS
777 HDS_HORZ, 0, 0, 0, 0, listview,
778 (HMENU) IDC_CHOOSE_LISTHEADER, hinstance,
779 (LPVOID) NULL)) == NULL)
780 // FIXME: throw an exception
781 exit (10);
782
783 // Retrieve the bounding rectangle of the parent window's
784 // client area, and then request size and position values
785 // from the header control.
786 GetClientRect (listview, &rcParent);
787
788 hdl.prc = &rcParent;
789 hdl.pwpos = &wp;
790 if (!SendMessage (listheader, HDM_LAYOUT, 0, (LPARAM) & hdl))
791 // FIXME: throw an exception
792 exit (11);
793
794
795 // Set the size, position, and visibility of the header control.
796 SetWindowPos (listheader, wp.hwndInsertAfter, wp.x, wp.y,
797 wp.cx, wp.cy, wp.flags | SWP_SHOWWINDOW);
798
799 header_height = wp.cy;
800
801 view_mode = VIEW_PACKAGE;
802 set_headers ();
803 init_headers (dc);
804 view_mode = VIEW_CATEGORY;
805 set_headers ();
806 init_headers (dc);
807
808 view_mode = _mode;
809 set_headers ();
810
811 ReleaseDC (lv, dc);
812 }
813
814 void
815 view::set_view_mode (views _mode)
816 {
817 if (_mode == NVIEW)
818 view_mode = VIEW_PACKAGE_FULL;
819 else
820 view_mode = _mode;
821 set_headers ();
822 }
823
824 const char *
825 view::mode_caption ()
826 {
827 switch (view_mode)
828 {
829 case VIEW_UNKNOWN:
830 return "";
831 case VIEW_PACKAGE_FULL:
832 return "Full";
833 case VIEW_PACKAGE:
834 return "Partial";
835 case VIEW_CATEGORY:
836 return "Category";
837 default:
838 return "";
839 }
840 }
841
842 int DoInsertItem (HWND hwndHeader, int iInsertAfter, int nWidth, LPSTR lpsz);
843
844 void
845 view::set_headers ()
846 {
847 switch (view_mode)
848 {
849 case VIEW_UNKNOWN:
850 return;
851 case VIEW_PACKAGE_FULL:
852 case VIEW_PACKAGE:
853 headers = pkg_headers;
854 current_col = 0;
855 new_col = 1;
856 src_col = 2;
857 cat_col = 3;
858 pkg_col = 4;
859 last_col = 4;
860 break;
861 case VIEW_CATEGORY:
862 headers = cat_headers;
863 current_col = 1;
864 new_col = 2;
865 src_col = 3;
866 cat_col = 0;
867 pkg_col = 4;
868 last_col = 4;
869 break;
870 default:
871 return;
872 }
873 while (int n = SendMessage (listheader, HDM_GETITEMCOUNT, 0, 0))
874 {
875 SendMessage (listheader, HDM_DELETEITEM, n - 1, 0);
876 }
877 int i;
878 for (i = 0; i <= last_col; i++)
879 DoInsertItem (listheader, i, headers[i].width, (char *) headers[i].text);
880 }
881
882
883 void
884 view::init_headers (HDC dc)
885 {
886 int i;
887
888 for (i = 0; headers[i].text; i++)
889 {
890 headers[i].width = 0;
891 headers[i].x = 0;
892 }
893
894 for (i = 0; headers[i].text; i++)
895 note_width (headers, dc, headers[i].text, HMARGIN, i);
896 /* src checkbox */
897 note_width (headers, dc, 0, HMARGIN + 11, src_col);
898 packagedb db;
899 for (size_t n = 1; n <= db.packages.number (); n++)
900 {
901 packagemeta & pkg = *db.packages[n];
902 if (pkg.installed)
903 note_width (headers, dc, pkg.installed->Canonical_version (),
904 HMARGIN, current_col);
905 for (size_t n = 1; n <= pkg.versions.number (); n++)
906 if (pkg.versions[n] != pkg.installed)
907 note_width (headers, dc,
908 pkg.versions[n]->Canonical_version (),
909 NEW_COL_SIZE_SLOP + HMARGIN, new_col);
910 for (size_t n = 1; n <= db.categories.number (); n++)
911 note_width (headers, dc, db.categories[n]->name, HMARGIN, cat_col);
912 if (!pkg.SDesc ())
913 note_width (headers, dc, pkg.name, HMARGIN, pkg_col);
914 else
915 {
916 static char buf[512];
917 strcpy (buf, pkg.name);
918 strcat (buf, ": ");
919 strcat (buf, pkg.SDesc ());
920 note_width (headers, dc, buf, HMARGIN, pkg_col);
921 }
922 }
923 note_width (headers, dc, "keep", NEW_COL_SIZE_SLOP + HMARGIN, new_col);
924 note_width (headers, dc, "uninstall", NEW_COL_SIZE_SLOP + HMARGIN, new_col);
925
926 headers[0].x = 0;
927 for (i = 1; i <= last_col; i++)
928 headers[i].x = headers[i - 1].x + headers[i - 1].width;
929 }
930
931 void
932 view::insert_pkg (packagemeta & pkg)
933 {
934 if (view_mode != VIEW_CATEGORY)
935 {
936 pick_pkg_line & line = *new pick_pkg_line (pkg);
937 contents.insert (line);
938 }
939 else
940 {
941 for (size_t x = 1; x <= pkg.Categories.number (); x++)
942 {
943 Category & cat = pkg.Categories[x]->key;
944 // Special case - yuck
945 if (cat == Category ("All"))
946 continue;
947 pick_category_line & catline = *new pick_category_line (cat, 1);
948 pick_pkg_line & line = *new pick_pkg_line (pkg);
949 catline.insert (line);
950 contents.insert (catline);
951 }
952 }
953 }
954
955 void
956 view::insert_category (Category * cat, bool collapsed)
957 {
958 if (*cat == Category ("All"))
959 return;
960 pick_category_line & catline = *new pick_category_line (*cat, 1, collapsed);
961 for (CategoryPackage * catpkg = cat->packages; catpkg;
962 catpkg = catpkg->next)
963 {
964
965 pick_pkg_line & line = *new pick_pkg_line (*catpkg->pkg);
966 catline.insert (line);
967 }
968 contents.insert (catline);
969 }
970
971 void
972 view::clear_view (void)
973 {
974 contents.empty ();
975 switch (view_mode)
976 {
977 case VIEW_UNKNOWN:
978 break;
979 case VIEW_PACKAGE_FULL:
980 case VIEW_PACKAGE:
981 contents.ShowLabel (false);
982 break;
983 case VIEW_CATEGORY:
984 contents.ShowLabel ();
985 break;
986 default:
987 return;
988 }
989 }
990
991 static views
992 viewsplusplus (views theview)
993 {
994 switch (theview)
995 {
996 case VIEW_UNKNOWN:
997 return VIEW_PACKAGE_FULL;
998 case VIEW_PACKAGE_FULL:
999 return VIEW_PACKAGE;
1000 case VIEW_PACKAGE:
1001 return VIEW_CATEGORY;
1002 case VIEW_CATEGORY:
1003 return NVIEW;
1004 default:
1005 return VIEW_UNKNOWN;
1006 }
1007 }
1008
1009 int
1010 view::click (int row, int x)
1011 {
1012 return contents.click (0, row, x);
1013 }
1014
1015 static void
1016 set_view_mode (HWND h, views mode)
1017 {
1018 chooser->set_view_mode (mode);
1019
1020 chooser->clear_view ();
1021 packagedb db;
1022 switch (chooser->get_view_mode ())
1023 {
1024 case VIEW_PACKAGE:
1025 for (size_t n = 1; n <= db.packages.number (); n++)
1026 {
1027 packagemeta & pkg = *db.packages[n];
1028 if ((!pkg.desired && pkg.installed)
1029 || (pkg.desired
1030 && (pkg.desired->srcpicked || pkg.desired->binpicked)))
1031 chooser->insert_pkg (pkg);
1032 }
1033 break;
1034 case VIEW_PACKAGE_FULL:
1035 for (size_t n = 1; n <= db.packages.number (); n++)
1036 {
1037 packagemeta & pkg = *db.packages[n];
1038 chooser->insert_pkg (pkg);
1039 }
1040 break;
1041 case VIEW_CATEGORY:
1042 /* start collapsed. TODO: make this a chooser flag */
1043 for (size_t n = 1; n <= db.categories.number (); n++)
1044 chooser->insert_category (db.categories[n], CATEGORY_COLLAPSED);
1045 break;
1046 default:
1047 break;
1048 }
1049
1050 RECT r;
1051 GetClientRect (h, &r);
1052 SCROLLINFO si;
1053 memset (&si, 0, sizeof (si));
1054 si.cbSize = sizeof (si);
1055 si.fMask = SIF_ALL;
1056 si.nMin = 0;
1057 si.nMax = chooser->headers[chooser->last_col].x + chooser->headers[chooser->last_col].width; // + HMARGIN;
1058 si.nPage = r.right;
1059 SetScrollInfo (h, SB_HORZ, &si, TRUE);
1060
1061 si.nMax = chooser->contents.itemcount () * row_height;
1062 si.nPage = r.bottom - header_height;
1063 SetScrollInfo (h, SB_VERT, &si, TRUE);
1064
1065 scroll_ulc_x = scroll_ulc_y = 0;
1066
1067 InvalidateRect (h, &r, TRUE);
1068
1069 if (nextbutton)
1070 SetFocus (nextbutton);
1071 }
1072
1073 // DoInsertItem - inserts an item into a header control.
1074 // Returns the index of the new item.
1075 // hwndHeader - handle to the header control.
1076 // iInsertAfter - index of the previous item.
1077 // nWidth - width of the new item.
1078 // lpsz - address of the item string.
1079 int
1080 DoInsertItem (HWND hwndHeader, int iInsertAfter, int nWidth, LPSTR lpsz)
1081 {
1082 HDITEM hdi;
1083 int index;
1084
1085 hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
1086 hdi.pszText = lpsz;
1087 hdi.cxy = nWidth;
1088 hdi.cchTextMax = lstrlen (hdi.pszText);
1089 hdi.fmt = HDF_LEFT | HDF_STRING;
1090
1091 index = SendMessage (hwndHeader, HDM_INSERTITEM,
1092 (WPARAM) iInsertAfter, (LPARAM) & hdi);
1093
1094 return index;
1095
1096 }
1097
1098
1099 static void
1100 create_listview (HWND dlg, RECT * r)
1101 {
1102 lv = CreateWindowEx (WS_EX_CLIENTEDGE,
1103 "listview",
1104 "listviewwindow",
1105 WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE,
1106 r->left, r->top,
1107 r->right - r->left + 1, r->bottom - r->top + 1,
1108 dlg,
1109 (HMENU) MAKEINTRESOURCE (IDC_CHOOSE_LIST),
1110 hinstance, 0);
1111 ShowWindow (lv, SW_SHOW);
1112 packagedb db;
1113 chooser = new view (VIEW_CATEGORY, lv, db.categories.registerbykey("All"));
1114
1115 default_trust (lv, TRUST_CURR);
1116 set_view_mode (lv, VIEW_CATEGORY);
1117 if (!SetDlgItemText (dlg, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ()))
1118 log (LOG_BABBLE, "Failed to set View button caption %ld",
1119 GetLastError ());
1120 for (size_t n = 1; n <= db.packages.number (); n++)
1121 {
1122 packagemeta & pkg = *db.packages[n];
1123 add_required (pkg);
1124 }
1125 /* FIXME: do we need to init the desired fields ? */
1126 static int ta[] = { IDC_CHOOSE_CURR, 0 };
1127 rbset (dlg, ta, IDC_CHOOSE_CURR);
1128
1129 }
1130
1131 static BOOL
1132 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
1133 {
1134 packagedb db;
1135 switch (id)
1136 {
1137 case IDC_CHOOSE_PREV:
1138 default_trust (lv, TRUST_PREV);
1139 for (size_t n = 1; n <= db.packages.number (); n++)
1140 {
1141 packagemeta & pkg = *db.packages[n];
1142 add_required (pkg);
1143 }
1144 set_view_mode (lv, chooser->get_view_mode ());
1145 break;
1146 case IDC_CHOOSE_CURR:
1147 default_trust (lv, TRUST_CURR);
1148 for (size_t n = 1; n <= db.packages.number (); n++)
1149 {
1150 packagemeta & pkg = *db.packages[n];
1151 add_required (pkg);
1152 }
1153 set_view_mode (lv, chooser->get_view_mode ());
1154 break;
1155 case IDC_CHOOSE_EXP:
1156 default_trust (lv, TRUST_TEST);
1157 for (size_t n = 1; n <= db.packages.number (); n++)
1158 {
1159 packagemeta & pkg = *db.packages[n];
1160 add_required (pkg);
1161 }
1162 set_view_mode (lv, chooser->get_view_mode ());
1163 break;
1164 case IDC_CHOOSE_VIEW:
1165 set_view_mode (lv, viewsplusplus (chooser->get_view_mode ()));
1166 if (!SetDlgItemText
1167 (h, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ()))
1168 log (LOG_BABBLE, "Failed to set View button caption %ld",
1169 GetLastError ());
1170 break;
1171
1172 case IDOK:
1173 if (source == IDC_SOURCE_CWD)
1174 NEXT (IDD_S_INSTALL);
1175 else
1176 NEXT (IDD_S_DOWNLOAD);
1177 break;
1178
1179 case IDC_BACK:
1180 initialized = 0;
1181 if (source == IDC_SOURCE_CWD)
1182 NEXT (IDD_LOCAL_DIR);
1183 else
1184 NEXT (IDD_SITE);
1185 break;
1186
1187 case IDCANCEL:
1188 NEXT (0);
1189 break;
1190 }
1191 return 0;
1192 }
1193
1194 static void
1195 GetParentRect (HWND parent, HWND child, RECT * r)
1196 {
1197 POINT p;
1198 GetWindowRect (child, r);
1199 p.x = r->left;
1200 p.y = r->top;
1201 ScreenToClient (parent, &p);
1202 r->left = p.x;
1203 r->top = p.y;
1204 p.x = r->right;
1205 p.y = r->bottom;
1206 ScreenToClient (parent, &p);
1207 r->right = p.x;
1208 r->bottom = p.y;
1209 }
1210
1211 static BOOL CALLBACK
1212 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
1213 {
1214 HWND frame;
1215 RECT r;
1216 switch (message)
1217 {
1218 case WM_INITDIALOG:
1219 nextbutton = GetDlgItem (h, IDOK);
1220 frame = GetDlgItem (h, IDC_LISTVIEW_POS);
1221 choose_inst_text = GetDlgItem (h, IDC_CHOOSE_INST_TEXT);
1222 if (source == IDC_SOURCE_DOWNLOAD)
1223 SetWindowText (choose_inst_text, "Select packages to download ");
1224 else
1225 SetWindowText (choose_inst_text, "Select packages to install ");
1226 GetParentRect (h, frame, &r);
1227 r.top += 2;
1228 r.bottom -= 2;
1229 create_listview (h, &r);
1230
1231 #if 0
1232 load_dialog (h);
1233 #endif
1234 return TRUE;
1235 case WM_COMMAND:
1236 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
1237 }
1238 return FALSE;
1239 }
1240
1241 /* Find out where to put existing tar file in local directory in
1242 known package array. */
1243 static void
1244 scan2 (char *path, unsigned int size)
1245 {
1246 packagemeta *pkg;
1247 fileparse f;
1248
1249 if (!parse_filename (path, f))
1250 return;
1251
1252 if (f.what[0] != '\0' && f.what[0] != 's')
1253 return;
1254
1255 packagedb db;
1256 pkg = db.packages.getbykey (f.pkg);
1257 if (pkg == NULL)
1258 return;
1259
1260 /* Scan existing package list looking for a match between a known
1261 package and a tar archive on disk.
1262 While scanning, keep track of appropriate "holes" in the trust
1263 table where a tar file could be put if no known entry
1264 exists.
1265
1266 We have 4 specific insertion points and one generic point.
1267 The generic point is in versioned order in the package version array.
1268 The specific points are
1269 *installed
1270 *prev
1271 *curr
1272 *exp.
1273
1274 if the version number matches a version in the db,
1275 we simply add this as a mirror source to that version.
1276 If it matches no version, we add a new version to the db.
1277
1278 Lastly if the version number does not matche one of installed/prev/current/exp
1279 AND we had to create a new version entry
1280 we apply the following heuristic:
1281 if there is no exp, we link this in exp.
1282 If there is an exp and this is higher, we link this in exp, and
1283 if there is no curr, bump what was in exp to curr. If there was a curr, we leave it be.
1284 if this is lower than exp, and there is no curr, link as curr. If there is a curr, leave it be.
1285 If this is lower than curr, and there is no prev, link as prev, if there is a prev, leave it be.
1286
1287 Whilst this logic is potentially wrong from time to time, it guarantees that
1288 setup.ini defined stability won't be altered unintentially. An alternative is to
1289 mark setup.ini defined prev/curr/exp packages as such, when this algorithm, can
1290 get smarter.
1291
1292 So, if setup.ini knows that ash-20010425-1.tar.gz is the current
1293 version and there is an ash-20010426-1.tar.gz in the current directory,
1294 the 20010426 version will be placed in the "test" slot, assuming that
1295 there is no test version listed in setup.ini. */
1296
1297 int added = 0;
1298 for (size_t n = 1; n <= pkg->versions.number (); n++)
1299 {
1300 if (!strcasecmp (f.ver, pkg->versions[n]->Canonical_version ()))
1301 {
1302 /* FIXME: Add a mirror entry */
1303 added = 1;
1304 }
1305 }
1306 if (!added)
1307 {
1308 /* FIXME: Add a new version */
1309
1310 /* And now the hole finder */
1311 #if 0
1312 if (!pkg->exp)
1313 pkg->exp = thenewver;
1314 else if (strcasecmp (f.ver, pkg->versions[n]->Canonicalversion ()) < 0)
1315 /* try curr */
1316 if (!pkg->curr)
1317 pkg->curr = thenewver;
1318 else if (strcasecmp (f.ver, pkg->versions[n]->Canonicalversion ()) <
1319 0)
1320 /* try prev */
1321 if (!pkg->prev)
1322 pkg->prev = thenewver;
1323 #endif
1324 }
1325
1326 }
1327
1328 static void
1329 scan_downloaded_files ()
1330 {
1331 find (".", scan2);
1332 }
1333
1334 void
1335 do_choose (HINSTANCE h, HWND owner)
1336 {
1337 int rv;
1338
1339 nextbutton = 0;
1340 bm_spin = LoadImage (h, MAKEINTRESOURCE (IDB_SPIN), IMAGE_BITMAP, 0, 0, 0);
1341 bm_rtarrow = LoadImage (h, MAKEINTRESOURCE (IDB_RTARROW), IMAGE_BITMAP,
1342 0, 0, 0);
1343
1344 bm_checkyes = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_YES), IMAGE_BITMAP,
1345 0, 0, 0);
1346 bm_checkno = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_NO), IMAGE_BITMAP,
1347 0, 0, 0);
1348 bm_checkna = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_NA), IMAGE_BITMAP,
1349 0, 0, 0);
1350
1351 register_windows (h);
1352
1353 if (source == IDC_SOURCE_DOWNLOAD || source == IDC_SOURCE_CWD)
1354 scan_downloaded_files ();
1355
1356 set_existence ();
1357 fill_missing_category ();
1358
1359 rv = DialogBox (h, MAKEINTRESOURCE (IDD_CHOOSE), owner, dialog_proc);
1360 if (rv == -1)
1361 fatal (owner, IDS_DIALOG_FAILED);
1362
1363 log (LOG_BABBLE, "Chooser results...");
1364 packagedb db;
1365 for (size_t n = 1; n <= db.packages.number (); n++)
1366 {
1367 packagemeta & pkg = *db.packages[n];
1368 // static const char *infos[] = { "nada", "prev", "curr", "test" };
1369 const char *trust = ((pkg.desired == pkg.prev) ? "prev"
1370 : (pkg.desired == pkg.curr) ? "curr"
1371 : (pkg.desired == pkg.exp) ? "test" : "unknown");
1372 const char *action = pkg.action_caption ();
1373 const char *installed =
1374 pkg.installed ? pkg.installed->Canonical_version () : "none";
1375
1376 log (LOG_BABBLE, "[%s] action=%s trust=%s installed=%s"
1377 " src?=%s",
1378 pkg.name, action, trust, installed,
1379 pkg.desired && pkg.desired->srcpicked ? "yes" : "no");
1380 if (pkg.Categories.number ())
1381 {
1382 /* List categories the package belongs to */
1383 int categories_len = 0;
1384 for (size_t n = 1; n <= pkg.Categories.number (); n++)
1385 categories_len += strlen (pkg.Categories[n]->key.name) + 2;
1386
1387 if (categories_len > 0)
1388 {
1389 char *categories = (char *) malloc (categories_len);
1390 strcpy (categories, pkg.Categories[1]->key.name);
1391 for (size_t n = 2; n <= pkg.Categories.number (); n++)
1392 {
1393 strcat (categories, ", ");
1394 strcat (categories, pkg.Categories[n]->key.name);
1395 }
1396 log (LOG_BABBLE, " categories=%s", categories);
1397 free (categories);
1398 }
1399 }
1400 if (pkg.desired && pkg.desired->required)
1401 {
1402 /* List other packages this package depends on */
1403 int requires_len = 0;
1404 Dependency *dp;
1405 for (dp = pkg.desired->required; dp; dp = dp->next)
1406 if (dp->package)
1407 requires_len += strlen (dp->package) + 2;
1408
1409 if (requires_len > 0)
1410 {
1411 char *requires = (char *) malloc (requires_len);
1412 strcpy (requires, pkg.desired->required->package);
1413 for (dp = pkg.desired->required->next; dp; dp = dp->next)
1414 if (dp->package)
1415 {
1416 strcat (requires, ", ");
1417 strcat (requires, dp->package);
1418 }
1419 log (LOG_BABBLE, " requires=%s", requires);
1420 free (requires);
1421 }
1422 }
1423 #if 0
1424
1425 /* FIXME: Reinstate this code, but spit out all mirror sites */
1426
1427 for (int t = 1; t < NTRUST; t++)
1428 {
1429 if (pkg->info[t].install)
1430 log (LOG_BABBLE, " [%s] ver=%s\n"
1431 " inst=%s %d exists=%s\n"
1432 " src=%s %d exists=%s",
1433 infos[t],
1434 pkg->info[t].version ? : "(none)",
1435 pkg->info[t].install ? : "(none)",
1436 pkg->info[t].install_size,
1437 (pkg->info[t].install_exists) ? "yes" : "no",
1438 pkg->info[t].source ? : "(none)",
1439 pkg->info[t].source_size,
1440 (pkg->info[t].source_exists) ? "yes" : "no");
1441 }
1442 #endif
1443 }
1444 }
1445
1446 #define WM_APP_START_CHOOSE WM_APP+0
1447 #define WM_APP_CHOOSE_IS_FINISHED WM_APP+1
1448
1449 extern void do_choose (HINSTANCE h, HWND owner);
1450
1451 void
1452 do_choose_thread (void *p)
1453 {
1454 ChooserPage *cp;
1455
1456 cp = static_cast < ChooserPage * >(p);
1457
1458 do_choose (cp->GetInstance (), cp->GetHWND ());
1459
1460 cp->PostMessage (WM_APP_CHOOSE_IS_FINISHED);
1461
1462 _endthread ();
1463 }
1464
1465 bool
1466 ChooserPage::Create ()
1467 {
1468 return PropertyPage::Create (IDD_CHOOSER);
1469 }
1470
1471 void
1472 ChooserPage::OnActivate ()
1473 {
1474 GetOwner ()->SetButtons (0);
1475 PostMessage (WM_APP_START_CHOOSE);
1476 }
1477
1478 bool
1479 ChooserPage::OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam)
1480 {
1481 switch (uMsg)
1482 {
1483 case WM_APP_START_CHOOSE:
1484 {
1485 // Start the chooser thread.
1486 _beginthread (do_choose_thread, 0, this);
1487 break;
1488 }
1489 case WM_APP_CHOOSE_IS_FINISHED:
1490 {
1491 switch (next_dialog)
1492 {
1493 case 0:
1494 {
1495 // Cancel
1496 GetOwner ()->PressButton (PSBTN_CANCEL);
1497 break;
1498 }
1499 case IDD_LOCAL_DIR:
1500 case IDD_SITE:
1501 {
1502 // Back
1503 GetOwner ()->SetActivePageByID (next_dialog);
1504 break;
1505 }
1506 case IDD_S_DOWNLOAD:
1507 {
1508 // Next, start download from internet
1509 Progress.SetActivateTask (WM_APP_START_DOWNLOAD);
1510 GetOwner ()->SetActivePageByID (IDD_INSTATUS);
1511 break;
1512 }
1513 case IDD_S_INSTALL:
1514 {
1515 // Next, install
1516 Progress.SetActivateTask (WM_APP_START_INSTALL);
1517 GetOwner ()->SetActivePageByID (IDD_INSTATUS);
1518 break;
1519 }
1520 }
1521 }
1522 default:
1523 return false;
1524 break;
1525 }
1526 return true;
1527 }
This page took 0.105487 seconds and 5 git commands to generate.