]>
Commit | Line | Data |
---|---|---|
23c9e63c | 1 | /* |
3467d79f | 2 | * Copyright (c) 2000, 2001 Red Hat, Inc. |
23c9e63c DD |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by DJ Delorie <dj@cygnus.com> | |
13 | * | |
14 | */ | |
15 | ||
16 | /* The purpose of this file is to let the user choose which packages | |
17 | to install, and which versions of the package when more than one | |
18 | version is provided. The "trust" level serves as an indication as | |
19 | to which version should be the default choice. At the moment, all | |
20 | we do is compare with previously installed packages to skip any | |
21 | that are already installed (by setting the action to ACTION_SAME). | |
22 | While the "trust" stuff is supported, it's not really implemented | |
23 | yet. We always prefer the "current" option. In the future, this | |
24 | file might have a user dialog added to let the user choose to not | |
25 | install packages, or to install packages that aren't installed by | |
26 | default. */ | |
27 | ||
4bb38dfa RC |
28 | #if 0 |
29 | static const char *cvsid = | |
f557695e | 30 | "\n%%% $Id$\n"; |
4bb38dfa | 31 | #endif |
8507f105 | 32 | |
23c9e63c | 33 | #include "win32.h" |
cbfc4215 | 34 | #include <commctrl.h> |
23c9e63c | 35 | #include <stdio.h> |
713bbe5f | 36 | #include <stdlib.h> |
60c632b3 | 37 | #include <io.h> |
713bbe5f | 38 | #include <ctype.h> |
ab57ceaa | 39 | #include <process.h> |
713bbe5f | 40 | |
23c9e63c DD |
41 | #include "dialog.h" |
42 | #include "resource.h" | |
43 | #include "state.h" | |
44 | #include "ini.h" | |
23c9e63c | 45 | #include "msg.h" |
89b1a15b | 46 | #include "log.h" |
4a83b7b0 | 47 | #include "find.h" |
fb087b80 | 48 | #include "filemanip.h" |
b24c88b3 | 49 | #include "io_stream.h" |
ab57ceaa | 50 | #include "propsheet.h" |
8f53e82a | 51 | #include "choose.h" |
7b606ae5 | 52 | #include "category.h" |
23c9e63c | 53 | |
7939f6d1 RC |
54 | #include "package_db.h" |
55 | #include "package_meta.h" | |
fa0c0d10 | 56 | #include "package_version.h" |
7c6ef2c3 | 57 | #include "cygpackage.h" |
7939f6d1 | 58 | |
97647369 RC |
59 | #include "PickView.h" |
60 | ||
60c632b3 | 61 | #include "port.h" |
ab57ceaa RC |
62 | #include "threebar.h" |
63 | extern ThreeBarProgressPage Progress; | |
60c632b3 | 64 | |
713bbe5f DD |
65 | static int initialized = 0; |
66 | ||
42bf5b92 | 67 | static HWND lv, nextbutton, choose_inst_text; |
97647369 | 68 | static PickView *chooser = NULL; |
8f53e82a | 69 | |
97647369 | 70 | static void set_view_mode (HWND h, PickView::views mode); |
cbfc4215 | 71 | |
713bbe5f DD |
72 | static void |
73 | paint (HWND hwnd) | |
23c9e63c | 74 | { |
713bbe5f DD |
75 | HDC hdc; |
76 | PAINTSTRUCT ps; | |
cc41a057 | 77 | int x, y; |
23c9e63c | 78 | |
713bbe5f | 79 | hdc = BeginPaint (hwnd, &ps); |
23c9e63c | 80 | |
97647369 | 81 | SelectObject (hdc, chooser->sysfont); |
fb087b80 | 82 | SetBkColor (hdc, GetSysColor (COLOR_WINDOW)); |
9eeb0e83 | 83 | SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)); |
23c9e63c | 84 | |
713bbe5f DD |
85 | RECT cr; |
86 | GetClientRect (hwnd, &cr); | |
87 | ||
97647369 RC |
88 | x = cr.left - chooser->scroll_ulc_x; |
89 | y = cr.top - chooser->scroll_ulc_y + chooser->header_height; | |
713bbe5f | 90 | |
97647369 | 91 | IntersectClipRect (hdc, cr.left, cr.top + chooser->header_height, cr.right, |
f557695e | 92 | cr.bottom); |
713bbe5f | 93 | |
cc41a057 | 94 | chooser->contents.paint (hdc, x, y, 0, (chooser->get_view_mode () == |
97647369 | 95 | PickView::views::Category) ? 0 : 1); |
5f48f258 | 96 | |
cbfc4215 | 97 | if (chooser->contents.itemcount () == 0) |
5f48f258 | 98 | { |
4bb38dfa | 99 | static const char *msg = "Nothing to Install/Update"; |
60c632b3 | 100 | if (source == IDC_SOURCE_DOWNLOAD) |
47f8d8b3 | 101 | msg = "Nothing to Download"; |
97647369 | 102 | TextOut (hdc, HMARGIN, chooser->header_height, msg, strlen (msg)); |
5f48f258 | 103 | } |
fb087b80 | 104 | |
713bbe5f DD |
105 | EndPaint (hwnd, &ps); |
106 | } | |
107 | ||
713bbe5f DD |
108 | static LRESULT CALLBACK |
109 | list_vscroll (HWND hwnd, HWND hctl, UINT code, int pos) | |
110 | { | |
97647369 | 111 | chooser->scroll (hwnd, SB_VERT, &chooser->scroll_ulc_y, code); |
2399c54d | 112 | return 0; |
713bbe5f DD |
113 | } |
114 | ||
115 | static LRESULT CALLBACK | |
116 | list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos) | |
117 | { | |
97647369 | 118 | chooser->scroll (hwnd, SB_HORZ, &chooser->scroll_ulc_x, code); |
2399c54d | 119 | return 0; |
713bbe5f DD |
120 | } |
121 | ||
122 | static LRESULT CALLBACK | |
123 | list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode) | |
124 | { | |
f557695e | 125 | int row, refresh; |
713bbe5f | 126 | |
cbfc4215 | 127 | if (chooser->contents.itemcount () == 0) |
8cfbc487 DD |
128 | return 0; |
129 | ||
97647369 | 130 | if (y < chooser->header_height) |
713bbe5f | 131 | return 0; |
97647369 RC |
132 | x += chooser->scroll_ulc_x; |
133 | y += chooser->scroll_ulc_y - chooser->header_height; | |
713bbe5f | 134 | |
97647369 | 135 | row = (y + ROW_MARGIN / 2) / chooser->row_height; |
713bbe5f | 136 | |
cbfc4215 | 137 | if (row < 0 || row >= chooser->contents.itemcount ()) |
713bbe5f DD |
138 | return 0; |
139 | ||
42a99ed1 | 140 | refresh = chooser->click (row, x); |
f557695e | 141 | |
8f53e82a RC |
142 | if (refresh) |
143 | { | |
144 | RECT r; | |
145 | GetClientRect (lv, &r); | |
146 | SCROLLINFO si; | |
147 | memset (&si, 0, sizeof (si)); | |
148 | si.cbSize = sizeof (si); | |
f557695e | 149 | si.fMask = SIF_ALL; /* SIF_RANGE was giving strange behaviour */ |
8f53e82a | 150 | si.nMin = 0; |
713bbe5f | 151 | |
97647369 RC |
152 | si.nMax = chooser->contents.itemcount () * chooser->row_height; |
153 | si.nPage = r.bottom - chooser->header_height; | |
42a99ed1 RC |
154 | |
155 | /* if we are under the minimum display count , | |
156 | * set the offset to 0 | |
157 | */ | |
4bb38dfa | 158 | if ((unsigned int) si.nMax <= si.nPage) |
97647369 RC |
159 | chooser->scroll_ulc_y = 0; |
160 | si.nPos = chooser->scroll_ulc_y; | |
42a99ed1 | 161 | |
8f53e82a | 162 | SetScrollInfo (lv, SB_VERT, &si, TRUE); |
3b9077d4 | 163 | |
8f53e82a | 164 | InvalidateRect (lv, &r, TRUE); |
713bbe5f | 165 | |
8f53e82a RC |
166 | } |
167 | else | |
168 | { | |
169 | RECT rect; | |
7c6ef2c3 RC |
170 | rect.left = |
171 | chooser->headers[chooser->new_col].x - chooser->scroll_ulc_x; | |
172 | rect.right = | |
173 | chooser->headers[chooser->src_col + 1].x - chooser->scroll_ulc_x; | |
174 | rect.top = | |
175 | chooser->header_height + row * chooser->row_height - | |
176 | chooser->scroll_ulc_y; | |
97647369 | 177 | rect.bottom = rect.top + chooser->row_height; |
8f53e82a RC |
178 | InvalidateRect (hwnd, &rect, TRUE); |
179 | } | |
2399c54d | 180 | return 0; |
713bbe5f DD |
181 | } |
182 | ||
183 | static LRESULT CALLBACK | |
184 | listview_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |
185 | { | |
6a748750 CF |
186 | switch (message) |
187 | { | |
188 | case WM_HSCROLL: | |
189 | return HANDLE_WM_HSCROLL (hwnd, wParam, lParam, list_hscroll); | |
190 | case WM_VSCROLL: | |
191 | return HANDLE_WM_VSCROLL (hwnd, wParam, lParam, list_vscroll); | |
192 | case WM_LBUTTONDOWN: | |
193 | return HANDLE_WM_LBUTTONDOWN (hwnd, wParam, lParam, list_click); | |
194 | case WM_PAINT: | |
195 | paint (hwnd); | |
196 | return 0; | |
cbfc4215 RC |
197 | case WM_NOTIFY: |
198 | { | |
199 | // pnmh = (LPNMHDR) lParam | |
cc41a057 RC |
200 | LPNMHEADER phdr = (LPNMHEADER) lParam; |
201 | switch (phdr->hdr.code) | |
202 | { | |
203 | case HDN_ITEMCHANGED: | |
204 | if (phdr->hdr.hwndFrom == chooser->ListHeader ()) | |
205 | { | |
206 | if (phdr->pitem && phdr->pitem->mask & HDI_WIDTH) | |
207 | chooser->headers[phdr->iItem].width = phdr->pitem->cxy; | |
208 | for (int i = 1; i <= chooser->last_col; i++) | |
209 | chooser->headers[i].x = | |
210 | chooser->headers[i - 1].x + chooser->headers[i - 1].width; | |
211 | RECT r; | |
212 | GetClientRect (hwnd, &r); | |
213 | SCROLLINFO si; | |
214 | si.cbSize = sizeof (si); | |
215 | si.fMask = SIF_ALL; | |
216 | GetScrollInfo (hwnd, SB_HORZ, &si); | |
217 | int oldMax = si.nMax; | |
218 | si.nMax = | |
219 | chooser->headers[chooser->last_col].x + | |
220 | chooser->headers[chooser->last_col].width; | |
221 | if (si.nTrackPos && oldMax > si.nMax) | |
222 | si.nTrackPos += si.nMax - oldMax; | |
223 | si.nPage = r.right; | |
224 | SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); | |
225 | InvalidateRect (hwnd, &r, TRUE); | |
226 | if (si.nTrackPos && oldMax > si.nMax) | |
97647369 | 227 | chooser->scroll (hwnd, SB_HORZ, &chooser->scroll_ulc_x, |
cc41a057 RC |
228 | SB_THUMBTRACK); |
229 | } | |
230 | break; | |
231 | default: | |
232 | break; | |
233 | } | |
cbfc4215 | 234 | } |
6a748750 CF |
235 | default: |
236 | return DefWindowProc (hwnd, message, wParam, lParam); | |
237 | } | |
713bbe5f DD |
238 | } |
239 | ||
240 | static void | |
241 | register_windows (HINSTANCE hinst) | |
242 | { | |
243 | WNDCLASSEX wcex; | |
244 | static int done = 0; | |
245 | ||
246 | if (done) | |
247 | return; | |
248 | done = 1; | |
249 | ||
250 | memset (&wcex, 0, sizeof (wcex)); | |
251 | wcex.cbSize = sizeof (WNDCLASSEX); | |
252 | wcex.style = CS_HREDRAW | CS_VREDRAW; | |
253 | wcex.lpfnWndProc = listview_proc; | |
254 | wcex.hInstance = hinst; | |
255 | wcex.hIcon = LoadIcon (0, IDI_APPLICATION); | |
256 | wcex.hCursor = LoadCursor (0, IDC_ARROW); | |
6a748750 | 257 | wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); |
713bbe5f DD |
258 | wcex.lpszClassName = "listview"; |
259 | ||
260 | RegisterClassEx (&wcex); | |
261 | } | |
262 | ||
60c632b3 CV |
263 | static void |
264 | set_existence () | |
265 | { | |
df62e023 RC |
266 | packagedb db; |
267 | /* Remove packages that are in the db, not installed, and have no | |
268 | mirror info. */ | |
269 | size_t n = 1; | |
270 | while (n <= db.packages.number ()) | |
271 | { | |
272 | packagemeta & pkg = *db.packages[n]; | |
273 | bool mirrors = false; | |
274 | size_t o = 1; | |
275 | while (o <= pkg.versions.number () && !mirrors) | |
276 | { | |
277 | packageversion & ver = *pkg.versions[o]; | |
7c6ef2c3 RC |
278 | if (((source != IDC_SOURCE_CWD) && (ver.bin.sites.number () |
279 | || ver.src.sites.number ())) | |
280 | || ver.bin.Cached () || ver.src.Cached ()) | |
df62e023 RC |
281 | mirrors = true; |
282 | ++o; | |
283 | } | |
284 | if (!pkg.installed && !mirrors) | |
7c6ef2c3 RC |
285 | { |
286 | packagemeta *pkgm = db.packages.removebyindex (n); | |
df62e023 RC |
287 | delete pkgm; |
288 | } | |
289 | else | |
290 | ++n; | |
291 | } | |
713bbe5f DD |
292 | } |
293 | ||
8f53e82a RC |
294 | static void |
295 | fill_missing_category () | |
296 | { | |
7b606ae5 | 297 | packagedb db; |
df62e023 | 298 | for (size_t n = 1; n <= db.packages.number (); n++) |
cbfc4215 | 299 | { |
cc41a057 | 300 | packagemeta & pkg = *db.packages[n]; |
cbfc4215 | 301 | if (!pkg.Categories.number ()) |
cc41a057 | 302 | pkg.add_category (db.categories.registerbykey ("Misc")); |
d343da15 | 303 | pkg.add_category (db.categories.registerbykey ("All")); |
cbfc4215 | 304 | } |
3467d79f CF |
305 | } |
306 | ||
713bbe5f | 307 | static void |
c46a33a9 | 308 | default_trust (HWND h, trusts trust) |
713bbe5f | 309 | { |
97647369 | 310 | chooser->deftrust = trust; |
bb849dbd | 311 | packagedb db; |
df62e023 | 312 | for (size_t n = 1; n <= db.packages.number (); n++) |
bb849dbd | 313 | { |
cc41a057 | 314 | packagemeta & pkg = *db.packages[n]; |
cbfc4215 RC |
315 | if (pkg.installed |
316 | || pkg.Categories.getbykey (db.categories.registerbykey ("Base")) | |
317 | || pkg.Categories.getbykey (db.categories.registerbykey ("Misc"))) | |
bb849dbd | 318 | { |
97647369 | 319 | pkg.desired = pkg.trustp (trust); |
cbfc4215 | 320 | if (pkg.desired) |
bb849dbd | 321 | { |
cc41a057 | 322 | pkg.desired->binpicked = pkg.desired == pkg.installed ? 0 : 1; |
cbfc4215 | 323 | pkg.desired->srcpicked = 0; |
bb849dbd RC |
324 | } |
325 | } | |
326 | else | |
cbfc4215 | 327 | pkg.desired = 0; |
bb849dbd | 328 | } |
713bbe5f DD |
329 | RECT r; |
330 | GetClientRect (h, &r); | |
331 | InvalidateRect (h, &r, TRUE); | |
332 | if (nextbutton) | |
333 | SetFocus (nextbutton); | |
df62e023 RC |
334 | // and then do the same for categories with no packages. |
335 | size_t n = 1; | |
336 | while (n <= db.categories.number ()) | |
337 | { | |
338 | if (!db.categories[n]->packages) | |
7c6ef2c3 RC |
339 | { |
340 | Category *cat = db.categories.removebyindex (n); | |
341 | delete cat; | |
342 | } | |
df62e023 RC |
343 | else |
344 | ++n; | |
345 | } | |
713bbe5f DD |
346 | } |
347 | ||
8f53e82a | 348 | static void |
97647369 | 349 | set_view_mode (HWND h, PickView::views mode) |
8f53e82a | 350 | { |
8f53e82a RC |
351 | chooser->set_view_mode (mode); |
352 | ||
353 | chooser->clear_view (); | |
bb849dbd | 354 | packagedb db; |
97647369 | 355 | if (chooser->get_view_mode () == PickView::views::Package) |
8f53e82a | 356 | { |
df62e023 | 357 | for (size_t n = 1; n <= db.packages.number (); n++) |
cbfc4215 | 358 | { |
cc41a057 | 359 | packagemeta & pkg = *db.packages[n]; |
cbfc4215 RC |
360 | if ((!pkg.desired && pkg.installed) |
361 | || (pkg.desired | |
cc41a057 RC |
362 | && (pkg.desired->srcpicked || pkg.desired->binpicked))) |
363 | chooser->insert_pkg (pkg); | |
cbfc4215 | 364 | } |
ad3c7385 | 365 | } |
97647369 | 366 | else if (chooser->get_view_mode () == PickView::views::PackageFull) |
ad3c7385 | 367 | { |
df62e023 | 368 | for (size_t n = 1; n <= db.packages.number (); n++) |
cbfc4215 | 369 | { |
cc41a057 | 370 | packagemeta & pkg = *db.packages[n]; |
cbfc4215 RC |
371 | chooser->insert_pkg (pkg); |
372 | } | |
ad3c7385 | 373 | } |
97647369 | 374 | else if (chooser->get_view_mode () == PickView::views::Category) |
ad3c7385 | 375 | { |
bb849dbd | 376 | /* start collapsed. TODO: make this a chooser flag */ |
4fe323f9 | 377 | for (size_t n = 1; n <= db.categories.number (); n++) |
cbfc4215 | 378 | chooser->insert_category (db.categories[n], CATEGORY_COLLAPSED); |
8f53e82a RC |
379 | } |
380 | ||
713bbe5f DD |
381 | RECT r; |
382 | GetClientRect (h, &r); | |
383 | SCROLLINFO si; | |
384 | memset (&si, 0, sizeof (si)); | |
385 | si.cbSize = sizeof (si); | |
386 | si.fMask = SIF_ALL; | |
387 | si.nMin = 0; | |
cc41a057 | 388 | si.nMax = chooser->headers[chooser->last_col].x + chooser->headers[chooser->last_col].width; // + HMARGIN; |
713bbe5f DD |
389 | si.nPage = r.right; |
390 | SetScrollInfo (h, SB_HORZ, &si, TRUE); | |
391 | ||
97647369 RC |
392 | si.nMax = chooser->contents.itemcount () * chooser->row_height; |
393 | si.nPage = r.bottom - chooser->header_height; | |
713bbe5f DD |
394 | SetScrollInfo (h, SB_VERT, &si, TRUE); |
395 | ||
97647369 | 396 | chooser->scroll_ulc_x = chooser->scroll_ulc_y = 0; |
713bbe5f DD |
397 | |
398 | InvalidateRect (h, &r, TRUE); | |
399 | ||
400 | if (nextbutton) | |
401 | SetFocus (nextbutton); | |
402 | } | |
403 | ||
713bbe5f | 404 | static void |
f557695e | 405 | create_listview (HWND dlg, RECT * r) |
713bbe5f | 406 | { |
713bbe5f | 407 | lv = CreateWindowEx (WS_EX_CLIENTEDGE, |
47f8d8b3 CF |
408 | "listview", |
409 | "listviewwindow", | |
410 | WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, | |
411 | r->left, r->top, | |
f557695e | 412 | r->right - r->left + 1, r->bottom - r->top + 1, |
47f8d8b3 | 413 | dlg, |
f557695e RC |
414 | (HMENU) MAKEINTRESOURCE (IDC_CHOOSE_LIST), |
415 | hinstance, 0); | |
713bbe5f | 416 | ShowWindow (lv, SW_SHOW); |
d343da15 | 417 | packagedb db; |
7c6ef2c3 RC |
418 | chooser = |
419 | new PickView (PickView::views::Category, lv, | |
420 | db.categories.registerbykey ("All")); | |
713bbe5f | 421 | |
713bbe5f | 422 | default_trust (lv, TRUST_CURR); |
97647369 | 423 | set_view_mode (lv, PickView::views::Category); |
f557695e | 424 | if (!SetDlgItemText (dlg, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ())) |
b24c88b3 RC |
425 | log (LOG_BABBLE, "Failed to set View button caption %ld", |
426 | GetLastError ()); | |
df62e023 | 427 | for (size_t n = 1; n <= db.packages.number (); n++) |
cbfc4215 | 428 | { |
cc41a057 | 429 | packagemeta & pkg = *db.packages[n]; |
97647369 | 430 | pkg.set_requirements (chooser->deftrust); |
cbfc4215 | 431 | } |
bb849dbd | 432 | /* FIXME: do we need to init the desired fields ? */ |
60c632b3 CV |
433 | static int ta[] = { IDC_CHOOSE_CURR, 0 }; |
434 | rbset (dlg, ta, IDC_CHOOSE_CURR); | |
d07591a3 | 435 | |
713bbe5f DD |
436 | } |
437 | ||
438 | static BOOL | |
439 | dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) | |
440 | { | |
bb849dbd | 441 | packagedb db; |
713bbe5f DD |
442 | switch (id) |
443 | { | |
713bbe5f DD |
444 | case IDC_CHOOSE_PREV: |
445 | default_trust (lv, TRUST_PREV); | |
df62e023 | 446 | for (size_t n = 1; n <= db.packages.number (); n++) |
cbfc4215 | 447 | { |
cc41a057 | 448 | packagemeta & pkg = *db.packages[n]; |
97647369 | 449 | pkg.set_requirements (TRUST_PREV); |
cbfc4215 | 450 | } |
8f53e82a | 451 | set_view_mode (lv, chooser->get_view_mode ()); |
713bbe5f DD |
452 | break; |
453 | case IDC_CHOOSE_CURR: | |
454 | default_trust (lv, TRUST_CURR); | |
df62e023 | 455 | for (size_t n = 1; n <= db.packages.number (); n++) |
cbfc4215 | 456 | { |
cc41a057 | 457 | packagemeta & pkg = *db.packages[n]; |
97647369 | 458 | pkg.set_requirements (TRUST_CURR); |
cbfc4215 | 459 | } |
8f53e82a | 460 | set_view_mode (lv, chooser->get_view_mode ()); |
713bbe5f DD |
461 | break; |
462 | case IDC_CHOOSE_EXP: | |
463 | default_trust (lv, TRUST_TEST); | |
df62e023 | 464 | for (size_t n = 1; n <= db.packages.number (); n++) |
cbfc4215 | 465 | { |
cc41a057 | 466 | packagemeta & pkg = *db.packages[n]; |
97647369 | 467 | pkg.set_requirements (TRUST_TEST); |
cbfc4215 | 468 | } |
8f53e82a | 469 | set_view_mode (lv, chooser->get_view_mode ()); |
713bbe5f | 470 | break; |
8f53e82a | 471 | case IDC_CHOOSE_VIEW: |
ad3c7385 | 472 | set_view_mode (lv, ++chooser->get_view_mode ()); |
f557695e RC |
473 | if (!SetDlgItemText |
474 | (h, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ())) | |
4bb38dfa | 475 | log (LOG_BABBLE, "Failed to set View button caption %ld", |
f557695e | 476 | GetLastError ()); |
713bbe5f DD |
477 | break; |
478 | ||
479 | case IDOK: | |
480 | if (source == IDC_SOURCE_CWD) | |
47f8d8b3 | 481 | NEXT (IDD_S_INSTALL); |
713bbe5f | 482 | else |
47f8d8b3 | 483 | NEXT (IDD_S_DOWNLOAD); |
713bbe5f DD |
484 | break; |
485 | ||
486 | case IDC_BACK: | |
487 | initialized = 0; | |
488 | if (source == IDC_SOURCE_CWD) | |
45c2d7d3 | 489 | NEXT (IDD_LOCAL_DIR); |
713bbe5f | 490 | else |
47f8d8b3 | 491 | NEXT (IDD_SITE); |
713bbe5f DD |
492 | break; |
493 | ||
494 | case IDCANCEL: | |
495 | NEXT (0); | |
496 | break; | |
497 | } | |
4bb38dfa | 498 | return 0; |
713bbe5f | 499 | } |
23c9e63c | 500 | |
713bbe5f | 501 | static void |
f557695e | 502 | GetParentRect (HWND parent, HWND child, RECT * r) |
713bbe5f DD |
503 | { |
504 | POINT p; | |
505 | GetWindowRect (child, r); | |
506 | p.x = r->left; | |
507 | p.y = r->top; | |
508 | ScreenToClient (parent, &p); | |
509 | r->left = p.x; | |
510 | r->top = p.y; | |
511 | p.x = r->right; | |
512 | p.y = r->bottom; | |
513 | ScreenToClient (parent, &p); | |
514 | r->right = p.x; | |
515 | r->bottom = p.y; | |
516 | } | |
517 | ||
518 | static BOOL CALLBACK | |
519 | dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) | |
520 | { | |
713bbe5f DD |
521 | HWND frame; |
522 | RECT r; | |
523 | switch (message) | |
524 | { | |
525 | case WM_INITDIALOG: | |
526 | nextbutton = GetDlgItem (h, IDOK); | |
527 | frame = GetDlgItem (h, IDC_LISTVIEW_POS); | |
f557695e | 528 | choose_inst_text = GetDlgItem (h, IDC_CHOOSE_INST_TEXT); |
42bf5b92 | 529 | if (source == IDC_SOURCE_DOWNLOAD) |
47f8d8b3 | 530 | SetWindowText (choose_inst_text, "Select packages to download "); |
42bf5b92 | 531 | else |
47f8d8b3 | 532 | SetWindowText (choose_inst_text, "Select packages to install "); |
713bbe5f DD |
533 | GetParentRect (h, frame, &r); |
534 | r.top += 2; | |
535 | r.bottom -= 2; | |
536 | create_listview (h, &r); | |
ab57ceaa | 537 | |
713bbe5f DD |
538 | #if 0 |
539 | load_dialog (h); | |
540 | #endif | |
42a99ed1 | 541 | return TRUE; |
713bbe5f DD |
542 | case WM_COMMAND: |
543 | return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd); | |
544 | } | |
545 | return FALSE; | |
546 | } | |
547 | ||
1b13eeec CF |
548 | /* Find out where to put existing tar file in local directory in |
549 | known package array. */ | |
85b43844 CF |
550 | static void |
551 | scan2 (char *path, unsigned int size) | |
552 | { | |
bb849dbd | 553 | packagemeta *pkg; |
85b43844 CF |
554 | fileparse f; |
555 | ||
556 | if (!parse_filename (path, f)) | |
557 | return; | |
558 | ||
7c6ef2c3 RC |
559 | #if 0 |
560 | // only process source package files? | |
561 | if (f.what.size () != 0 && f.what.cstr_oneuse ()[0] != 's') | |
85b43844 | 562 | return; |
7c6ef2c3 | 563 | #endif |
85b43844 | 564 | |
bb849dbd | 565 | packagedb db; |
cbfc4215 | 566 | pkg = db.packages.getbykey (f.pkg); |
c46a33a9 | 567 | if (pkg == NULL) |
85b43844 CF |
568 | return; |
569 | ||
1b13eeec | 570 | /* Scan existing package list looking for a match between a known |
bb849dbd | 571 | package and a tar archive on disk. |
1b13eeec CF |
572 | While scanning, keep track of appropriate "holes" in the trust |
573 | table where a tar file could be put if no known entry | |
574 | exists. | |
575 | ||
bb849dbd RC |
576 | We have 4 specific insertion points and one generic point. |
577 | The generic point is in versioned order in the package version array. | |
578 | The specific points are | |
579 | *installed | |
580 | *prev | |
581 | *curr | |
582 | *exp. | |
583 | ||
584 | if the version number matches a version in the db, | |
585 | we simply add this as a mirror source to that version. | |
586 | If it matches no version, we add a new version to the db. | |
587 | ||
588 | Lastly if the version number does not matche one of installed/prev/current/exp | |
589 | AND we had to create a new version entry | |
590 | we apply the following heuristic: | |
591 | if there is no exp, we link this in exp. | |
592 | If there is an exp and this is higher, we link this in exp, and | |
593 | if there is no curr, bump what was in exp to curr. If there was a curr, we leave it be. | |
594 | if this is lower than exp, and there is no curr, link as curr. If there is a curr, leave it be. | |
595 | If this is lower than curr, and there is no prev, link as prev, if there is a prev, leave it be. | |
596 | ||
597 | Whilst this logic is potentially wrong from time to time, it guarantees that | |
598 | setup.ini defined stability won't be altered unintentially. An alternative is to | |
599 | mark setup.ini defined prev/curr/exp packages as such, when this algorithm, can | |
600 | get smarter. | |
601 | ||
1b13eeec CF |
602 | So, if setup.ini knows that ash-20010425-1.tar.gz is the current |
603 | version and there is an ash-20010426-1.tar.gz in the current directory, | |
604 | the 20010426 version will be placed in the "test" slot, assuming that | |
605 | there is no test version listed in setup.ini. */ | |
606 | ||
bb849dbd RC |
607 | int added = 0; |
608 | for (size_t n = 1; n <= pkg->versions.number (); n++) | |
80429b97 | 609 | { |
3c054baf | 610 | if (!f.ver.casecompare (pkg->versions[n]->Canonical_version ())) |
d4a4527d | 611 | { |
7c6ef2c3 RC |
612 | if (f.what == String ()) |
613 | { | |
614 | //bin package | |
615 | pkg->versions[n]->bin.set_cached (String ("file://") + path); | |
616 | } | |
617 | else if (f.what == "src") | |
618 | { | |
619 | //src package | |
620 | pkg->versions[n]->src.set_cached (String ("file://") + path); | |
621 | } | |
bb849dbd | 622 | added = 1; |
d4a4527d RC |
623 | } |
624 | } | |
bb849dbd | 625 | if (!added) |
d4a4527d | 626 | { |
7c6ef2c3 RC |
627 | #if 0 |
628 | // Do we want old versions to show up | |
629 | packageversion *pv = new cygpackage (f.pkg); | |
630 | ((cygpackage *) pv)->set_canonical_version (f.ver); | |
631 | if (!f.what.size ()) | |
632 | pv->bin.set_cached (String ("file://") + path); | |
633 | else | |
634 | // patch or src, assume src until someone complains | |
635 | pv->src.set_cached (String ("file://") + path); | |
636 | pkg->add_version (*pv); | |
637 | ||
638 | #endif | |
bb849dbd RC |
639 | |
640 | /* And now the hole finder */ | |
641 | #if 0 | |
642 | if (!pkg->exp) | |
643 | pkg->exp = thenewver; | |
644 | else if (strcasecmp (f.ver, pkg->versions[n]->Canonicalversion ()) < 0) | |
645 | /* try curr */ | |
646 | if (!pkg->curr) | |
647 | pkg->curr = thenewver; | |
648 | else if (strcasecmp (f.ver, pkg->versions[n]->Canonicalversion ()) < | |
649 | 0) | |
650 | /* try prev */ | |
651 | if (!pkg->prev) | |
652 | pkg->prev = thenewver; | |
653 | #endif | |
d4a4527d | 654 | } |
bb849dbd | 655 | |
4a83b7b0 DD |
656 | } |
657 | ||
658 | static void | |
659 | scan_downloaded_files () | |
660 | { | |
661 | find (".", scan2); | |
662 | } | |
663 | ||
713bbe5f | 664 | void |
ab57ceaa | 665 | do_choose (HINSTANCE h, HWND owner) |
713bbe5f | 666 | { |
c46a33a9 | 667 | int rv; |
713bbe5f DD |
668 | |
669 | nextbutton = 0; | |
3b9077d4 | 670 | |
713bbe5f DD |
671 | register_windows (h); |
672 | ||
60c632b3 | 673 | if (source == IDC_SOURCE_DOWNLOAD || source == IDC_SOURCE_CWD) |
4a83b7b0 | 674 | scan_downloaded_files (); |
fb087b80 | 675 | |
60c632b3 | 676 | set_existence (); |
8f53e82a | 677 | fill_missing_category (); |
713bbe5f | 678 | |
ab57ceaa | 679 | rv = DialogBox (h, MAKEINTRESOURCE (IDD_CHOOSE), owner, dialog_proc); |
713bbe5f | 680 | if (rv == -1) |
ab57ceaa | 681 | fatal (owner, IDS_DIALOG_FAILED); |
713bbe5f | 682 | |
89b1a15b | 683 | log (LOG_BABBLE, "Chooser results..."); |
bb849dbd | 684 | packagedb db; |
df62e023 | 685 | for (size_t n = 1; n <= db.packages.number (); n++) |
89b1a15b | 686 | { |
cc41a057 | 687 | packagemeta & pkg = *db.packages[n]; |
bb849dbd | 688 | // static const char *infos[] = { "nada", "prev", "curr", "test" }; |
cbfc4215 RC |
689 | const char *trust = ((pkg.desired == pkg.prev) ? "prev" |
690 | : (pkg.desired == pkg.curr) ? "curr" | |
691 | : (pkg.desired == pkg.exp) ? "test" : "unknown"); | |
3c054baf RC |
692 | String action = pkg.action_caption (); |
693 | String const installed = | |
cbfc4215 | 694 | pkg.installed ? pkg.installed->Canonical_version () : "none"; |
bb849dbd RC |
695 | |
696 | log (LOG_BABBLE, "[%s] action=%s trust=%s installed=%s" | |
2dada532 | 697 | " src?=%s", |
7c6ef2c3 RC |
698 | pkg.name.cstr_oneuse (), action.cstr_oneuse (), trust, |
699 | installed.cstr_oneuse (), pkg.desired | |
700 | && pkg.desired->srcpicked ? "yes" : "no"); | |
cbfc4215 | 701 | if (pkg.Categories.number ()) |
2dada532 CF |
702 | { |
703 | /* List categories the package belongs to */ | |
3c054baf RC |
704 | String all_categories = pkg.Categories[1]->key.name; |
705 | for (size_t n = 2; n <= pkg.Categories.number (); n++) | |
7c6ef2c3 | 706 | all_categories += String (", ") + pkg.Categories[n]->key.name; |
2dada532 | 707 | |
3c054baf | 708 | log (LOG_BABBLE, String (" categories=") + all_categories); |
2dada532 | 709 | } |
cbfc4215 | 710 | if (pkg.desired && pkg.desired->required) |
2dada532 CF |
711 | { |
712 | /* List other packages this package depends on */ | |
7c6ef2c3 | 713 | Dependency *dp = pkg.desired->required; |
3c054baf | 714 | String requires = dp->package; |
7c6ef2c3 RC |
715 | for (dp = dp->next; dp; dp = dp->next) |
716 | if (dp->package.size ()) | |
3c054baf | 717 | requires += String (", ") + dp->package; |
2dada532 | 718 | |
7c6ef2c3 | 719 | log (LOG_BABBLE, String (" requires=") + requires); |
2dada532 | 720 | } |
bb849dbd RC |
721 | #if 0 |
722 | ||
723 | /* FIXME: Reinstate this code, but spit out all mirror sites */ | |
2dada532 | 724 | |
c46a33a9 | 725 | for (int t = 1; t < NTRUST; t++) |
47f8d8b3 | 726 | { |
c46a33a9 | 727 | if (pkg->info[t].install) |
2dada532 | 728 | log (LOG_BABBLE, " [%s] ver=%s\n" |
f557695e RC |
729 | " inst=%s %d exists=%s\n" |
730 | " src=%s %d exists=%s", | |
47f8d8b3 | 731 | infos[t], |
f557695e RC |
732 | pkg->info[t].version ? : "(none)", |
733 | pkg->info[t].install ? : "(none)", | |
c46a33a9 | 734 | pkg->info[t].install_size, |
3467d79f | 735 | (pkg->info[t].install_exists) ? "yes" : "no", |
f557695e | 736 | pkg->info[t].source ? : "(none)", |
c46a33a9 | 737 | pkg->info[t].source_size, |
2dada532 | 738 | (pkg->info[t].source_exists) ? "yes" : "no"); |
47f8d8b3 | 739 | } |
bb849dbd | 740 | #endif |
89b1a15b | 741 | } |
713bbe5f | 742 | } |
ab57ceaa RC |
743 | |
744 | #define WM_APP_START_CHOOSE WM_APP+0 | |
745 | #define WM_APP_CHOOSE_IS_FINISHED WM_APP+1 | |
746 | ||
747 | extern void do_choose (HINSTANCE h, HWND owner); | |
748 | ||
749 | void | |
750 | do_choose_thread (void *p) | |
751 | { | |
752 | ChooserPage *cp; | |
753 | ||
754 | cp = static_cast < ChooserPage * >(p); | |
755 | ||
756 | do_choose (cp->GetInstance (), cp->GetHWND ()); | |
757 | ||
758 | cp->PostMessage (WM_APP_CHOOSE_IS_FINISHED); | |
759 | ||
760 | _endthread (); | |
761 | } | |
762 | ||
7c6ef2c3 | 763 | bool ChooserPage::Create () |
ab57ceaa RC |
764 | { |
765 | return PropertyPage::Create (IDD_CHOOSER); | |
766 | } | |
767 | ||
768 | void | |
769 | ChooserPage::OnActivate () | |
770 | { | |
771 | GetOwner ()->SetButtons (0); | |
772 | PostMessage (WM_APP_START_CHOOSE); | |
773 | } | |
774 | ||
7c6ef2c3 | 775 | bool ChooserPage::OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam) |
ab57ceaa RC |
776 | { |
777 | switch (uMsg) | |
778 | { | |
779 | case WM_APP_START_CHOOSE: | |
780 | { | |
781 | // Start the chooser thread. | |
782 | _beginthread (do_choose_thread, 0, this); | |
783 | break; | |
784 | } | |
785 | case WM_APP_CHOOSE_IS_FINISHED: | |
786 | { | |
787 | switch (next_dialog) | |
788 | { | |
789 | case 0: | |
790 | { | |
791 | // Cancel | |
792 | GetOwner ()->PressButton (PSBTN_CANCEL); | |
793 | break; | |
794 | } | |
795 | case IDD_LOCAL_DIR: | |
796 | case IDD_SITE: | |
797 | { | |
798 | // Back | |
799 | GetOwner ()->SetActivePageByID (next_dialog); | |
800 | break; | |
801 | } | |
802 | case IDD_S_DOWNLOAD: | |
803 | { | |
804 | // Next, start download from internet | |
805 | Progress.SetActivateTask (WM_APP_START_DOWNLOAD); | |
806 | GetOwner ()->SetActivePageByID (IDD_INSTATUS); | |
807 | break; | |
808 | } | |
809 | case IDD_S_INSTALL: | |
810 | { | |
811 | // Next, install | |
812 | Progress.SetActivateTask (WM_APP_START_INSTALL); | |
813 | GetOwner ()->SetActivePageByID (IDD_INSTATUS); | |
814 | break; | |
815 | } | |
816 | } | |
817 | } | |
818 | default: | |
819 | return false; | |
820 | break; | |
821 | } | |
822 | return true; | |
823 | } |