]>
cygwin.com Git - cygwin-apps/setup.git/blob - choose.cc
e10ec14123ded21524b363a4e35354d5b5e080b6
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
28 static char *cvsid
= "\n%%% $Id$\n";
44 #include "filemanip.h"
53 #define NEW_COL_SIZE_SLOP (ICON_MARGIN + 11)
57 static int initialized
= 0;
59 static int scroll_ulc_x
, scroll_ulc_y
;
61 static HWND lv
, nextbutton
, choose_inst_text
;
63 static int header_height
;
64 static HANDLE sysfont
;
65 static int row_height
;
66 static HANDLE bm_spin
, bm_rtarrow
, bm_checkyes
, bm_checkno
, bm_checkna
;
68 static view
*chooser
= NULL
;
69 static trusts deftrust
= TRUST_UNKNOWN
;
71 static struct _header pkg_headers
[] = {
72 { "Current", 7, 0, 0 },
75 { "Category", 8, 0, 0 },
76 { "Package", 7, 0, 0 },
80 static struct _header cat_headers
[] = {
81 { "Category", 8, 0, 0 },
82 { "Current", 7, 0, 0 },
85 { "Package", 7, 0, 0 },
89 static int add_required(Package
*pkg
);
90 static void set_view_mode (HWND h
, views mode
);
93 isinstalled (Package
*pkg
, int trust
)
95 if (source
== IDC_SOURCE_DOWNLOAD
)
96 return pkg
->info
[trust
].install_exists
< 0;
98 return pkg
->installed
&& pkg
->info
[trust
].version
&&
99 strcasecmp (pkg
->installed
->version
, pkg
->info
[trust
].version
) == 0;
102 /* Set the next action given a current action. */
104 set_action (Package
*pkg
, bool preinc
)
106 if (!pkg
->action
|| preinc
)
108 ((int) pkg
->action
)++;
112 /* Exercise the action state machine. */
113 for (;; ((int) pkg
->action
)++)
118 pkg
->action
= (actions
) (ACTION_CURR
- 1);
121 pkg
->action
= ACTION_PREV
;
122 /* fall through intentionally */
126 /* Try to find the next best action. We may not have all of
127 prev, curr, or test but we should have at least one of those. */
129 inf
= pkg
->info
+ pkg
->action
;
130 if (inf
->version
&& inf
->install_exists
)
132 if (isinstalled (pkg
, pkg
->action
))
133 (int) pkg
->action
+= ACTION_SAME
;
137 /* ACTION_SAME_* are used when the installed version is the same
138 as the given action. */
139 case ACTION_SAME_CURR
:
140 case ACTION_SAME_TEST
:
141 if (!preinc
) /* Previously set to this value */
143 (int) pkg
->action
-= ACTION_SAME
+ 1; /* revert to ACTION_CURR, etc. */
145 case ACTION_SAME_PREV
:
146 if (!preinc
) /* Previously set to this value */
148 pkg
->action
= ACTION_UNINSTALL
;
149 /* Fall through intentionally */
150 case ACTION_UNINSTALL
:
151 if (source
!= IDC_SOURCE_DOWNLOAD
&& pkg
->installed
)
156 if (isinstalled (pkg
, deftrust
))
158 pkg
->trust
= deftrust
;
163 case ACTION_SRC_ONLY
:
165 if (pkg
->info
[deftrust
].source_exists
)
167 pkg
->trust
= deftrust
;
173 case ACTION_SAME_LAST
:
174 pkg
->action
= ACTION_SKIP
;
175 /* Fall through intentionally */
177 if ((source
== IDC_SOURCE_DOWNLOAD
) || !pkg
->installed
178 || pkg
->trust
!= pkg
->installed_ix
)
182 log (0, "should never get here %d\n", pkg
->action
);
187 add_required (Package
*pkg
)
196 case ACTION_UNINSTALL
:
199 case ACTION_SRC_ONLY
:
207 if ((required
= getpkgbyname(dp
->package
)) == NULL
)
212 switch (required
->action
)
218 case ACTION_SAME_CURR
:
219 case ACTION_SAME_TEST
:
220 case ACTION_SAME_PREV
:
222 case ACTION_SAME_LAST
:
223 /* we are installing a user selected version */
226 case ACTION_UNINSTALL
:
227 /* it's already installed - leave it */
228 required
->action
= (actions
) required
->installed_ix
;
232 case ACTION_SRC_ONLY
:
234 /* the current install will fail */
235 required
->action
= ACTION_UNKNOWN
; /* this find prev, then curr, then test. */
236 set_action(required
, 0); /* we need a find_best that gets installed, */
237 changed
++; /* then current, then prev, then test */
238 chooser
->insert_pkg (required
);
241 log (0, "invalid state %d\n", required
->action
);
243 changed
+= add_required (required
);
249 /* Return an appropriate caption given the current action. */
251 choose_caption (Package
*pkg
)
259 pkg
->trust
= (trusts
) pkg
->action
;
260 return pkg
->info
[pkg
->trust
].version
;
261 case ACTION_SAME_PREV
:
262 case ACTION_SAME_CURR
:
263 case ACTION_SAME_TEST
:
265 case ACTION_UNINSTALL
:
268 return source
== IDC_SOURCE_DOWNLOAD
? "Retrieve" : "Reinstall";
269 case ACTION_SRC_ONLY
:
270 if (pkg
->installed
&& pkg
->installed
->source_exists
)
271 return "Redo Source";
287 hdc
= BeginPaint (hwnd
, &ps
);
289 SelectObject (hdc
, sysfont
);
290 SetBkColor (hdc
, GetSysColor (COLOR_WINDOW
));
291 SetTextColor (hdc
, GetSysColor (COLOR_WINDOWTEXT
));
294 GetClientRect (hwnd
, &cr
);
298 x
= cr
.left
- scroll_ulc_x
;
299 y
= cr
.top
- scroll_ulc_y
+ header_height
;
302 for (i
= 0; i
<= chooser
->last_col
; i
++)
304 TextOut (hdc
, x
+ chooser
->headers
[i
].x
, 3, chooser
->headers
[i
].text
,
305 chooser
->headers
[i
].slen
);
306 MoveToEx (hdc
, x
+ chooser
->headers
[i
].x
, header_height
-3, &p
);
307 LineTo (hdc
, x
+ chooser
->headers
[i
].x
+ chooser
->headers
[i
].width
,
311 IntersectClipRect (hdc
, cr
.left
, cr
.top
+ header_height
, cr
.right
, cr
.bottom
);
313 for (ii
= 0; ii
< chooser
->nlines
; ii
++)
314 chooser
->lines
[ii
].paint (hdc
, x
, y
, ii
,
315 (chooser
->get_view_mode () == VIEW_CATEGORY
) ? 0 : 1);
317 if (chooser
->nlines
== 0)
319 static char *msg
= "Nothing to Install/Update";
320 if (source
== IDC_SOURCE_DOWNLOAD
)
321 msg
= "Nothing to Download";
322 TextOut (hdc
, HMARGIN
, header_height
, msg
, strlen (msg
));
325 EndPaint (hwnd
, &ps
);
329 scroll_common (HWND hwnd
, int which
, int *var
, int code
)
334 si
.cbSize
= sizeof (si
);
336 GetScrollInfo (hwnd
, which
, &si
);
341 si
.nPos
= si
.nTrackPos
;
343 case SB_THUMBPOSITION
:
352 si
.nPos
+= row_height
;
355 si
.nPos
-= row_height
;
358 si
.nPos
+= si
.nPage
* 9/10;
361 si
.nPos
-= si
.nPage
* 9/10;
365 if ((int)si
.nPos
< 0)
367 if (si
.nPos
+ si
.nPage
> si
.nMax
)
368 si
.nPos
= si
.nMax
- si
.nPage
;
371 SetScrollInfo (hwnd
, which
, &si
, TRUE
);
373 int ox
= scroll_ulc_x
;
374 int oy
= scroll_ulc_y
;
378 GetClientRect (hwnd
, &cr
);
380 sr
.top
+= header_height
;
381 ScrollWindow (hwnd
, ox
- scroll_ulc_x
, oy
- scroll_ulc_y
, &sr
, &sr
);
384 ScrollWindow (hwnd
, ox
- scroll_ulc_x
, 0, &sr
, &sr
);
387 static LRESULT CALLBACK
388 list_vscroll (HWND hwnd
, HWND hctl
, UINT code
, int pos
)
390 scroll_common (hwnd
, SB_VERT
, &scroll_ulc_y
, code
);
393 static LRESULT CALLBACK
394 list_hscroll (HWND hwnd
, HWND hctl
, UINT code
, int pos
)
396 scroll_common (hwnd
, SB_HORZ
, &scroll_ulc_x
, code
);
399 static LRESULT CALLBACK
400 list_click (HWND hwnd
, BOOL dblclk
, int x
, int y
, UINT hitCode
)
404 if (chooser
->nlines
== 0)
407 if (y
< header_height
)
410 y
+= scroll_ulc_y
- header_height
;
412 r
= (y
+ ROW_MARGIN
/2) / row_height
;
414 if (r
< 0 || r
>= chooser
->nlines
)
417 refresh
= chooser
->click (r
, x
);
422 GetClientRect (lv
, &r
);
424 memset (&si
, 0, sizeof (si
));
425 si
.cbSize
= sizeof (si
);
426 si
.fMask
= SIF_ALL
; /* SIF_RANGE was giving strange behaviour */
429 si
.nMax
= chooser
->nlines
* row_height
;
430 si
.nPage
= r
.bottom
- header_height
;
431 si
.nPos
= scroll_ulc_y
;
432 SetScrollInfo (lv
, SB_VERT
, &si
, TRUE
);
434 InvalidateRect (lv
, &r
, TRUE
);
440 rect
.left
= chooser
->headers
[chooser
->new_col
].x
- scroll_ulc_x
;
441 rect
.right
= chooser
->headers
[chooser
->src_col
+ 1].x
- scroll_ulc_x
;
442 rect
.top
= header_height
+ r
* row_height
- scroll_ulc_y
;
443 rect
.bottom
= rect
.top
+ row_height
;
444 InvalidateRect (hwnd
, &rect
, TRUE
);
448 static LRESULT CALLBACK
449 listview_proc (HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
454 return HANDLE_WM_HSCROLL (hwnd
, wParam
, lParam
, list_hscroll
);
456 return HANDLE_WM_VSCROLL (hwnd
, wParam
, lParam
, list_vscroll
);
458 return HANDLE_WM_LBUTTONDOWN (hwnd
, wParam
, lParam
, list_click
);
463 return DefWindowProc (hwnd
, message
, wParam
, lParam
);
468 register_windows (HINSTANCE hinst
)
477 memset (&wcex
, 0, sizeof (wcex
));
478 wcex
.cbSize
= sizeof (WNDCLASSEX
);
479 wcex
.style
= CS_HREDRAW
| CS_VREDRAW
;
480 wcex
.lpfnWndProc
= listview_proc
;
481 wcex
.hInstance
= hinst
;
482 wcex
.hIcon
= LoadIcon (0, IDI_APPLICATION
);
483 wcex
.hCursor
= LoadCursor (0, IDC_ARROW
);
484 wcex
.hbrBackground
= (HBRUSH
) (COLOR_WINDOW
+ 1);
485 wcex
.lpszClassName
= "listview";
487 RegisterClassEx (&wcex
);
491 note_width (struct _header
*hdrs
, HDC dc
, char *string
, int addend
, int column
)
496 GetTextExtentPoint32 (dc
, string
, strlen (string
), &s
);
497 if (hdrs
[column
].width
< s
.cx
+ addend
)
498 hdrs
[column
].width
= s
.cx
+ addend
;
502 check_existence (Info
*inf
, int check_src
)
504 if (source
== IDC_SOURCE_NETINST
)
506 if (source
== IDC_SOURCE_CWD
)
507 return 0; /* should have already been determined */
509 return (inf
->source
&& _access (inf
->source
, 0) == 0) ? -1 : 1;
511 return (inf
->install
&& _access (inf
->install
, 0) == 0) ? -1 : 1;
515 /* Iterate over the package list, setting the "existence" flags
516 for the source or binary. */
520 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
524 for (Info
*inf
= pkg
->infoscan
; inf
< pkg
->infoend
; inf
++)
526 if (inf
->install_exists
)
529 exists
|= inf
->install_exists
= check_existence (inf
, 0);
530 if (inf
->source_exists
)
533 exists
|= inf
->source_exists
= check_existence (inf
, 1);
535 if (source
!= IDC_SOURCE_DOWNLOAD
&& !exists
)
536 pkg
->exclude
= EXCLUDE_NOT_FOUND
;
541 fill_missing_category ()
543 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
544 if (!pkg
->exclude
&& !pkg
->category
)
545 add_category (pkg
, register_category ("Misc"));
549 keep_or_skip (Package
*pkg
)
552 return (actions
) pkg
->installed_ix
;
557 default_trust (HWND h
, trusts trust
)
562 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
565 pkg
->action
= (actions
) trust
;
566 if (pkg
->category
&& !(getpackagecategorybyname (pkg
, "Required") ||
567 getpackagecategorybyname (pkg
, "Misc")))
568 pkg
->action
= keep_or_skip (pkg
);
572 GetClientRect (h
, &r
);
573 InvalidateRect (h
, &r
, TRUE
);
575 SetFocus (nextbutton
);
579 pick_line::set_line (Package
*_pkg
)
586 pick_line::set_line (Category
*_cat
)
593 pick_line::paint (HDC hdc
, int x
, int y
, int row
, int show_cat
)
595 int r
= y
+ row
* row_height
;
596 int by
= r
+ tm
.tmHeight
- 11;
601 TextOut (hdc
, x
+ chooser
->headers
[chooser
->current_col
].x
, r
,
602 pkg
->installed
->version
, strlen (pkg
->installed
->version
));
603 SelectObject (bitmap_dc
, bm_rtarrow
);
604 BitBlt (hdc
, x
+ chooser
->headers
[chooser
->current_col
].x
605 + chooser
->headers
[0].width
+ ICON_MARGIN
/ 2
607 by
, 11, 11, bitmap_dc
, 0, 0, SRCCOPY
);
610 const char *s
= choose_caption (pkg
);
611 TextOut (hdc
, x
+ chooser
->headers
[chooser
->new_col
].x
612 + NEW_COL_SIZE_SLOP
, r
, s
, strlen (s
));
613 SelectObject (bitmap_dc
, bm_spin
);
614 BitBlt (hdc
, x
+ chooser
->headers
[chooser
->new_col
].x
, by
, 11, 11,
615 bitmap_dc
, 0, 0, SRCCOPY
);
618 if (!pkg
->info
[pkg
->trust
].source_exists
619 || (pkg
->action
!= ACTION_REDO
&& pkg
->action
!= (actions
) pkg
->trust
))
620 check_bm
= bm_checkna
;
621 else if (pkg
->srcpicked
)
622 check_bm
= bm_checkyes
;
624 check_bm
= bm_checkno
;
626 SelectObject (bitmap_dc
, check_bm
);
627 BitBlt (hdc
, x
+ chooser
->headers
[chooser
->src_col
].x
, by
, 11, 11,
628 bitmap_dc
, 0, 0, SRCCOPY
);
630 /* shows "first" category - do we want to show any? */
631 if (pkg
->category
&& show_cat
)
632 TextOut (hdc
, x
+ chooser
->headers
[chooser
->cat_col
].x
, r
,
633 pkg
->category
->name
, strlen (pkg
->category
->name
));
639 TextOut (hdc
, x
+ chooser
->headers
[chooser
->pkg_col
].x
, r
, s
, strlen (s
));
642 TextOut (hdc
, x
+ chooser
->headers
[chooser
->cat_col
].x
, r
, cat
->name
,
647 pick_line::click (int x
)
651 if (pkg
->info
[pkg
->trust
].source_exists
652 && x
>= chooser
->headers
[chooser
->src_col
].x
- HMARGIN
/2
653 && x
<= chooser
->headers
[chooser
->src_col
+ 1].x
- HMARGIN
/2)
656 if (x
>= chooser
->headers
[chooser
->new_col
].x
- (HMARGIN
/ 2)
657 && x
<= chooser
->headers
[chooser
->new_col
+ 1].x
- HMARGIN
/2)
660 /* Add any packages that are needed by this package */
661 return add_required (pkg
);
666 /* handle the catalog being clicked ... does this belong up a level.. ? */
672 _view::_view (views _mode
, HDC dc
)
676 view_mode
= VIEW_PACKAGE
;
679 view_mode
= VIEW_CATEGORY
;
688 _view::set_view_mode (views _mode
)
691 view_mode
= VIEW_PACKAGE_FULL
;
698 _view::mode_caption ()
702 case VIEW_UNKNOWN
: return "";
703 case VIEW_PACKAGE_FULL
: return "Full";
704 case VIEW_PACKAGE
: return "Partial";
705 case VIEW_CATEGORY
: return "Category";
711 _view::set_headers (void)
717 case VIEW_PACKAGE_FULL
:
719 headers
= pkg_headers
;
728 headers
= cat_headers
;
741 _view::init_headers (HDC dc
)
745 for (i
= 0; headers
[i
].text
; i
++)
746 headers
[i
].width
= 0;
748 for (i
= 0; headers
[i
].text
; i
++)
749 note_width (headers
, dc
, headers
[i
].text
, 0, i
);
750 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
754 note_width (headers
, dc
, pkg
->installed
->version
, 0, current_col
);
755 note_width (headers
, dc
, pkg
->installed
->version
, NEW_COL_SIZE_SLOP
,
758 for (Info
*inf
= pkg
->infoscan
; inf
< pkg
->infoend
; inf
++)
759 note_width (headers
, dc
, inf
->version
, NEW_COL_SIZE_SLOP
, new_col
);
760 for (Category
*cat
= pkg
->category
; cat
; cat
= cat
->next
)
761 note_width (headers
, dc
, cat
->name
, 0, cat_col
);
762 note_width (headers
, dc
, pkg
->name
, 0, pkg_col
);
763 note_width (headers
, dc
, pkg
->sdesc
, 0, pkg_col
);
765 note_width (headers
, dc
, "keep", NEW_COL_SIZE_SLOP
, new_col
);
766 note_width (headers
, dc
, "uninstall", NEW_COL_SIZE_SLOP
, new_col
);
768 headers
[0].x
= HMARGIN
/2;
769 for (i
= 1; i
<= last_col
; i
++)
770 headers
[i
].x
= headers
[i
-1].x
+ headers
[i
-1].width
+ ((i
== new_col
) ?
771 NEW_COL_SIZE_SLOP
: 0) + HMARGIN
;
775 _view::insert_pkg (Package
*pkg
)
781 if (view_mode
!= VIEW_CATEGORY
)
785 lines
= (pick_line
*) calloc (npackages
+ ncategories
,
791 insert_under (0, line
);
795 // assert (lines); /* protect against a coding change in future */
796 for (Category
*cat
= pkg
->category
; cat
; cat
= cat
->next
)
798 /* insert the package under this category in the list. If this category is not
803 /* this should be a generic call to list_sort_cmp */
804 if (lines
[n
].get_category ()
805 && cat
->name
== lines
[n
].get_category ()->name
)
806 insert_under (n
, line
);
811 /* the category wasn't visible - insert at the end */
812 insert_category (cat
, CATEGORY_COLLAPSED
);
820 _view::insert_category (Category
*cat
, int collapsed
)
826 lines
= (pick_line
*) malloc ((npackages
+ ncategories
) * sizeof (pick_line
));
827 memset (lines
, '\0', (npackages
+ ncategories
) * sizeof (pick_line
) );
831 for (CategoryPackage
*catpkg
= cat
->packages
; catpkg
; catpkg
= catpkg
->next
)
832 insert_pkg (getpkgbyname (catpkg
->pkgname
));
839 /* this should be a generic call to list_sort_cmp */
840 if (lines
[n
].get_category ()
841 && strcasecmp (cat
->name
, lines
[n
].get_category ()->name
) < 0)
845 for (CategoryPackage
*catpkg
= cat
->packages
; catpkg
; catpkg
= catpkg
->next
)
846 insert_pkg (getpkgbyname (catpkg
->pkgname
));
849 else if (lines
[n
].get_category () == cat
)
856 /* insert at the end */
859 for (CategoryPackage
*catpkg
= cat
->packages
; catpkg
; catpkg
= catpkg
->next
)
860 insert_pkg (getpkgbyname (catpkg
->pkgname
));
865 /* insert a new line at line n */
867 _view::insert_at (int n
, pick_line line
)
869 if (n
< 0 || n
> nlines
)
871 memmove (&lines
[n
+ 1], &lines
[n
], (nlines
- n
) * sizeof (pick_line
));
876 /* insert a new line in the chooser, at the next depth in from linen */
878 _view::insert_under (int linen
, pick_line line
)
881 /* special case - empty view */
887 /* part 1 - find the appropriate bucket beginning */
888 if (lines
[linen
].get_category ())
892 else if (lines
[linen
].get_pkg ())
895 /* walk up to the beginning of the bucket */
896 while (n
> 0 && lines
[n
- 1].get_pkg ())
899 /* part 2 - insert in sorted order in the bucket */
902 if (lines
[n
].get_category () || (lines
[n
].get_pkg ()
903 && strcasecmp (line
.get_pkg ()->name
, lines
[n
].get_pkg ()->name
) < 0))
908 else if (lines
[n
].get_pkg () == line
.get_pkg ())
916 /* insert at the end of this bucket */
922 _view::clear_view (void)
928 viewsplusplus(views theview
)
932 case VIEW_UNKNOWN
: return VIEW_PACKAGE_FULL
;
933 case VIEW_PACKAGE_FULL
: return VIEW_PACKAGE
;
934 case VIEW_PACKAGE
: return VIEW_CATEGORY
;
935 case VIEW_CATEGORY
: return NVIEW
;
936 default: return VIEW_UNKNOWN
;
941 _view::click (int row
, int x
)
945 if (lines
[row
].get_pkg ())
946 return lines
[row
].click (x
);
949 /* if we are the last line or the next line is a category too, expand */
950 if (row
== (nlines
-1) || lines
[row
+ 1].get_category ())
953 for (CategoryPackage
*catpkg
= lines
[row
].get_category ()->packages
; catpkg
; catpkg
= catpkg
->next
)
955 Package
* pkg
= getpkgbyname (catpkg
->pkgname
);
959 /* this is a nasty hack. It will go away when the hierarchy is coded */
962 if (lines
[n
].get_category () || (lines
[n
].get_pkg ()
963 && strcasecmp (pkg
->name
, lines
[n
].get_pkg ()->name
) < 0))
968 else if (lines
[n
].get_pkg () == pkg
)
976 /* insert at the end of this category */
981 return nlines
- count
;
986 int count
= 0, n
= row
+ 1;
987 while (n
< nlines
&! lines
[n
].get_category ())
989 memmove (&lines
[n
], &lines
[n
+ 1], (nlines
- n
) * sizeof (pick_line
));
1000 set_view_mode (HWND h
, views mode
)
1003 chooser
->set_view_mode (mode
);
1005 chooser
->clear_view ();
1006 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
1008 set_action (pkg
, 0);
1010 switch (chooser
->get_view_mode ())
1013 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
1014 if (!pkg
->exclude
&& !is_full_action (pkg
))
1015 chooser
->insert_pkg (pkg
);
1017 case VIEW_PACKAGE_FULL
:
1018 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
1020 chooser
->insert_pkg (pkg
);
1023 /* start collapsed. TODO: make this a chooser flag */
1024 for (Category
*cat
= category
; cat
; cat
= cat
->next
)
1025 chooser
->insert_category (cat
, CATEGORY_COLLAPSED
);
1032 GetClientRect (h
, &r
);
1034 memset (&si
, 0, sizeof (si
));
1035 si
.cbSize
= sizeof (si
);
1038 si
.nMax
= chooser
->headers
[chooser
->last_col
].x
+ chooser
->headers
[chooser
->last_col
].width
+ HMARGIN
;
1040 SetScrollInfo (h
, SB_HORZ
, &si
, TRUE
);
1042 si
.nMax
= chooser
->nlines
* row_height
;
1043 si
.nPage
= r
.bottom
- header_height
;
1044 SetScrollInfo (h
, SB_VERT
, &si
, TRUE
);
1046 scroll_ulc_x
= scroll_ulc_y
= 0;
1048 InvalidateRect (h
, &r
, TRUE
);
1051 SetFocus (nextbutton
);
1055 create_listview (HWND dlg
, RECT
*r
)
1058 lv
= CreateWindowEx (WS_EX_CLIENTEDGE
,
1061 WS_CHILD
| WS_HSCROLL
| WS_VSCROLL
| WS_VISIBLE
,
1063 r
->right
-r
->left
+ 1, r
->bottom
-r
->top
+ 1,
1065 (HMENU
) MAKEINTRESOURCE(IDC_CHOOSE_LIST
),
1068 ShowWindow (lv
, SW_SHOW
);
1069 HDC dc
= GetDC (lv
);
1070 sysfont
= GetStockObject (DEFAULT_GUI_FONT
);
1071 SelectObject (dc
, sysfont
);
1072 GetTextMetrics (dc
, &tm
);
1073 header_height
= tm
.tmHeight
+ 5 + 3;
1075 bitmap_dc
= CreateCompatibleDC (dc
);
1077 row_height
= (tm
.tmHeight
+ tm
.tmExternalLeading
+ ROW_MARGIN
);
1078 int irh
= tm
.tmExternalLeading
+ tm
.tmDescent
+ 11 + ROW_MARGIN
;
1079 if (row_height
< irh
)
1082 chooser
= new (view
) (VIEW_CATEGORY
, dc
);
1084 default_trust (lv
, TRUST_CURR
);
1085 set_view_mode (lv
, VIEW_CATEGORY
);
1086 if (!SetDlgItemText (dlg
, IDC_CHOOSE_VIEWCAPTION
, chooser
->mode_caption()))
1087 log (LOG_BABBLE
, "Failed to set View button caption %d", GetLastError() );
1088 for (Package
*foo
= package
; foo
->name
; foo
++)
1090 static int ta
[] = { IDC_CHOOSE_CURR
, 0 };
1091 rbset (dlg
, ta
, IDC_CHOOSE_CURR
);
1097 dialog_cmd (HWND h
, int id
, HWND hwndctl
, UINT code
)
1101 case IDC_CHOOSE_PREV
:
1102 default_trust (lv
, TRUST_PREV
);
1103 for (Package
*foo
= package
; foo
->name
; foo
++)
1105 set_view_mode (lv
, chooser
->get_view_mode ());
1107 case IDC_CHOOSE_CURR
:
1108 default_trust (lv
, TRUST_CURR
);
1109 for (Package
*foo
= package
; foo
->name
; foo
++)
1111 set_view_mode (lv
, chooser
->get_view_mode ());
1113 case IDC_CHOOSE_EXP
:
1114 default_trust (lv
, TRUST_TEST
);
1115 for (Package
*foo
= package
; foo
->name
; foo
++)
1117 set_view_mode (lv
, chooser
->get_view_mode ());
1119 case IDC_CHOOSE_VIEW
:
1120 set_view_mode (lv
, viewsplusplus (chooser
->get_view_mode ()));
1121 if (!SetDlgItemText (h
, IDC_CHOOSE_VIEWCAPTION
, chooser
->mode_caption()))
1122 log (LOG_BABBLE
, "Failed to set View button caption %d", GetLastError() );
1126 if (source
== IDC_SOURCE_CWD
)
1127 NEXT (IDD_S_INSTALL
);
1129 NEXT (IDD_S_DOWNLOAD
);
1134 if (source
== IDC_SOURCE_CWD
)
1147 GetParentRect (HWND parent
, HWND child
, RECT
*r
)
1150 GetWindowRect (child
, r
);
1153 ScreenToClient (parent
, &p
);
1158 ScreenToClient (parent
, &p
);
1163 static BOOL CALLBACK
1164 dialog_proc (HWND h
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1172 nextbutton
= GetDlgItem (h
, IDOK
);
1173 frame
= GetDlgItem (h
, IDC_LISTVIEW_POS
);
1174 choose_inst_text
= GetDlgItem(h
,IDC_CHOOSE_INST_TEXT
);
1175 if (source
== IDC_SOURCE_DOWNLOAD
)
1176 SetWindowText (choose_inst_text
, "Select packages to download ");
1178 SetWindowText (choose_inst_text
, "Select packages to install ");
1179 GetParentRect (h
, frame
, &r
);
1182 create_listview (h
, &r
);
1188 return HANDLE_WM_COMMAND (h
, wParam
, lParam
, dialog_cmd
);
1194 base (const char *s
)
1201 if ((*s
== '/' || *s
== ':' || *s
== '\\') && s
[1])
1209 find_tar_ext (const char *path
)
1211 char *p
= strchr (path
, '\0') - 7;
1216 if (strcmp (p
, ".tar.gz") != 0)
1219 else if (--p
<= path
|| strcmp (p
, ".tar.bz2") != 0)
1225 /* Parse a filename into package, version, and extension components. */
1227 parse_filename (const char *in_fn
, fileparse
& f
)
1230 char fn
[strlen (in_fn
) + 1];
1233 int n
= find_tar_ext (fn
);
1238 strcpy (f
.tail
, fn
+ n
);
1240 f
.pkg
[0] = f
.what
[0] = '\0';
1242 for (ver
= p
; *ver
; ver
++)
1243 if (*ver
== '-' || *ver
== '_')
1244 if (isdigit (ver
[1]))
1250 else if (strcasecmp (ver
, "-src") == 0 ||
1251 strcasecmp (ver
, "-patch") == 0)
1255 strcpy (f
.what
, strlwr (ver
));
1256 strcpy (f
.pkgtar
, p
);
1257 strcat (f
.pkgtar
, f
.tail
);
1258 ver
= strchr (ver
, '\0');
1267 p
= strchr (ver
, '\0');
1268 strcpy (f
.pkgtar
, in_fn
);
1269 if ((p
-= 4) >= ver
&& strcasecmp (p
, "-src") == 0)
1271 strcpy (f
.what
, "src");
1273 p
= f
.pkgtar
+ (p
- fn
) + 4;
1274 memcpy (p
- 4, p
, strlen (p
));
1276 else if ((p
-= 2) >= ver
&& strcasecmp (p
, "-patch") == 0)
1278 strcpy (f
.what
, "patch");
1280 p
= f
.pkgtar
+ (p
- fn
) + 6;
1281 memcpy (p
- 6, p
, strlen (p
));
1285 strcpy (f
.ver
, *ver
? ver
: "0.0");
1289 /* Return a pointer to a package given the name. */
1291 getpkgbyname (const char *pkgname
)
1293 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
1294 if (strcasecmp (pkg
->name
, pkgname
) == 0)
1300 /* Return a pointer to a category given the name. */
1302 getcategorybyname (const char *categoryname
)
1304 for (Category
*cat
= category
; cat
; cat
=cat
->next
)
1305 if (strcasecmp (cat
->name
, categoryname
) == 0)
1311 /* Return a pointer to a category of a given package given the name. */
1313 getpackagecategorybyname (Package
*pkg
, const char *categoryname
)
1315 for (Category
*cat
= pkg
->category
; cat
; cat
= cat
->next
)
1316 if (strcasecmp (cat
->name
, categoryname
) == 0)
1322 /* Find out where to put existing tar file in local directory in
1323 known package array. */
1325 scan2 (char *path
, unsigned int size
)
1330 if (!parse_filename (path
, f
))
1333 if (f
.what
[0] != '\0' && f
.what
[0] != 's')
1336 pkg
= getpkgbyname (f
.pkg
);
1340 /* Scan existing package list looking for a match between a known
1341 package from setup.ini and a tar archive on disk.
1342 While scanning, keep track of appropriate "holes" in the trust
1343 table where a tar file could be put if no known entry
1346 So, if setup.ini knows that ash-20010425-1.tar.gz is the current
1347 version and there is an ash-20010426-1.tar.gz in the current directory,
1348 the 20010426 version will be placed in the "test" slot, assuming that
1349 there is no test version listed in setup.ini. */
1352 Info
*maybe_hole
= NULL
;
1354 for (Info
*inf
= pkg
->infoscan
; inf
< pkg
->infoend
; inf
++)
1355 if (!inf
->version
|| inf
->derived
)
1362 else if ((cmp
= strcasecmp (f
.ver
, inf
->version
)) == 0)
1364 if (f
.what
[0] == 's')
1365 inf
->source_exists
= -1;
1367 inf
->install_exists
= -1;
1370 else if (!hole
&& maybe_hole
&& cmp
< 0)
1375 /* If maybe_hole != NULL, then we should be sitting at the "test"
1376 trust entry. Use that if there was nothing at all in the
1377 known package list. */
1378 if (!hole
&& maybe_hole
)
1381 /* If !hole, we didn't find this version in the known packages array
1382 and there was no place to put it. */
1386 /* The derived flag is set when we place info about a file in a slot
1387 iff there was nothing known about the file in the known package
1388 array. We try to put the highest numbered versions in the "empty"
1392 cmp
= strcasecmp (f
.ver
, hole
->version
) < 0;
1398 free (hole
->version
);
1400 free (hole
->source
);
1402 free (hole
->install
);
1406 /* Fill in the "hole", setting a flag that we derived this location
1407 from context rather than from setup.ini. */
1409 hole
->version
= strdup (f
.ver
);
1410 if (!hole
->source
&& f
.what
[0] == 's')
1412 hole
->source
= strdup (path
);
1413 hole
->source_exists
= -1;
1414 hole
->source_size
= size
;
1418 hole
->install
= strdup (path
);
1419 hole
->install_exists
= -1;
1420 hole
->install_size
= size
;
1425 scan_downloaded_files ()
1430 _Info::_Info (const char *_install
, const char *_version
, int _install_size
,
1431 const char *_source
, int _source_size
)
1433 memset (this, 0, sizeof (*this));
1434 install
= strdup (_install
);
1435 version
= strdup (_version
);
1436 install_size
= _install_size
;
1439 source
= strdup (_source
);
1440 source_size
= _source_size
;
1445 read_installed_db ()
1448 if (!get_root_dir ())
1451 char line
[1000], pkgname
[1000], inst
[1000], src
[1000];
1454 FILE *db
= fopen (cygpath ("/etc/setup/installed.db", 0), "rt");
1458 while (fgets (line
, 1000, db
))
1463 sscanf (line
, "%s %s %d %s %d", pkgname
, inst
, &instsz
, src
, &srcsz
);
1465 Package
*pkg
= getpkgbyname (pkgname
);
1467 parseable
= parse_filename (inst
, f
);
1473 pkg
= new_package (pkgname
);
1474 pkg
->info
[TRUST_CURR
].version
= strdup (f
.ver
);
1475 pkg
->info
[TRUST_CURR
].install
= strdup (inst
);
1476 pkg
->info
[TRUST_CURR
].install_size
= instsz
;
1479 pkg
->info
[TRUST_CURR
].source
= strdup (src
);
1480 pkg
->info
[TRUST_CURR
].source_size
= srcsz
;
1482 pkg
->installed_ix
= TRUST_CURR
;
1483 /* Exists on local system but not on download system */
1484 pkg
->exclude
= EXCLUDE_NOT_FOUND
;
1487 pkg
->installed
= new Info (inst
, f
.ver
, instsz
);
1489 if (!pkg
->installed_ix
)
1490 for (trusts t
= TRUST_PREV
; t
< NTRUST
; ((int) t
)++)
1491 if (pkg
->info
[t
].install
&& strcmp (f
.ver
, pkg
->info
[t
].version
) == 0)
1493 pkg
->installed_ix
= t
;
1501 package_sort (const void *va
, const void *vb
)
1503 Package
*a
= (Package
*)va
;
1504 Package
*b
= (Package
*)vb
;
1505 return strcasecmp (a
->name
, b
->name
);
1509 do_choose (HINSTANCE h
)
1514 bm_spin
= LoadImage (h
, MAKEINTRESOURCE (IDB_SPIN
), IMAGE_BITMAP
, 0, 0, 0);
1515 bm_rtarrow
= LoadImage (h
, MAKEINTRESOURCE (IDB_RTARROW
), IMAGE_BITMAP
,
1518 bm_checkyes
= LoadImage (h
, MAKEINTRESOURCE (IDB_CHECK_YES
), IMAGE_BITMAP
,
1520 bm_checkno
= LoadImage (h
, MAKEINTRESOURCE (IDB_CHECK_NO
), IMAGE_BITMAP
,
1522 bm_checkna
= LoadImage (h
, MAKEINTRESOURCE (IDB_CHECK_NA
), IMAGE_BITMAP
,
1525 register_windows (h
);
1527 if (source
== IDC_SOURCE_DOWNLOAD
|| source
== IDC_SOURCE_CWD
)
1528 scan_downloaded_files ();
1530 read_installed_db ();
1532 fill_missing_category ();
1534 qsort (package
, npackages
, sizeof (package
[0]), package_sort
);
1536 rv
= DialogBox (h
, MAKEINTRESOURCE (IDD_CHOOSE
), 0, dialog_proc
);
1538 fatal (IDS_DIALOG_FAILED
);
1540 log (LOG_BABBLE
, "Chooser results...");
1541 for (Package
*pkg
= package
; pkg
->name
; pkg
++)
1543 static char *infos
[] = {"nada", "prev", "curr", "test"};
1544 const char *trust
= ((pkg
->trust
== TRUST_PREV
) ? "prev"
1545 : (pkg
->trust
== TRUST_CURR
) ? "curr"
1546 : (pkg
->trust
== TRUST_TEST
) ? "test"
1548 const char *action
= choose_caption (pkg
);
1549 const char *installed
= ((pkg
->installed_ix
== -1) ? "none"
1550 : (pkg
->installed_ix
== TRUST_PREV
) ? "prev"
1551 : (pkg
->installed_ix
== TRUST_CURR
) ? "curr"
1552 : (pkg
->installed_ix
== TRUST_TEST
) ? "test"
1554 const char *excluded
= (pkg
->exclude
? "yes" : "no");
1556 log (LOG_BABBLE
, "[%s] action=%s trust=%s installed=%s excluded=%s"
1558 pkg
->name
, action
, trust
, installed
, excluded
,
1559 pkg
->srcpicked
? "yes" : "no");
1562 /* List categories the package belongs to */
1563 char *categories
= "";
1564 int categories_len
= 0;
1566 for (cp
= pkg
->category
; cp
; cp
= cp
->next
)
1568 categories_len
+= strlen (cp
->name
) + 2;
1570 if (categories_len
> 0)
1572 categories
= (char *) malloc (categories_len
);
1573 strcpy(categories
, pkg
->category
->name
);
1574 for (cp
= pkg
->category
->next
; cp
; cp
= cp
->next
)
1577 strcat (categories
, ", ");
1578 strcat (categories
, cp
->name
);
1580 log (LOG_BABBLE
, " categories=%s", categories
);
1586 /* List other packages this package depends on */
1587 char *requires
= "";
1588 int requires_len
= 0;
1590 for (dp
= pkg
->required
; dp
; dp
= dp
->next
)
1592 requires_len
+= strlen (dp
->package
) + 2;
1594 if (requires_len
> 0)
1596 requires
= (char *) malloc (requires_len
);
1597 strcpy(requires
, pkg
->required
->package
);
1598 for (dp
= pkg
->required
->next
; dp
; dp
= dp
->next
)
1601 strcat (requires
, ", ");
1602 strcat (requires
, dp
->package
);
1604 log (LOG_BABBLE
, " requires=%s", requires
);
1609 for (int t
= 1; t
< NTRUST
; t
++)
1611 if (pkg
->info
[t
].install
)
1612 log (LOG_BABBLE
, " [%s] ver=%s\n"
1613 " inst=%s %d exists=%s\n"
1614 " src=%s %d exists=%s",
1616 pkg
->info
[t
].version
?: "(none)",
1617 pkg
->info
[t
].install
?: "(none)",
1618 pkg
->info
[t
].install_size
,
1619 (pkg
->info
[t
].install_exists
) ? "yes" : "no",
1620 pkg
->info
[t
].source
?: "(none)",
1621 pkg
->info
[t
].source_size
,
1622 (pkg
->info
[t
].source_exists
) ? "yes" : "no");
This page took 0.183326 seconds and 4 git commands to generate.