]> cygwin.com Git - cygwin-apps/setup.git/blame - choose.cc
* Makefile.in (setup_version.c): Add back magic which allows detection of
[cygwin-apps/setup.git] / choose.cc
CommitLineData
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
29static 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"
63extern ThreeBarProgressPage Progress;
60c632b3 64
713bbe5f
DD
65static int initialized = 0;
66
42bf5b92 67static HWND lv, nextbutton, choose_inst_text;
97647369 68static PickView *chooser = NULL;
8f53e82a 69
97647369 70static void set_view_mode (HWND h, PickView::views mode);
cbfc4215 71
713bbe5f
DD
72static void
73paint (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
108static LRESULT CALLBACK
109list_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
115static LRESULT CALLBACK
116list_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
122static LRESULT CALLBACK
123list_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
183static LRESULT CALLBACK
184listview_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
240static void
241register_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
263static void
264set_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
294static void
295fill_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 307static void
c46a33a9 308default_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 348static void
97647369 349set_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 404static void
f557695e 405create_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
438static BOOL
439dialog_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 501static void
f557695e 502GetParentRect (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
518static BOOL CALLBACK
519dialog_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
550static void
551scan2 (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
658static void
659scan_downloaded_files ()
660{
661 find (".", scan2);
662}
663
713bbe5f 664void
ab57ceaa 665do_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
747extern void do_choose (HINSTANCE h, HWND owner);
748
749void
750do_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 763bool ChooserPage::Create ()
ab57ceaa
RC
764{
765 return PropertyPage::Create (IDD_CHOOSER);
766}
767
768void
769ChooserPage::OnActivate ()
770{
771 GetOwner ()->SetButtons (0);
772 PostMessage (WM_APP_START_CHOOSE);
773}
774
7c6ef2c3 775bool 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}
This page took 0.154579 seconds and 5 git commands to generate.