]>
cygwin.com Git - cygwin-apps/setup.git/blob - choose.cc
2 * Copyright (c) 2000, 2001 Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
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
29 static const char *cvsid
=
48 #include "filemanip.h"
49 #include "io_stream.h"
53 #include "package_db.h"
54 #include "package_meta.h"
55 #include "package_version.h"
59 #define alloca __builtin_alloca
64 #define RTARROW_WIDTH 11
66 #define NEW_COL_SIZE_SLOP (ICON_MARGIN + SPIN_WIDTH + RTARROW_WIDTH)
70 static int initialized
= 0;
72 static int scroll_ulc_x
, scroll_ulc_y
;
74 static HWND lv
, nextbutton
, choose_inst_text
;
76 static int header_height
;
77 static HANDLE sysfont
;
78 static int row_height
;
79 static HANDLE bm_spin
, bm_rtarrow
, bm_checkyes
, bm_checkno
, bm_checkna
;
81 static view
*chooser
= NULL
;
82 static trusts deftrust
= TRUST_UNKNOWN
;
84 static struct _header pkg_headers
[] = {
88 {"Category", 8, 0, 0},
93 static struct _header cat_headers
[] = {
94 {"Category", 8, 0, 0},
102 static void set_view_mode (HWND h
, views mode
);
105 pkgtrustp (packagemeta
const &pkg
, trusts
const t
)
107 return t
== TRUST_PREV
? pkg
.prev
: t
== TRUST_CURR
? pkg
.curr
: pkg
.exp
;
111 add_required (packagemeta
& pkg
, size_t depth
= 0)
114 packagemeta
*required
;
117 || (pkg
.desired
!= pkg
.installed
&& !pkg
.desired
->binpicked
))
118 /* uninstall || source only */
121 dp
= pkg
.desired
->required
;
123 /* cheap test for too much recursion */
128 if ((required
= db
.packages
.getbykey (dp
->package
)) == NULL
)
134 if (!required
->desired
)
136 /* it's set to uninstall */
137 required
->set_action (pkgtrustp (*required
, deftrust
));
139 else if (required
->desired
!= required
->installed
140 && !required
->desired
->binpicked
)
142 /* it's set to change to a different version source only */
143 required
->desired
->binpicked
= 1;
145 /* does this requirement have requirements? */
146 changed
+= add_required (*required
, depth
+ 1);
153 topbucket::paint (HDC hdc
, int x
, int y
, int row
, int show_cat
)
156 for (size_t n
= 1; n
<= bucket
.number (); n
++)
158 bucket
[n
]->paint (hdc
, x
, y
, accum_row
, show_cat
);
159 accum_row
+= bucket
[n
]->itemcount ();
164 topbucket::empty (void)
166 while (bucket
.number ())
168 pick_line
*line
= bucket
.removebyindex (1);
173 topbucket::~topbucket (void)
179 topbucket::click (int const myrow
, int const ClickedRow
, int const x
)
181 int accum_row
= myrow
;
182 for (size_t n
= 1; n
<= bucket
.number (); n
++)
184 accum_row
+= bucket
[n
]->itemcount ();
185 if (accum_row
> ClickedRow
)
186 return bucket
[n
]->click (accum_row
- bucket
[n
]->itemcount (),
199 hdc
= BeginPaint (hwnd
, &ps
);
201 SelectObject (hdc
, sysfont
);
202 SetBkColor (hdc
, GetSysColor (COLOR_WINDOW
));
203 SetTextColor (hdc
, GetSysColor (COLOR_WINDOWTEXT
));
206 GetClientRect (hwnd
, &cr
);
208 x
= cr
.left
- scroll_ulc_x
;
209 y
= cr
.top
- scroll_ulc_y
+ header_height
;
211 IntersectClipRect (hdc
, cr
.left
, cr
.top
+ header_height
, cr
.right
,
214 chooser
->contents
.paint (hdc
, x
, y
, 0, (chooser
->get_view_mode () ==
215 VIEW_CATEGORY
) ? 0 : 1);
217 if (chooser
->contents
.itemcount () == 0)
219 static const char *msg
= "Nothing to Install/Update";
220 if (source
== IDC_SOURCE_DOWNLOAD
)
221 msg
= "Nothing to Download";
222 TextOut (hdc
, HMARGIN
, header_height
, msg
, strlen (msg
));
225 EndPaint (hwnd
, &ps
);
229 view::scroll (HWND hwnd
, int which
, int *var
, int code
)
232 si
.cbSize
= sizeof (si
);
234 GetScrollInfo (hwnd
, which
, &si
);
239 si
.nPos
= si
.nTrackPos
;
241 case SB_THUMBPOSITION
:
250 si
.nPos
+= row_height
;
253 si
.nPos
-= row_height
;
256 si
.nPos
+= si
.nPage
* 9 / 10;
259 si
.nPos
-= si
.nPage
* 9 / 10;
263 if ((int) si
.nPos
< 0)
265 if (si
.nPos
+ si
.nPage
> (unsigned int) si
.nMax
)
266 si
.nPos
= si
.nMax
- si
.nPage
;
269 SetScrollInfo (hwnd
, which
, &si
, TRUE
);
271 int ox
= scroll_ulc_x
;
272 int oy
= scroll_ulc_y
;
276 GetClientRect (hwnd
, &cr
);
278 sr
.top
+= header_height
;
280 ScrollWindow (hwnd
, ox
- scroll_ulc_x
, oy
- scroll_ulc_y
, &sr
, &sr
);
284 ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
286 if (ox
- scroll_ulc_x
)
288 GetClientRect (listheader
, &cr
);
290 // UpdateWindow (htmp);
291 MoveWindow (listheader
, -scroll_ulc_x
, 0,
292 chooser
->headers
[last_col
].x
+
293 chooser
->headers
[last_col
].width
, header_height
, TRUE
);
298 static LRESULT CALLBACK
299 list_vscroll (HWND hwnd
, HWND hctl
, UINT code
, int pos
)
301 chooser
->scroll (hwnd
, SB_VERT
, &scroll_ulc_y
, code
);
305 static LRESULT CALLBACK
306 list_hscroll (HWND hwnd
, HWND hctl
, UINT code
, int pos
)
308 chooser
->scroll (hwnd
, SB_HORZ
, &scroll_ulc_x
, code
);
312 static LRESULT CALLBACK
313 list_click (HWND hwnd
, BOOL dblclk
, int x
, int y
, UINT hitCode
)
317 if (chooser
->contents
.itemcount () == 0)
320 if (y
< header_height
)
323 y
+= scroll_ulc_y
- header_height
;
325 row
= (y
+ ROW_MARGIN
/ 2) / row_height
;
327 if (row
< 0 || row
>= chooser
->contents
.itemcount ())
330 refresh
= chooser
->click (row
, x
);
335 GetClientRect (lv
, &r
);
337 memset (&si
, 0, sizeof (si
));
338 si
.cbSize
= sizeof (si
);
339 si
.fMask
= SIF_ALL
; /* SIF_RANGE was giving strange behaviour */
342 si
.nMax
= chooser
->contents
.itemcount () * row_height
;
343 si
.nPage
= r
.bottom
- header_height
;
345 /* if we are under the minimum display count ,
346 * set the offset to 0
348 if ((unsigned int) si
.nMax
<= si
.nPage
)
350 si
.nPos
= scroll_ulc_y
;
352 SetScrollInfo (lv
, SB_VERT
, &si
, TRUE
);
354 InvalidateRect (lv
, &r
, TRUE
);
360 rect
.left
= chooser
->headers
[chooser
->new_col
].x
- scroll_ulc_x
;
361 rect
.right
= chooser
->headers
[chooser
->src_col
+ 1].x
- scroll_ulc_x
;
362 rect
.top
= header_height
+ row
* row_height
- scroll_ulc_y
;
363 rect
.bottom
= rect
.top
+ row_height
;
364 InvalidateRect (hwnd
, &rect
, TRUE
);
369 static LRESULT CALLBACK
370 listview_proc (HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
375 return HANDLE_WM_HSCROLL (hwnd
, wParam
, lParam
, list_hscroll
);
377 return HANDLE_WM_VSCROLL (hwnd
, wParam
, lParam
, list_vscroll
);
379 return HANDLE_WM_LBUTTONDOWN (hwnd
, wParam
, lParam
, list_click
);
385 // pnmh = (LPNMHDR) lParam
386 LPNMHEADER phdr
= (LPNMHEADER
) lParam
;
387 switch (phdr
->hdr
.code
)
389 case HDN_ITEMCHANGED
:
390 if (phdr
->hdr
.hwndFrom
== chooser
->ListHeader ())
392 if (phdr
->pitem
&& phdr
->pitem
->mask
& HDI_WIDTH
)
393 chooser
->headers
[phdr
->iItem
].width
= phdr
->pitem
->cxy
;
394 for (int i
= 1; i
<= chooser
->last_col
; i
++)
395 chooser
->headers
[i
].x
=
396 chooser
->headers
[i
- 1].x
+ chooser
->headers
[i
- 1].width
;
398 GetClientRect (hwnd
, &r
);
400 si
.cbSize
= sizeof (si
);
402 GetScrollInfo (hwnd
, SB_HORZ
, &si
);
403 int oldMax
= si
.nMax
;
405 chooser
->headers
[chooser
->last_col
].x
+
406 chooser
->headers
[chooser
->last_col
].width
;
407 if (si
.nTrackPos
&& oldMax
> si
.nMax
)
408 si
.nTrackPos
+= si
.nMax
- oldMax
;
410 SetScrollInfo (hwnd
, SB_HORZ
, &si
, TRUE
);
411 InvalidateRect (hwnd
, &r
, TRUE
);
412 if (si
.nTrackPos
&& oldMax
> si
.nMax
)
413 chooser
->scroll (hwnd
, SB_HORZ
, &scroll_ulc_x
,
422 return DefWindowProc (hwnd
, message
, wParam
, lParam
);
427 register_windows (HINSTANCE hinst
)
436 memset (&wcex
, 0, sizeof (wcex
));
437 wcex
.cbSize
= sizeof (WNDCLASSEX
);
438 wcex
.style
= CS_HREDRAW
| CS_VREDRAW
;
439 wcex
.lpfnWndProc
= listview_proc
;
440 wcex
.hInstance
= hinst
;
441 wcex
.hIcon
= LoadIcon (0, IDI_APPLICATION
);
442 wcex
.hCursor
= LoadCursor (0, IDC_ARROW
);
443 wcex
.hbrBackground
= (HBRUSH
) (COLOR_WINDOW
+ 1);
444 wcex
.lpszClassName
= "listview";
446 RegisterClassEx (&wcex
);
450 note_width (struct _header
*hdrs
, HDC dc
, const char *string
, int addend
,
455 if (hdrs
[column
].width
< addend
)
456 hdrs
[column
].width
= addend
;
460 GetTextExtentPoint32 (dc
, string
, strlen (string
), &s
);
461 if (hdrs
[column
].width
< s
.cx
+ addend
)
462 hdrs
[column
].width
= s
.cx
+ addend
;
469 iterate through the package list, and delete packages that are
471 * have no mirror site
472 and then do the same for categories with no packages.
477 fill_missing_category ()
480 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
482 packagemeta
& pkg
= *db
.packages
[n
];
483 if (!pkg
.Categories
.number ())
484 pkg
.add_category (db
.categories
.registerbykey ("Misc"));
489 default_trust (HWND h
, trusts trust
)
493 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
495 packagemeta
& pkg
= *db
.packages
[n
];
497 || pkg
.Categories
.getbykey (db
.categories
.registerbykey ("Base"))
498 || pkg
.Categories
.getbykey (db
.categories
.registerbykey ("Misc")))
500 pkg
.desired
= pkgtrustp (pkg
, trust
);
503 pkg
.desired
->binpicked
= pkg
.desired
== pkg
.installed
? 0 : 1;
504 pkg
.desired
->srcpicked
= 0;
511 GetClientRect (h
, &r
);
512 InvalidateRect (h
, &r
, TRUE
);
514 SetFocus (nextbutton
);
518 pick_pkg_line::paint (HDC hdc
, int x
, int y
, int row
, int show_cat
)
520 int r
= y
+ row
* row_height
;
521 int by
= r
+ tm
.tmHeight
- 11;
522 int oldDC
= SaveDC (hdc
);
525 HRGN oldClip
= CreateRectRgn (0, 0, 0, 0);
526 if (GetRandomRgn (hdc
, oldClip
, SYSRGN
) == -1)
528 RestoreDC (hdc
, oldDC
);
531 unsigned int regionsize
= GetRegionData (oldClip
, 0, 0);
532 LPRGNDATA oldClipData
= (LPRGNDATA
) malloc (regionsize
);
533 if (GetRegionData (oldClip
, regionsize
, oldClipData
) != regionsize
)
535 RestoreDC (hdc
, oldDC
);
536 DeleteObject (oldClip
);
539 for (unsigned int n
= 0; n
< oldClipData
->rdh
.nCount
; n
++)
540 for (unsigned int t
= 0; t
< 2; t
++)
541 ScreenToClient (WindowFromDC (hdc
),
542 &((POINT
*) oldClipData
->Buffer
)[t
+ n
* 2]);
544 HRGN oldClip2
= ExtCreateRegion (NULL
, regionsize
, oldClipData
);
545 SelectClipRgn (hdc
, oldClip2
);
548 IntersectClipRect (hdc
, x
+ chooser
->headers
[chooser
->current_col
].x
,
550 x
+ chooser
->headers
[chooser
->current_col
].x
+
551 chooser
->headers
[chooser
->current_col
].width
,
554 x
+ chooser
->headers
[chooser
->current_col
].x
+ HMARGIN
/ 2, r
,
555 pkg
.installed
->Canonical_version (),
556 strlen (pkg
.installed
->Canonical_version ()));
557 SelectObject (bitmap_dc
, bm_rtarrow
);
558 BitBlt (hdc
, x
+ chooser
->headers
[chooser
->new_col
].x
+ HMARGIN
/ 2,
559 by
, 11, 11, bitmap_dc
, 0, 0, SRCCOPY
);
560 SelectClipRgn (hdc
, oldClip2
);
563 const char *s
= pkg
.action_caption ();
564 IntersectClipRect (hdc
, x
+ chooser
->headers
[chooser
->new_col
].x
,
566 x
+ chooser
->headers
[chooser
->new_col
].x
+
567 chooser
->headers
[chooser
->new_col
].width
, by
+ 11);
569 x
+ chooser
->headers
[chooser
->new_col
].x
+ HMARGIN
/ 2 +
570 NEW_COL_SIZE_SLOP
, r
, s
, strlen (s
));
571 SelectObject (bitmap_dc
, bm_spin
);
573 x
+ chooser
->headers
[chooser
->new_col
].x
+ ICON_MARGIN
/ 2 +
574 RTARROW_WIDTH
+ HMARGIN
/ 2, by
, 11, 11, bitmap_dc
, 0, 0, SRCCOPY
);
575 SelectClipRgn (hdc
, oldClip2
);
578 if ( /* uninstall */ !pkg
.desired
||
579 /* source only */ (!pkg
.desired
->binpicked
580 && pkg
.desired
->srcpicked
) ||
581 /* when no source mirror available */
582 !pkg
.desired
->src
.sites
.number ())
583 check_bm
= bm_checkna
;
584 else if (pkg
.desired
->srcpicked
)
585 check_bm
= bm_checkyes
;
587 check_bm
= bm_checkno
;
589 SelectObject (bitmap_dc
, check_bm
);
590 IntersectClipRect (hdc
, x
+ chooser
->headers
[chooser
->src_col
].x
, by
,
591 x
+ chooser
->headers
[chooser
->src_col
].x
+
592 chooser
->headers
[chooser
->src_col
].width
, by
+ 11);
593 BitBlt (hdc
, x
+ chooser
->headers
[chooser
->src_col
].x
+ HMARGIN
/ 2, by
, 11,
594 11, bitmap_dc
, 0, 0, SRCCOPY
);
595 SelectClipRgn (hdc
, oldClip2
);
597 /* shows "first" category - do we want to show any? */
598 if (pkg
.Categories
.number () && show_cat
)
600 IntersectClipRect (hdc
, x
+ chooser
->headers
[chooser
->cat_col
].x
, by
,
601 x
+ chooser
->headers
[chooser
->cat_col
].x
+
602 chooser
->headers
[chooser
->cat_col
].x
, by
+ 11);
603 TextOut (hdc
, x
+ chooser
->headers
[chooser
->cat_col
].x
+ HMARGIN
/ 2, r
,
604 pkg
.Categories
[1]->key
.name
,
605 strlen (pkg
.Categories
[1]->key
.name
));
606 SelectClipRgn (hdc
, oldClip2
);
613 static char buf
[512];
614 strcpy (buf
, pkg
.name
);
616 strcat (buf
, pkg
.SDesc ());
619 IntersectClipRect (hdc
, x
+ chooser
->headers
[chooser
->pkg_col
].x
, by
,
620 x
+ chooser
->headers
[chooser
->pkg_col
].x
+
621 chooser
->headers
[chooser
->pkg_col
].width
, by
+ 11);
622 TextOut (hdc
, x
+ chooser
->headers
[chooser
->pkg_col
].x
+ HMARGIN
/ 2, r
, s
,
624 DeleteObject (oldClip
);
625 DeleteObject (oldClip2
);
626 RestoreDC (hdc
, oldDC
);
630 pick_category_line::paint (HDC hdc
, int x
, int y
, int row
, int show_cat
)
632 int r
= y
+ row
* row_height
;
633 TextOut (hdc
, x
+ chooser
->headers
[chooser
->cat_col
].x
+ HMARGIN
/ 2, r
,
634 cat
.name
, strlen (cat
.name
));
637 int accum_row
= row
+ 1;
638 for (size_t n
= 1; n
<= bucket
.number (); n
++)
640 bucket
[n
]->paint (hdc
, x
, y
, accum_row
, show_cat
);
641 accum_row
+= bucket
[n
]->itemcount ();
646 pick_pkg_line::click (int const myrow
, int const ClickedRow
, int const x
)
648 // assert (myrow == ClickedRow);
649 if (pkg
.desired
&& pkg
.desired
->src
.sites
.number ()
650 && x
>= chooser
->headers
[chooser
->src_col
].x
- HMARGIN
/ 2
651 && x
<= chooser
->headers
[chooser
->src_col
+ 1].x
- HMARGIN
/ 2)
652 pkg
.desired
->srcpicked
^= 1;
654 if (x
>= chooser
->headers
[chooser
->new_col
].x
- HMARGIN
/ 2
655 && x
<= chooser
->headers
[chooser
->new_col
+ 1].x
- HMARGIN
/ 2)
657 pkg
.set_action (pkgtrustp (pkg
, deftrust
));
658 /* Add any packages that are needed by this package */
659 return add_required (pkg
);
665 pick_category_line::click (int const myrow
, int const ClickedRow
, int const x
)
667 if (myrow
== ClickedRow
)
669 collapsed
= !collapsed
;
671 for (size_t n
= 1; n
<= bucket
.number (); n
++)
672 accum_row
+= bucket
[n
]->itemcount ();
673 return collapsed
? accum_row
: -accum_row
;
677 int accum_row
= myrow
+ 1;
678 for (size_t n
= 1; n
<= bucket
.number (); n
++)
680 if (accum_row
+ bucket
[n
]->itemcount () > ClickedRow
)
681 return bucket
[n
]->click (accum_row
, ClickedRow
, x
);
682 accum_row
+= bucket
[n
]->itemcount ();
688 HWND
DoCreateHeader (HWND hwndParent
);
690 view::view (views _mode
, HWND lv
):listview (lv
)
696 sysfont
= GetStockObject (DEFAULT_GUI_FONT
);
697 SelectObject (dc
, sysfont
);
698 GetTextMetrics (dc
, &tm
);
700 bitmap_dc
= CreateCompatibleDC (dc
);
702 row_height
= (tm
.tmHeight
+ tm
.tmExternalLeading
+ ROW_MARGIN
);
711 if (row_height
< irh
)
721 // Ensure that the common control DLL is loaded, and then create
722 // the header control.
725 sizeof (INITCOMMONCONTROLSEX
),
728 InitCommonControlsEx (&controlinfo
);
730 if ((listheader
= CreateWindowEx (0, WC_HEADER
, (LPCTSTR
) NULL
,
731 WS_CHILD
| WS_BORDER
| CCS_NORESIZE
|
733 HDS_HORZ
, 0, 0, 0, 0, listview
,
734 (HMENU
) IDC_CHOOSE_LISTHEADER
, hinstance
,
735 (LPVOID
) NULL
)) == NULL
)
736 // FIXME: throw an exception
739 // Retrieve the bounding rectangle of the parent window's
740 // client area, and then request size and position values
741 // from the header control.
742 GetClientRect (listview
, &rcParent
);
746 if (!SendMessage (listheader
, HDM_LAYOUT
, 0, (LPARAM
) & hdl
))
747 // FIXME: throw an exception
751 // Set the size, position, and visibility of the header control.
752 SetWindowPos (listheader
, wp
.hwndInsertAfter
, wp
.x
, wp
.y
,
753 wp
.cx
, wp
.cy
, wp
.flags
| SWP_SHOWWINDOW
);
755 header_height
= wp
.cy
;
757 view_mode
= VIEW_PACKAGE
;
760 view_mode
= VIEW_CATEGORY
;
771 view::set_view_mode (views _mode
)
774 view_mode
= VIEW_PACKAGE_FULL
;
781 view::mode_caption ()
787 case VIEW_PACKAGE_FULL
:
798 int DoInsertItem (HWND hwndHeader
, int iInsertAfter
, int nWidth
, LPSTR lpsz
);
807 case VIEW_PACKAGE_FULL
:
809 headers
= pkg_headers
;
818 headers
= cat_headers
;
829 while (int n
= SendMessage (listheader
, HDM_GETITEMCOUNT
, 0, 0))
831 SendMessage (listheader
, HDM_DELETEITEM
, n
- 1, 0);
834 for (i
= 0; i
<= last_col
; i
++)
835 DoInsertItem (listheader
, i
, headers
[i
].width
, (char *) headers
[i
].text
);
840 view::init_headers (HDC dc
)
844 for (i
= 0; headers
[i
].text
; i
++)
846 headers
[i
].width
= 0;
850 for (i
= 0; headers
[i
].text
; i
++)
851 note_width (headers
, dc
, headers
[i
].text
, HMARGIN
, i
);
853 note_width (headers
, dc
, 0, HMARGIN
+ 11, src_col
);
855 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
857 packagemeta
& pkg
= *db
.packages
[n
];
859 note_width (headers
, dc
, pkg
.installed
->Canonical_version (),
860 HMARGIN
, current_col
);
861 for (size_t n
= 1; n
<= pkg
.versions
.number (); n
++)
862 if (pkg
.versions
[n
] != pkg
.installed
)
863 note_width (headers
, dc
,
864 pkg
.versions
[n
]->Canonical_version (),
865 NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
866 for (size_t n
= 1; n
<= db
.categories
.number (); n
++)
867 note_width (headers
, dc
, db
.categories
[n
]->name
, HMARGIN
, cat_col
);
869 note_width (headers
, dc
, pkg
.name
, HMARGIN
, pkg_col
);
872 static char buf
[512];
873 strcpy (buf
, pkg
.name
);
875 strcat (buf
, pkg
.SDesc ());
876 note_width (headers
, dc
, buf
, HMARGIN
, pkg_col
);
879 note_width (headers
, dc
, "keep", NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
880 note_width (headers
, dc
, "uninstall", NEW_COL_SIZE_SLOP
+ HMARGIN
, new_col
);
883 for (i
= 1; i
<= last_col
; i
++)
884 headers
[i
].x
= headers
[i
- 1].x
+ headers
[i
- 1].width
;
888 view::insert_pkg (packagemeta
& pkg
)
890 if (view_mode
!= VIEW_CATEGORY
)
892 pick_pkg_line
& line
= *new pick_pkg_line (pkg
);
893 contents
.insert (line
);
897 for (size_t x
= 1; x
<= pkg
.Categories
.number (); x
++)
899 Category
& cat
= pkg
.Categories
[x
]->key
;
900 pick_category_line
& catline
= *new pick_category_line (cat
);
901 pick_pkg_line
& line
= *new pick_pkg_line (pkg
);
902 catline
.insert (line
);
903 contents
.insert (catline
);
909 view::insert_category (Category
* cat
, bool collapsed
)
911 pick_category_line
& catline
= *new pick_category_line (*cat
, collapsed
);
912 for (CategoryPackage
* catpkg
= cat
->packages
; catpkg
;
913 catpkg
= catpkg
->next
)
915 pick_pkg_line
& line
= *new pick_pkg_line (*catpkg
->pkg
);
916 catline
.insert (line
);
918 contents
.insert (catline
);
922 view::clear_view (void)
928 viewsplusplus (views theview
)
933 return VIEW_PACKAGE_FULL
;
934 case VIEW_PACKAGE_FULL
:
937 return VIEW_CATEGORY
;
946 view::click (int row
, int x
)
948 return contents
.click (0, row
, x
);
952 set_view_mode (HWND h
, views mode
)
954 chooser
->set_view_mode (mode
);
956 chooser
->clear_view ();
958 switch (chooser
->get_view_mode ())
961 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
963 packagemeta
& pkg
= *db
.packages
[n
];
964 if ((!pkg
.desired
&& pkg
.installed
)
966 && (pkg
.desired
->srcpicked
|| pkg
.desired
->binpicked
)))
967 chooser
->insert_pkg (pkg
);
970 case VIEW_PACKAGE_FULL
:
971 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
973 packagemeta
& pkg
= *db
.packages
[n
];
974 chooser
->insert_pkg (pkg
);
978 /* start collapsed. TODO: make this a chooser flag */
979 for (size_t n
= 1; n
<= db
.categories
.number (); n
++)
980 chooser
->insert_category (db
.categories
[n
], CATEGORY_COLLAPSED
);
987 GetClientRect (h
, &r
);
989 memset (&si
, 0, sizeof (si
));
990 si
.cbSize
= sizeof (si
);
993 si
.nMax
= chooser
->headers
[chooser
->last_col
].x
+ chooser
->headers
[chooser
->last_col
].width
; // + HMARGIN;
995 SetScrollInfo (h
, SB_HORZ
, &si
, TRUE
);
997 si
.nMax
= chooser
->contents
.itemcount () * row_height
;
998 si
.nPage
= r
.bottom
- header_height
;
999 SetScrollInfo (h
, SB_VERT
, &si
, TRUE
);
1001 scroll_ulc_x
= scroll_ulc_y
= 0;
1003 InvalidateRect (h
, &r
, TRUE
);
1006 SetFocus (nextbutton
);
1009 // DoInsertItem - inserts an item into a header control.
1010 // Returns the index of the new item.
1011 // hwndHeader - handle to the header control.
1012 // iInsertAfter - index of the previous item.
1013 // nWidth - width of the new item.
1014 // lpsz - address of the item string.
1016 DoInsertItem (HWND hwndHeader
, int iInsertAfter
, int nWidth
, LPSTR lpsz
)
1021 hdi
.mask
= HDI_TEXT
| HDI_FORMAT
| HDI_WIDTH
;
1024 hdi
.cchTextMax
= lstrlen (hdi
.pszText
);
1025 hdi
.fmt
= HDF_LEFT
| HDF_STRING
;
1027 index
= SendMessage (hwndHeader
, HDM_INSERTITEM
,
1028 (WPARAM
) iInsertAfter
, (LPARAM
) & hdi
);
1036 create_listview (HWND dlg
, RECT
* r
)
1038 lv
= CreateWindowEx (WS_EX_CLIENTEDGE
,
1041 WS_CHILD
| WS_HSCROLL
| WS_VSCROLL
| WS_VISIBLE
,
1043 r
->right
- r
->left
+ 1, r
->bottom
- r
->top
+ 1,
1045 (HMENU
) MAKEINTRESOURCE (IDC_CHOOSE_LIST
),
1047 ShowWindow (lv
, SW_SHOW
);
1048 chooser
= new view (VIEW_CATEGORY
, lv
);
1050 default_trust (lv
, TRUST_CURR
);
1051 set_view_mode (lv
, VIEW_CATEGORY
);
1052 if (!SetDlgItemText (dlg
, IDC_CHOOSE_VIEWCAPTION
, chooser
->mode_caption ()))
1053 log (LOG_BABBLE
, "Failed to set View button caption %ld",
1056 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
1058 packagemeta
& pkg
= *db
.packages
[n
];
1061 /* FIXME: do we need to init the desired fields ? */
1062 static int ta
[] = { IDC_CHOOSE_CURR
, 0 };
1063 rbset (dlg
, ta
, IDC_CHOOSE_CURR
);
1068 dialog_cmd (HWND h
, int id
, HWND hwndctl
, UINT code
)
1073 case IDC_CHOOSE_PREV
:
1074 default_trust (lv
, TRUST_PREV
);
1075 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
1077 packagemeta
& pkg
= *db
.packages
[n
];
1080 set_view_mode (lv
, chooser
->get_view_mode ());
1082 case IDC_CHOOSE_CURR
:
1083 default_trust (lv
, TRUST_CURR
);
1084 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
1086 packagemeta
& pkg
= *db
.packages
[n
];
1089 set_view_mode (lv
, chooser
->get_view_mode ());
1091 case IDC_CHOOSE_EXP
:
1092 default_trust (lv
, TRUST_TEST
);
1093 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
1095 packagemeta
& pkg
= *db
.packages
[n
];
1098 set_view_mode (lv
, chooser
->get_view_mode ());
1100 case IDC_CHOOSE_VIEW
:
1101 set_view_mode (lv
, viewsplusplus (chooser
->get_view_mode ()));
1103 (h
, IDC_CHOOSE_VIEWCAPTION
, chooser
->mode_caption ()))
1104 log (LOG_BABBLE
, "Failed to set View button caption %ld",
1109 if (source
== IDC_SOURCE_CWD
)
1110 NEXT (IDD_S_INSTALL
);
1112 NEXT (IDD_S_DOWNLOAD
);
1117 if (source
== IDC_SOURCE_CWD
)
1118 NEXT (IDD_LOCAL_DIR
);
1131 GetParentRect (HWND parent
, HWND child
, RECT
* r
)
1134 GetWindowRect (child
, r
);
1137 ScreenToClient (parent
, &p
);
1142 ScreenToClient (parent
, &p
);
1147 static BOOL CALLBACK
1148 dialog_proc (HWND h
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1155 nextbutton
= GetDlgItem (h
, IDOK
);
1156 frame
= GetDlgItem (h
, IDC_LISTVIEW_POS
);
1157 choose_inst_text
= GetDlgItem (h
, IDC_CHOOSE_INST_TEXT
);
1158 if (source
== IDC_SOURCE_DOWNLOAD
)
1159 SetWindowText (choose_inst_text
, "Select packages to download ");
1161 SetWindowText (choose_inst_text
, "Select packages to install ");
1162 GetParentRect (h
, frame
, &r
);
1165 create_listview (h
, &r
);
1171 return HANDLE_WM_COMMAND (h
, wParam
, lParam
, dialog_cmd
);
1176 /* Find out where to put existing tar file in local directory in
1177 known package array. */
1179 scan2 (char *path
, unsigned int size
)
1184 if (!parse_filename (path
, f
))
1187 if (f
.what
[0] != '\0' && f
.what
[0] != 's')
1191 pkg
= db
.packages
.getbykey (f
.pkg
);
1195 /* Scan existing package list looking for a match between a known
1196 package and a tar archive on disk.
1197 While scanning, keep track of appropriate "holes" in the trust
1198 table where a tar file could be put if no known entry
1201 We have 4 specific insertion points and one generic point.
1202 The generic point is in versioned order in the package version array.
1203 The specific points are
1209 if the version number matches a version in the db,
1210 we simply add this as a mirror source to that version.
1211 If it matches no version, we add a new version to the db.
1213 Lastly if the version number does not matche one of installed/prev/current/exp
1214 AND we had to create a new version entry
1215 we apply the following heuristic:
1216 if there is no exp, we link this in exp.
1217 If there is an exp and this is higher, we link this in exp, and
1218 if there is no curr, bump what was in exp to curr. If there was a curr, we leave it be.
1219 if this is lower than exp, and there is no curr, link as curr. If there is a curr, leave it be.
1220 If this is lower than curr, and there is no prev, link as prev, if there is a prev, leave it be.
1222 Whilst this logic is potentially wrong from time to time, it guarantees that
1223 setup.ini defined stability won't be altered unintentially. An alternative is to
1224 mark setup.ini defined prev/curr/exp packages as such, when this algorithm, can
1227 So, if setup.ini knows that ash-20010425-1.tar.gz is the current
1228 version and there is an ash-20010426-1.tar.gz in the current directory,
1229 the 20010426 version will be placed in the "test" slot, assuming that
1230 there is no test version listed in setup.ini. */
1233 for (size_t n
= 1; n
<= pkg
->versions
.number (); n
++)
1235 if (!strcasecmp (f
.ver
, pkg
->versions
[n
]->Canonical_version ()))
1237 /* FIXME: Add a mirror entry */
1243 /* FIXME: Add a new version */
1245 /* And now the hole finder */
1248 pkg
->exp
= thenewver
;
1249 else if (strcasecmp (f
.ver
, pkg
->versions
[n
]->Canonicalversion ()) < 0)
1252 pkg
->curr
= thenewver
;
1253 else if (strcasecmp (f
.ver
, pkg
->versions
[n
]->Canonicalversion ()) <
1257 pkg
->prev
= thenewver
;
1264 scan_downloaded_files ()
1270 do_choose (HINSTANCE h
)
1275 bm_spin
= LoadImage (h
, MAKEINTRESOURCE (IDB_SPIN
), IMAGE_BITMAP
, 0, 0, 0);
1276 bm_rtarrow
= LoadImage (h
, MAKEINTRESOURCE (IDB_RTARROW
), IMAGE_BITMAP
,
1279 bm_checkyes
= LoadImage (h
, MAKEINTRESOURCE (IDB_CHECK_YES
), IMAGE_BITMAP
,
1281 bm_checkno
= LoadImage (h
, MAKEINTRESOURCE (IDB_CHECK_NO
), IMAGE_BITMAP
,
1283 bm_checkna
= LoadImage (h
, MAKEINTRESOURCE (IDB_CHECK_NA
), IMAGE_BITMAP
,
1286 register_windows (h
);
1288 if (source
== IDC_SOURCE_DOWNLOAD
|| source
== IDC_SOURCE_CWD
)
1289 scan_downloaded_files ();
1292 fill_missing_category ();
1294 rv
= DialogBox (h
, MAKEINTRESOURCE (IDD_CHOOSE
), 0, dialog_proc
);
1296 fatal (IDS_DIALOG_FAILED
);
1298 log (LOG_BABBLE
, "Chooser results...");
1300 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
1302 packagemeta
& pkg
= *db
.packages
[n
];
1303 // static const char *infos[] = { "nada", "prev", "curr", "test" };
1304 const char *trust
= ((pkg
.desired
== pkg
.prev
) ? "prev"
1305 : (pkg
.desired
== pkg
.curr
) ? "curr"
1306 : (pkg
.desired
== pkg
.exp
) ? "test" : "unknown");
1307 const char *action
= pkg
.action_caption ();
1308 const char *installed
=
1309 pkg
.installed
? pkg
.installed
->Canonical_version () : "none";
1311 log (LOG_BABBLE
, "[%s] action=%s trust=%s installed=%s"
1313 pkg
.name
, action
, trust
, installed
,
1314 pkg
.desired
&& pkg
.desired
->srcpicked
? "yes" : "no");
1315 if (pkg
.Categories
.number ())
1317 /* List categories the package belongs to */
1318 int categories_len
= 0;
1319 for (size_t n
= 1; n
<= pkg
.Categories
.number (); n
++)
1320 categories_len
+= strlen (pkg
.Categories
[n
]->key
.name
) + 2;
1322 if (categories_len
> 0)
1324 char *categories
= (char *) malloc (categories_len
);
1325 strcpy (categories
, pkg
.Categories
[1]->key
.name
);
1326 for (size_t n
= 2; n
<= pkg
.Categories
.number (); n
++)
1328 strcat (categories
, ", ");
1329 strcat (categories
, pkg
.Categories
[n
]->key
.name
);
1331 log (LOG_BABBLE
, " categories=%s", categories
);
1335 if (pkg
.desired
&& pkg
.desired
->required
)
1337 /* List other packages this package depends on */
1338 int requires_len
= 0;
1340 for (dp
= pkg
.desired
->required
; dp
; dp
= dp
->next
)
1342 requires_len
+= strlen (dp
->package
) + 2;
1344 if (requires_len
> 0)
1346 char *requires
= (char *) malloc (requires_len
);
1347 strcpy (requires
, pkg
.desired
->required
->package
);
1348 for (dp
= pkg
.desired
->required
->next
; dp
; dp
= dp
->next
)
1351 strcat (requires
, ", ");
1352 strcat (requires
, dp
->package
);
1354 log (LOG_BABBLE
, " requires=%s", requires
);
1360 /* FIXME: Reinstate this code, but spit out all mirror sites */
1362 for (int t
= 1; t
< NTRUST
; t
++)
1364 if (pkg
->info
[t
].install
)
1365 log (LOG_BABBLE
, " [%s] ver=%s\n"
1366 " inst=%s %d exists=%s\n"
1367 " src=%s %d exists=%s",
1369 pkg
->info
[t
].version
? : "(none)",
1370 pkg
->info
[t
].install
? : "(none)",
1371 pkg
->info
[t
].install_size
,
1372 (pkg
->info
[t
].install_exists
) ? "yes" : "no",
1373 pkg
->info
[t
].source
? : "(none)",
1374 pkg
->info
[t
].source_size
,
1375 (pkg
->info
[t
].source_exists
) ? "yes" : "no");
This page took 0.090986 seconds and 5 git commands to generate.