]>
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" |
aa1e3b4d | 44 | #include "LogSingleton.h" |
fb087b80 | 45 | #include "filemanip.h" |
b24c88b3 | 46 | #include "io_stream.h" |
ab57ceaa | 47 | #include "propsheet.h" |
8f53e82a | 48 | #include "choose.h" |
7b606ae5 | 49 | #include "category.h" |
23c9e63c | 50 | |
7939f6d1 RC |
51 | #include "package_db.h" |
52 | #include "package_meta.h" | |
fa0c0d10 | 53 | #include "package_version.h" |
7939f6d1 | 54 | |
97647369 RC |
55 | #include "PickView.h" |
56 | ||
60c632b3 | 57 | #include "port.h" |
ab57ceaa | 58 | #include "threebar.h" |
58ee6135 RC |
59 | |
60 | #include "download.h" | |
6625e635 RC |
61 | |
62 | using namespace std; | |
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); | |
e0aec95e | 154 | si.fMask = SIF_ALL | SIF_DISABLENOSCROLL; /* 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); | |
e0aec95e | 221 | si.fMask = SIF_ALL | SIF_DISABLENOSCROLL; |
cc41a057 RC |
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 | 272 | packagedb db; |
3c196821 | 273 | /* binary packages */ |
df62e023 | 274 | /* Remove packages that are in the db, not installed, and have no |
3c196821 | 275 | mirror info and are not cached for both binary and source packages. */ |
cfae3b8d RC |
276 | vector <packagemeta *>::iterator i = db.packages.begin (); |
277 | while (i != db.packages.end ()) | |
df62e023 | 278 | { |
cfae3b8d | 279 | packagemeta & pkg = **i; |
3c196821 RC |
280 | if (!pkg.installed && !pkg.accessible() && |
281 | !pkg.sourceAccessible() ) | |
7c6ef2c3 | 282 | { |
cfae3b8d | 283 | packagemeta *pkgm = *i; |
df62e023 | 284 | delete pkgm; |
cfae3b8d | 285 | i = db.packages.erase (i); |
df62e023 RC |
286 | } |
287 | else | |
cfae3b8d | 288 | ++i; |
df62e023 | 289 | } |
3c196821 RC |
290 | #if 0 |
291 | /* remove any source packages which are not accessible */ | |
292 | vector <packagemeta *>::iterator i = db.sourcePackages.begin(); | |
293 | while (i != db.sourcePackages.end()) | |
294 | { | |
295 | packagemeta & pkg = **i; | |
296 | if (!packageAccessible (pkg)) | |
297 | { | |
298 | packagemeta *pkgm = *i; | |
299 | delete pkgm; | |
300 | i = db.sourcePackages.erase (i); | |
301 | } | |
302 | else | |
303 | ++i; | |
304 | } | |
305 | #endif | |
713bbe5f DD |
306 | } |
307 | ||
8f53e82a RC |
308 | static void |
309 | fill_missing_category () | |
310 | { | |
7b606ae5 | 311 | packagedb db; |
cfae3b8d RC |
312 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
313 | i != db.packages.end (); ++i) | |
cbfc4215 | 314 | { |
cfae3b8d | 315 | packagemeta & pkg = **i; |
405d7186 | 316 | if (!pkg.categories.size ()) |
0cf68afd RC |
317 | pkg.add_category ("Misc"); |
318 | pkg.add_category ("All"); | |
cbfc4215 | 319 | } |
3467d79f CF |
320 | } |
321 | ||
713bbe5f | 322 | static void |
c46a33a9 | 323 | default_trust (HWND h, trusts trust) |
713bbe5f | 324 | { |
97647369 | 325 | chooser->deftrust = trust; |
bb849dbd | 326 | packagedb db; |
cfae3b8d RC |
327 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
328 | i != db.packages.end (); ++i) | |
bb849dbd | 329 | { |
cfae3b8d | 330 | packagemeta & pkg = **i; |
cbfc4215 | 331 | if (pkg.installed |
405d7186 RC |
332 | || pkg.categories.find ("Base") != pkg.categories.end () |
333 | || pkg.categories.find ("Misc") != pkg.categories.end ()) | |
bb849dbd | 334 | { |
97647369 | 335 | pkg.desired = pkg.trustp (trust); |
cbfc4215 | 336 | if (pkg.desired) |
528a8edb RC |
337 | pkg.desired.pick (pkg.desired.accessible() |
338 | && pkg.desired != pkg.installed); | |
bb849dbd RC |
339 | } |
340 | else | |
3c196821 | 341 | pkg.desired = packageversion (); |
bb849dbd | 342 | } |
713bbe5f DD |
343 | RECT r; |
344 | GetClientRect (h, &r); | |
345 | InvalidateRect (h, &r, TRUE); | |
df62e023 | 346 | // and then do the same for categories with no packages. |
0cf68afd RC |
347 | for (packagedb::categoriesType::iterator n = packagedb::categories.begin(); |
348 | n != packagedb::categories.end(); ++n) | |
349 | if (!n->second.size()) | |
350 | { | |
351 | log (LOG_BABBLE) << "Removing empty category " << n->first << endLog; | |
352 | packagedb::categories.erase (n++); | |
353 | } | |
713bbe5f DD |
354 | } |
355 | ||
8f53e82a | 356 | static void |
97647369 | 357 | set_view_mode (HWND h, PickView::views mode) |
8f53e82a | 358 | { |
8f53e82a RC |
359 | chooser->set_view_mode (mode); |
360 | ||
361 | chooser->clear_view (); | |
bb849dbd | 362 | packagedb db; |
97647369 | 363 | if (chooser->get_view_mode () == PickView::views::Package) |
8f53e82a | 364 | { |
cfae3b8d RC |
365 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
366 | i != db.packages.end (); ++i) | |
cbfc4215 | 367 | { |
cfae3b8d | 368 | packagemeta & pkg = **i; |
cbfc4215 | 369 | if ((!pkg.desired && pkg.installed) |
3c196821 | 370 | || (pkg.desired && (pkg.desired.picked () |
e0aec95e MB |
371 | || pkg.desired.sourcePackage().picked()))) |
372 | chooser->insert_pkg (pkg); | |
373 | } | |
374 | } | |
375 | else if (chooser->get_view_mode () == PickView::views::PackageKeeps) | |
376 | { | |
377 | for (vector <packagemeta *>::iterator i = db.packages.begin (); | |
378 | i != db.packages.end (); ++i) | |
379 | { | |
380 | packagemeta & pkg = **i; | |
381 | if (pkg.installed && pkg.desired && !pkg.desired.picked() | |
382 | && !pkg.desired.sourcePackage().picked()) | |
383 | chooser->insert_pkg (pkg); | |
384 | } | |
385 | } | |
386 | else if (chooser->get_view_mode () == PickView::views::PackageSkips) | |
387 | { | |
388 | for (vector <packagemeta *>::iterator i = db.packages.begin (); | |
389 | i != db.packages.end (); ++i) | |
390 | { | |
391 | packagemeta & pkg = **i; | |
392 | if (!pkg.desired && !pkg.installed) | |
cc41a057 | 393 | chooser->insert_pkg (pkg); |
cbfc4215 | 394 | } |
ad3c7385 | 395 | } |
97647369 | 396 | else if (chooser->get_view_mode () == PickView::views::PackageFull) |
ad3c7385 | 397 | { |
cfae3b8d RC |
398 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
399 | i != db.packages.end (); ++i) | |
400 | chooser->insert_pkg (**i); | |
ad3c7385 | 401 | } |
97647369 | 402 | else if (chooser->get_view_mode () == PickView::views::Category) |
ad3c7385 | 403 | { |
bb849dbd | 404 | /* start collapsed. TODO: make this a chooser flag */ |
0cf68afd RC |
405 | for (packagedb::categoriesType::iterator n |
406 | = packagedb::categories.begin(); | |
407 | n != packagedb::categories.end(); ++n) | |
408 | chooser->insert_category (&*n, CATEGORY_COLLAPSED); | |
8f53e82a RC |
409 | } |
410 | ||
713bbe5f DD |
411 | RECT r; |
412 | GetClientRect (h, &r); | |
413 | SCROLLINFO si; | |
414 | memset (&si, 0, sizeof (si)); | |
415 | si.cbSize = sizeof (si); | |
e0aec95e | 416 | si.fMask = SIF_ALL | SIF_DISABLENOSCROLL; |
713bbe5f | 417 | si.nMin = 0; |
cc41a057 | 418 | si.nMax = chooser->headers[chooser->last_col].x + chooser->headers[chooser->last_col].width; // + HMARGIN; |
713bbe5f DD |
419 | si.nPage = r.right; |
420 | SetScrollInfo (h, SB_HORZ, &si, TRUE); | |
421 | ||
97647369 RC |
422 | si.nMax = chooser->contents.itemcount () * chooser->row_height; |
423 | si.nPage = r.bottom - chooser->header_height; | |
713bbe5f DD |
424 | SetScrollInfo (h, SB_VERT, &si, TRUE); |
425 | ||
97647369 | 426 | chooser->scroll_ulc_x = chooser->scroll_ulc_y = 0; |
713bbe5f DD |
427 | |
428 | InvalidateRect (h, &r, TRUE); | |
713bbe5f DD |
429 | } |
430 | ||
713bbe5f | 431 | static void |
f557695e | 432 | create_listview (HWND dlg, RECT * r) |
713bbe5f | 433 | { |
713bbe5f | 434 | lv = CreateWindowEx (WS_EX_CLIENTEDGE, |
47f8d8b3 CF |
435 | "listview", |
436 | "listviewwindow", | |
437 | WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, | |
438 | r->left, r->top, | |
f557695e | 439 | r->right - r->left + 1, r->bottom - r->top + 1, |
47f8d8b3 | 440 | dlg, |
f557695e RC |
441 | (HMENU) MAKEINTRESOURCE (IDC_CHOOSE_LIST), |
442 | hinstance, 0); | |
713bbe5f | 443 | ShowWindow (lv, SW_SHOW); |
d343da15 | 444 | packagedb db; |
7c6ef2c3 RC |
445 | chooser = |
446 | new PickView (PickView::views::Category, lv, | |
0cf68afd | 447 | *db.categories.find("All")); |
713bbe5f | 448 | |
713bbe5f | 449 | default_trust (lv, TRUST_CURR); |
97647369 | 450 | set_view_mode (lv, PickView::views::Category); |
f557695e | 451 | if (!SetDlgItemText (dlg, IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ())) |
aa1e3b4d RC |
452 | log (LOG_BABBLE) << "Failed to set View button caption %ld" << |
453 | GetLastError () << endLog; | |
cfae3b8d RC |
454 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
455 | i != db.packages.end (); ++i) | |
cbfc4215 | 456 | { |
cfae3b8d | 457 | packagemeta & pkg = **i; |
97647369 | 458 | pkg.set_requirements (chooser->deftrust); |
cbfc4215 | 459 | } |
bb849dbd | 460 | /* FIXME: do we need to init the desired fields ? */ |
c7230a28 | 461 | static int ta[] = { IDC_CHOOSE_KEEP, IDC_CHOOSE_PREV, IDC_CHOOSE_CURR, IDC_CHOOSE_EXP, 0 }; |
60c632b3 | 462 | rbset (dlg, ta, IDC_CHOOSE_CURR); |
713bbe5f | 463 | } |
23c9e63c | 464 | |
713bbe5f | 465 | static void |
f557695e | 466 | GetParentRect (HWND parent, HWND child, RECT * r) |
713bbe5f DD |
467 | { |
468 | POINT p; | |
469 | GetWindowRect (child, r); | |
470 | p.x = r->left; | |
471 | p.y = r->top; | |
472 | ScreenToClient (parent, &p); | |
473 | r->left = p.x; | |
474 | r->top = p.y; | |
475 | p.x = r->right; | |
476 | p.y = r->bottom; | |
477 | ScreenToClient (parent, &p); | |
478 | r->right = p.x; | |
479 | r->bottom = p.y; | |
480 | } | |
481 | ||
3c196821 RC |
482 | static void |
483 | scanAVersion (packageversion version) | |
484 | { | |
485 | if (!version) | |
486 | return; | |
487 | /* Remove mirror sites. | |
488 | * FIXME: This is a bit of a hack. a better way is to abstract | |
489 | * the availability logic to the package | |
490 | */ | |
491 | if (!check_for_cached (*(version.source())) && source == IDC_SOURCE_CWD) | |
3f34f364 | 492 | version.source()->sites.clear(); |
3c196821 RC |
493 | } |
494 | ||
4a83b7b0 DD |
495 | static void |
496 | scan_downloaded_files () | |
497 | { | |
b401ef47 RC |
498 | /* Look at every known package, in all the known mirror dirs, |
499 | * and fill in the Cached attribute if it exists. | |
500 | */ | |
58ee6135 | 501 | packagedb db; |
cfae3b8d RC |
502 | for (vector <packagemeta *>::iterator n = db.packages.begin (); |
503 | n != db.packages.end (); ++n) | |
58ee6135 | 504 | { |
cfae3b8d | 505 | packagemeta & pkg = **n; |
3c196821 RC |
506 | for (set<packageversion>::iterator i = pkg.versions.begin (); |
507 | i != pkg.versions.end (); ++i) | |
58ee6135 | 508 | { |
3c196821 RC |
509 | scanAVersion (*i); |
510 | packageversion foo = *i; | |
511 | packageversion pkgsrcver = foo.sourcePackage(); | |
512 | scanAVersion (pkgsrcver); | |
9e9b881a RC |
513 | /* For local installs, if there is no src and no bin, the version |
514 | * is unavailable | |
515 | */ | |
3c196821 RC |
516 | if (!i->accessible() && !pkgsrcver.accessible() |
517 | && *i != pkg.installed) | |
2ab26cdb | 518 | { |
3c196821 RC |
519 | if (pkg.prev == *i) |
520 | pkg.prev = packageversion(); | |
521 | if (pkg.curr == *i) | |
522 | pkg.curr = packageversion(); | |
523 | if (pkg.exp == *i) | |
524 | pkg.exp = packageversion(); | |
525 | pkg.versions.erase(i); | |
526 | /* For now, leave the source version alone */ | |
2ab26cdb | 527 | } |
58ee6135 RC |
528 | } |
529 | } | |
3c196821 RC |
530 | /* Don't explicity iterate through sources - any sources that aren't |
531 | referenced are unselectable anyway | |
532 | */ | |
4a83b7b0 DD |
533 | } |
534 | ||
f6a81f69 RC |
535 | bool |
536 | ChooserPage::Create () | |
713bbe5f | 537 | { |
f6a81f69 RC |
538 | return PropertyPage::Create (IDD_CHOOSE); |
539 | } | |
713bbe5f | 540 | |
f6a81f69 RC |
541 | void |
542 | ChooserPage::OnInit () | |
543 | { | |
544 | HWND frame; | |
545 | RECT r; | |
3b9077d4 | 546 | |
f6a81f69 | 547 | register_windows (GetInstance ()); |
713bbe5f | 548 | |
60c632b3 | 549 | if (source == IDC_SOURCE_DOWNLOAD || source == IDC_SOURCE_CWD) |
4a83b7b0 | 550 | scan_downloaded_files (); |
fb087b80 | 551 | |
60c632b3 | 552 | set_existence (); |
8f53e82a | 553 | fill_missing_category (); |
713bbe5f | 554 | |
f6a81f69 RC |
555 | frame = GetDlgItem (IDC_LISTVIEW_POS); |
556 | choose_inst_text = GetDlgItem (IDC_CHOOSE_INST_TEXT); | |
557 | if (source == IDC_SOURCE_DOWNLOAD) | |
558 | ::SetWindowText (choose_inst_text, "Select packages to download "); | |
559 | else | |
560 | ::SetWindowText (choose_inst_text, "Select packages to install "); | |
561 | GetParentRect (GetHWND (), frame, &r); | |
562 | r.top += 2; | |
563 | r.bottom -= 2; | |
564 | create_listview (GetHWND (), &r); | |
565 | } | |
566 | ||
52620058 RC |
567 | void |
568 | ChooserPage::OnActivate() | |
569 | { | |
570 | set_view_mode (lv, chooser->get_view_mode ()); | |
571 | } | |
572 | ||
f6a81f69 RC |
573 | long |
574 | ChooserPage::OnNext () | |
575 | { | |
576 | if (source == IDC_SOURCE_CWD) | |
577 | { | |
578 | // Next, install | |
579 | Progress.SetActivateTask (WM_APP_START_INSTALL); | |
580 | } | |
581 | else | |
582 | { | |
583 | // Next, start download from internet | |
584 | Progress.SetActivateTask (WM_APP_START_DOWNLOAD); | |
585 | } | |
713bbe5f | 586 | |
aa1e3b4d | 587 | log (LOG_BABBLE) << "Chooser results..." << endLog; |
bb849dbd | 588 | packagedb db; |
cfae3b8d RC |
589 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
590 | i != db.packages.end (); ++i) | |
89b1a15b | 591 | { |
cfae3b8d | 592 | packagemeta & pkg = **i; |
cbfc4215 RC |
593 | const char *trust = ((pkg.desired == pkg.prev) ? "prev" |
594 | : (pkg.desired == pkg.curr) ? "curr" | |
595 | : (pkg.desired == pkg.exp) ? "test" : "unknown"); | |
3c054baf RC |
596 | String action = pkg.action_caption (); |
597 | String const installed = | |
3c196821 | 598 | pkg.installed ? pkg.installed.Canonical_version () : "none"; |
bb849dbd | 599 | |
3c196821 | 600 | log (LOG_BABBLE) << "[" << pkg.name << "] action=" << action << " trust=" << trust << " installed=" << installed << " src?=" << (pkg.desired && pkg.desired.sourcePackage().picked() ? "yes" : "no") << endLog; |
405d7186 | 601 | if (pkg.categories.size ()) |
2dada532 CF |
602 | { |
603 | /* List categories the package belongs to */ | |
405d7186 RC |
604 | set <String, String::caseless>::const_iterator i |
605 | = pkg.categories.begin (); | |
c27b09ba | 606 | String all_categories = *(i++); |
405d7186 RC |
607 | while (i != pkg.categories.end ()) |
608 | all_categories += String (", ") + *(i++); | |
2dada532 | 609 | |
aa1e3b4d | 610 | log (LOG_BABBLE) << " categories=" << all_categories << endLog; |
2dada532 | 611 | } |
3c196821 RC |
612 | #if 0 |
613 | if (pkg.desired.required()) | |
2dada532 CF |
614 | { |
615 | /* List other packages this package depends on */ | |
7c6ef2c3 | 616 | Dependency *dp = pkg.desired->required; |
aa1e3b4d | 617 | String requires = dp->package.serialise (); |
7c6ef2c3 | 618 | for (dp = dp->next; dp; dp = dp->next) |
aa1e3b4d | 619 | requires += String (", ") + dp->package.serialise (); |
2dada532 | 620 | |
aa1e3b4d | 621 | log (LOG_BABBLE) << " requires=" << requires; |
2dada532 | 622 | } |
3c196821 | 623 | #endif |
f416a2b6 | 624 | pkg.logAllVersions(); |
89b1a15b | 625 | } |
f6a81f69 | 626 | return IDD_INSTATUS; |
713bbe5f | 627 | } |
ab57ceaa | 628 | |
f6a81f69 RC |
629 | long |
630 | ChooserPage::OnBack () | |
ab57ceaa | 631 | { |
f6a81f69 RC |
632 | initialized = 0; |
633 | if (source == IDC_SOURCE_CWD) | |
634 | return IDD_LOCAL_DIR; | |
635 | else | |
636 | return IDD_SITE; | |
ab57ceaa RC |
637 | } |
638 | ||
f6a81f69 RC |
639 | bool |
640 | ChooserPage::OnMessageCmd (int id, HWND hwndctl, UINT code) | |
ab57ceaa | 641 | { |
f6a81f69 RC |
642 | if (code != BN_CLICKED) |
643 | { | |
644 | // Not a click notification, we don't care. | |
645 | return false; | |
646 | } | |
ab57ceaa | 647 | |
f6a81f69 RC |
648 | packagedb db; |
649 | switch (id) | |
ab57ceaa | 650 | { |
c7230a28 MB |
651 | case IDC_CHOOSE_KEEP: |
652 | if (IsDlgButtonChecked (GetHWND (), id)) | |
653 | { | |
654 | for (vector <packagemeta *>::iterator i = db.packages.begin (); | |
655 | i != db.packages.end (); ++i) | |
656 | { | |
657 | packagemeta & pkg = **i; | |
658 | pkg.desired = pkg.installed; | |
659 | } | |
660 | set_view_mode (lv, chooser->get_view_mode ()); | |
661 | break; | |
662 | } | |
663 | else | |
664 | return false; | |
f6a81f69 RC |
665 | case IDC_CHOOSE_PREV: |
666 | if (IsDlgButtonChecked (GetHWND (), id)) | |
ab57ceaa | 667 | { |
f6a81f69 | 668 | default_trust (lv, TRUST_PREV); |
cfae3b8d RC |
669 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
670 | i != db.packages.end (); ++i) | |
f6a81f69 | 671 | { |
cfae3b8d | 672 | packagemeta & pkg = **i; |
f6a81f69 RC |
673 | pkg.set_requirements (TRUST_PREV); |
674 | } | |
675 | set_view_mode (lv, chooser->get_view_mode ()); | |
676 | break; | |
ab57ceaa | 677 | } |
f6a81f69 RC |
678 | else |
679 | return false; | |
680 | case IDC_CHOOSE_CURR: | |
681 | if (IsDlgButtonChecked (GetHWND (), id)) | |
ab57ceaa | 682 | { |
f6a81f69 | 683 | default_trust (lv, TRUST_CURR); |
cfae3b8d RC |
684 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
685 | i != db.packages.end (); ++i) | |
f6a81f69 | 686 | { |
cfae3b8d | 687 | packagemeta & pkg = **i; |
f6a81f69 RC |
688 | pkg.set_requirements (TRUST_CURR); |
689 | } | |
690 | set_view_mode (lv, chooser->get_view_mode ()); | |
691 | break; | |
ab57ceaa | 692 | } |
f6a81f69 | 693 | else |
ab57ceaa | 694 | return false; |
f6a81f69 RC |
695 | case IDC_CHOOSE_EXP: |
696 | if (IsDlgButtonChecked (GetHWND (), id)) | |
697 | { | |
698 | default_trust (lv, TRUST_TEST); | |
cfae3b8d RC |
699 | for (vector <packagemeta *>::iterator i = db.packages.begin (); |
700 | i != db.packages.end (); ++i) | |
f6a81f69 | 701 | { |
cfae3b8d | 702 | packagemeta & pkg = **i; |
f6a81f69 RC |
703 | pkg.set_requirements (TRUST_TEST); |
704 | } | |
705 | set_view_mode (lv, chooser->get_view_mode ()); | |
706 | break; | |
707 | } | |
708 | else | |
709 | return false; | |
710 | case IDC_CHOOSE_VIEW: | |
711 | set_view_mode (lv, ++chooser->get_view_mode ()); | |
712 | if (!SetDlgItemText | |
713 | (GetHWND (), IDC_CHOOSE_VIEWCAPTION, chooser->mode_caption ())) | |
aa1e3b4d RC |
714 | log (LOG_BABBLE) << "Failed to set View button caption " << |
715 | GetLastError () << endLog; | |
ab57ceaa | 716 | break; |
f6a81f69 RC |
717 | |
718 | ||
719 | default: | |
720 | // Wasn't recognized or handled. | |
721 | return false; | |
ab57ceaa | 722 | } |
f6a81f69 RC |
723 | |
724 | // Was handled since we never got to default above. | |
ab57ceaa RC |
725 | return true; |
726 | } |