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