]>
Commit | Line | Data |
---|---|---|
23c9e63c DD |
1 | /* |
2 | * Copyright (c) 2000, Red Hat, Inc. | |
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 get the list of mirror sites and ask | |
17 | the user which mirror site they want to download from. */ | |
18 | ||
d60832c6 MB |
19 | #include <string> |
20 | #include <algorithm> | |
21 | ||
3bac26a1 | 22 | #include "site.h" |
23c9e63c DD |
23 | #include "win32.h" |
24 | #include <stdio.h> | |
25 | #include <stdlib.h> | |
ab57ceaa | 26 | #include <process.h> |
23c9e63c DD |
27 | |
28 | #include "dialog.h" | |
29 | #include "resource.h" | |
30 | #include "state.h" | |
31 | #include "geturl.h" | |
32 | #include "msg.h" | |
aa1e3b4d | 33 | #include "LogSingleton.h" |
b24c88b3 | 34 | #include "io_stream.h" |
de6a1a64 | 35 | #include "site.h" |
23c9e63c | 36 | |
ab57ceaa RC |
37 | #include "propsheet.h" |
38 | ||
39 | #include "threebar.h" | |
a8d753b6 | 40 | #include "ControlAdjuster.h" |
072fb49a | 41 | #include "Exception.h" |
08678720 | 42 | #include "String++.h" |
a8d753b6 | 43 | |
01878bdf JT |
44 | #define MIRROR_LIST_URL "https://cygwin.com/mirrors.lst" |
45 | ||
ab57ceaa RC |
46 | extern ThreeBarProgressPage Progress; |
47 | ||
e5e2eba8 CF |
48 | /* |
49 | What to do if dropped mirrors are selected. | |
50 | */ | |
51 | enum | |
52 | { | |
53 | CACHE_REJECT, // Go back to re-select mirrors. | |
54 | CACHE_ACCEPT_WARN, // Go on. Warn again next time. | |
55 | CACHE_ACCEPT_NOWARN // Go on. Don't warn again. | |
56 | }; | |
57 | ||
a8d753b6 RC |
58 | /* |
59 | Sizing information. | |
60 | */ | |
61 | static ControlAdjuster::ControlInfo SiteControlsInfo[] = { | |
62 | {IDC_URL_LIST, CP_STRETCH, CP_STRETCH}, | |
63 | {IDC_EDIT_USER_URL, CP_STRETCH, CP_BOTTOM}, | |
64 | {IDC_BUTTON_ADD_URL, CP_RIGHT, CP_BOTTOM}, | |
82306ac2 | 65 | {IDC_SITE_USERURL, CP_LEFT, CP_BOTTOM}, |
a8d753b6 RC |
66 | {0, CP_LEFT, CP_TOP} |
67 | }; | |
68 | ||
69 | SitePage::SitePage () | |
70 | { | |
71 | sizeProcessor.AddControlInfo (SiteControlsInfo); | |
72 | } | |
73 | ||
7c05cfce | 74 | #include "getopt++/StringArrayOption.h" |
da434346 | 75 | #include "getopt++/BoolOption.h" |
f0fd8856 | 76 | #include "UserSettings.h" |
f2ff9838 | 77 | |
e5e2eba8 CF |
78 | bool cache_is_usable; |
79 | bool cache_needs_writing; | |
155eacb6 | 80 | std::string cache_warn_urls; |
e5e2eba8 CF |
81 | |
82 | /* Selected sites */ | |
3bac26a1 | 83 | SiteList site_list; |
e5e2eba8 CF |
84 | |
85 | /* Fresh mirrors + selected sites */ | |
3bac26a1 | 86 | SiteList all_site_list; |
23c9e63c | 87 | |
e5e2eba8 CF |
88 | /* Previously fresh + cached before */ |
89 | SiteList cached_site_list; | |
90 | ||
91 | /* Stale selected sites to warn about and add to cache */ | |
92 | SiteList dropped_site_list; | |
93 | ||
20f237b4 JT |
94 | StringArrayOption SiteOption('s', "site", IDS_HELPTEXT_SITE); |
95 | BoolOption OnlySiteOption(false, 'O', "only-site", IDS_HELPTEXT_ONLY_SITE); | |
c123d344 | 96 | extern BoolOption UnsupportedOption; |
da434346 | 97 | |
f26f525f | 98 | SiteSetting::SiteSetting (): saved (false) |
dbdc1d9d | 99 | { |
155eacb6 | 100 | std::vector<std::string> SiteOptionStrings = SiteOption; |
7c05cfce JT |
101 | if (SiteOptionStrings.size()) |
102 | { | |
155eacb6 | 103 | for (std::vector<std::string>::const_iterator n = SiteOptionStrings.begin (); |
7c05cfce JT |
104 | n != SiteOptionStrings.end (); ++n) |
105 | registerSavedSite (n->c_str ()); | |
106 | } | |
dbdc1d9d RC |
107 | else |
108 | getSavedSites (); | |
109 | } | |
2bbf91cf | 110 | |
c123d344 JT |
111 | const char * |
112 | SiteSetting::lastMirrorKey () | |
113 | { | |
114 | if (UnsupportedOption) | |
115 | return "last-mirror-unsupported"; | |
116 | ||
117 | return "last-mirror"; | |
118 | } | |
119 | ||
2bbf91cf | 120 | void |
0df9be37 RC |
121 | SiteSetting::save() |
122 | { | |
c123d344 | 123 | io_stream *f = UserSettings::instance().open (lastMirrorKey ()); |
0df9be37 RC |
124 | if (f) |
125 | { | |
126 | for (SiteList::const_iterator n = site_list.begin (); | |
f26f525f CF |
127 | n != site_list.end (); ++n) |
128 | *f << n->url; | |
0df9be37 RC |
129 | delete f; |
130 | } | |
f26f525f CF |
131 | saved = true; |
132 | } | |
133 | ||
134 | SiteSetting::~SiteSetting () | |
135 | { | |
136 | if (!saved) | |
137 | save (); | |
0df9be37 | 138 | } |
2bbf91cf | 139 | |
155eacb6 AG |
140 | site_list_type::site_list_type (const std::string &_url, |
141 | const std::string &_servername, | |
142 | const std::string &_area, | |
143 | const std::string &_location, | |
dd645a18 JT |
144 | bool _from_mirrors_lst, |
145 | bool _noshow = false) | |
de6a1a64 | 146 | { |
d60832c6 | 147 | url = _url; |
e5e2eba8 CF |
148 | servername = _servername; |
149 | area = _area; | |
150 | location = _location; | |
c4ae0173 | 151 | from_mirrors_lst = _from_mirrors_lst; |
dd645a18 | 152 | noshow = _noshow; |
d4818fbe JT |
153 | |
154 | /* Canonicalize URL to ensure it ends with a '/' */ | |
155 | if (url.at(url.length()-1) != '/') | |
156 | url.append("/"); | |
157 | ||
158 | /* displayed_url is protocol and site name part of url */ | |
155eacb6 | 159 | std::string::size_type path_offset = url.find ("/", url.find ("//") + 2); |
978f04b6 | 160 | displayed_url = url.substr(0, path_offset); |
d60832c6 | 161 | |
978f04b6 JT |
162 | /* the sorting key is hostname components in reverse order (to sort by country code) |
163 | plus the url (to ensure uniqueness) */ | |
155eacb6 AG |
164 | key = std::string(); |
165 | std::string::size_type last_idx = displayed_url.length () - 1; | |
166 | std::string::size_type idx = url.find_last_of("./", last_idx); | |
d60832c6 MB |
167 | if (last_idx - idx == 3) |
168 | { | |
169 | /* Sort non-country TLDs (.com, .net, ...) together. */ | |
170 | key += " "; | |
171 | } | |
172 | do | |
173 | { | |
174 | key += url.substr(idx + 1, last_idx - idx); | |
175 | key += " "; | |
176 | last_idx = idx - 1; | |
177 | idx = url.find_last_of("./", last_idx); | |
155eacb6 | 178 | if (idx == std::string::npos) |
d60832c6 MB |
179 | idx = 0; |
180 | } while (idx > 0); | |
181 | key += url; | |
de6a1a64 RC |
182 | } |
183 | ||
3bac26a1 RC |
184 | bool |
185 | site_list_type::operator == (site_list_type const &rhs) const | |
186 | { | |
d60832c6 | 187 | return stricmp (key.c_str(), rhs.key.c_str()) == 0; |
3bac26a1 RC |
188 | } |
189 | ||
190 | bool | |
191 | site_list_type::operator < (site_list_type const &rhs) const | |
192 | { | |
d60832c6 | 193 | return stricmp (key.c_str(), rhs.key.c_str()) < 0; |
3bac26a1 RC |
194 | } |
195 | ||
57ddb743 JT |
196 | /* |
197 | A SiteList is maintained as an in-order std::vector of site_list_type, by | |
198 | replacing it with a new object with the new item inserted in the correct | |
199 | place. | |
200 | ||
201 | Yes, we could just use an ordered container, instead. | |
202 | */ | |
203 | static void | |
204 | site_list_insert(SiteList &site_list, site_list_type newsite) | |
205 | { | |
206 | SiteList::iterator i = find (site_list.begin(), site_list.end(), newsite); | |
207 | if (i == site_list.end()) | |
208 | { | |
209 | SiteList result; | |
210 | merge (site_list.begin(), site_list.end(), | |
211 | &newsite, &newsite + 1, | |
212 | inserter (result, result.begin())); | |
213 | site_list = result; | |
214 | } | |
215 | else | |
216 | *i = newsite; | |
217 | } | |
218 | ||
23c9e63c | 219 | static void |
b7301c43 | 220 | save_dialog (HWND h) |
23c9e63c | 221 | { |
b7301c43 | 222 | // Remove anything that was previously in the selected site list. |
3bac26a1 | 223 | site_list.clear (); |
23c9e63c | 224 | |
23c9e63c | 225 | HWND listbox = GetDlgItem (h, IDC_URL_LIST); |
de6a1a64 RC |
226 | int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0); |
227 | if (sel_count > 0) | |
23c9e63c | 228 | { |
de6a1a64 | 229 | int sel_buffer[sel_count]; |
6d751ec8 | 230 | SendMessage (listbox, LB_GETSELITEMS, sel_count, (LPARAM) sel_buffer); |
de6a1a64 RC |
231 | for (int n = 0; n < sel_count; n++) |
232 | { | |
233 | int mirror = | |
234 | SendMessage (listbox, LB_GETITEMDATA, sel_buffer[n], 0); | |
3bac26a1 | 235 | site_list.push_back (all_site_list[mirror]); |
de6a1a64 | 236 | } |
23c9e63c | 237 | } |
23c9e63c DD |
238 | } |
239 | ||
c4ae0173 KB |
240 | // This is called only for lists of mirrors that came (now or in a |
241 | // previous setup run) from mirrors.lst. | |
e5e2eba8 CF |
242 | void |
243 | load_site_list (SiteList& theSites, char *theString) | |
23c9e63c | 244 | { |
e5e2eba8 CF |
245 | char *bol, *eol, *nl; |
246 | ||
247 | nl = theString; | |
23c9e63c DD |
248 | while (*nl) |
249 | { | |
250 | bol = nl; | |
b24c88b3 | 251 | for (eol = bol; *eol && *eol != '\n'; eol++); |
23c9e63c | 252 | if (*eol) |
b24c88b3 | 253 | nl = eol + 1; |
23c9e63c DD |
254 | else |
255 | nl = eol; | |
256 | while (eol > bol && eol[-1] == '\r') | |
257 | eol--; | |
258 | *eol = 0; | |
eff7a094 MB |
259 | if (*bol == '#' || !*bol) |
260 | continue; | |
261 | /* Accept only the URL schemes we can understand. */ | |
262 | if (strncmp(bol, "http://", 7) == 0 || | |
66d0ef98 JT |
263 | strncmp(bol, "https://", 8) == 0 || |
264 | strncmp(bol, "ftp://", 6) == 0 || | |
265 | strncmp(bol, "ftps://", 7) == 0) | |
dd645a18 JT |
266 | { |
267 | int i; | |
268 | char *semi[4]; | |
4ab6879c | 269 | |
dd645a18 JT |
270 | /* split into up to 4 semicolon-delimited parts */ |
271 | for (i = 0; i < 4; i++) | |
272 | semi[i] = 0; | |
4ab6879c | 273 | |
dd645a18 JT |
274 | char *p = bol; |
275 | for (i = 0; i < 4; i++) | |
276 | { | |
277 | semi[i] = strchr (p, ';'); | |
278 | if (!semi[i]) | |
279 | break; | |
280 | ||
281 | *semi[i] = 0; | |
282 | p = ++semi[i]; | |
283 | } | |
284 | ||
285 | /* Ignore malformed lines */ | |
286 | if (!semi[0] || !semi[1] || !semi[2]) | |
287 | continue; | |
288 | ||
289 | bool noshow = semi[3] && (strncmp(semi[3], "noshow", 6) == 0); | |
290 | ||
291 | site_list_type newsite (bol, semi[0], semi[1], semi[2], true, noshow); | |
292 | site_list_insert (theSites, newsite); | |
293 | } | |
66d0ef98 JT |
294 | else |
295 | { | |
296 | Log (LOG_BABBLE) << "Discarding line '" << bol << "' due to unknown protocol" << endLog; | |
297 | } | |
23c9e63c | 298 | } |
e5e2eba8 CF |
299 | } |
300 | ||
b4947fb6 JT |
301 | static void |
302 | migrate_selected_site_list() | |
303 | { | |
304 | const std::string http = "http://"; | |
305 | ||
306 | for (SiteList::iterator i = site_list.begin(); | |
307 | i != site_list.end(); | |
308 | ++i) | |
309 | { | |
310 | /* If the saved selected site URL starts with "http://", and the same URL, | |
311 | but starting with "https://" appears in the mirror list, migrate to | |
312 | "https://" */ | |
313 | if (strnicmp(i->url.c_str(), http.c_str(), strlen(http.c_str())) == 0) | |
314 | { | |
315 | std::string migrated_site = "https://"; | |
316 | migrated_site.append(i->url.substr(http.length())); | |
317 | ||
318 | site_list_type migrate(migrated_site, "", "", "", false); | |
319 | SiteList::iterator j = find (all_site_list.begin(), | |
320 | all_site_list.end(), migrate); | |
321 | if (j != all_site_list.end()) | |
322 | { | |
323 | Log (LOG_PLAIN) << "Migrated " << i->url << " to " << migrated_site << endLog; | |
324 | *i = migrate; | |
325 | } | |
326 | } | |
327 | } | |
328 | } | |
329 | ||
e5e2eba8 CF |
330 | static int |
331 | get_site_list (HINSTANCE h, HWND owner) | |
332 | { | |
e5e2eba8 | 333 | char *theMirrorString, *theCachedString; |
c123d344 JT |
334 | |
335 | if (UnsupportedOption) | |
336 | return 0; | |
337 | ||
da434346 | 338 | const char *cached_mirrors = OnlySiteOption ? NULL : UserSettings::instance().get ("mirrors-lst"); |
f26f525f CF |
339 | if (cached_mirrors) |
340 | { | |
157dc2b8 | 341 | Log (LOG_BABBLE) << "Loaded cached mirror list" << endLog; |
f26f525f CF |
342 | cache_is_usable = true; |
343 | } | |
344 | else | |
345 | { | |
157dc2b8 | 346 | Log (LOG_BABBLE) << "Cached mirror list unavailable" << endLog; |
f26f525f | 347 | cache_is_usable = false; |
ca09f44c | 348 | cached_mirrors = ""; |
f26f525f CF |
349 | } |
350 | ||
01878bdf | 351 | std::string mirrors = OnlySiteOption ? std::string ("") : get_url_to_string (MIRROR_LIST_URL, owner); |
f26f525f CF |
352 | if (mirrors.size()) |
353 | cache_needs_writing = true; | |
354 | else | |
355 | { | |
356 | if (!cached_mirrors[0]) | |
ad6cd84a JT |
357 | { |
358 | if (!OnlySiteOption) | |
359 | note(owner, IDS_NO_MIRROR_LST); | |
360 | Log (LOG_BABBLE) << "Defaulting to empty mirror list" << endLog; | |
361 | } | |
f26f525f CF |
362 | else |
363 | { | |
364 | mirrors = cached_mirrors; | |
157dc2b8 | 365 | Log (LOG_BABBLE) << "Using cached mirror list" << endLog; |
f26f525f CF |
366 | } |
367 | cache_is_usable = false; | |
368 | cache_needs_writing = false; | |
369 | } | |
370 | theMirrorString = new_cstr_char_array (mirrors); | |
371 | theCachedString = new_cstr_char_array (cached_mirrors); | |
e5e2eba8 CF |
372 | |
373 | load_site_list (all_site_list, theMirrorString); | |
374 | load_site_list (cached_site_list, theCachedString); | |
b4947fb6 | 375 | |
e5e2eba8 CF |
376 | delete[] theMirrorString; |
377 | delete[] theCachedString; | |
b5b282c4 | 378 | |
b4947fb6 JT |
379 | migrate_selected_site_list(); |
380 | ||
23c9e63c DD |
381 | return 0; |
382 | } | |
383 | ||
6fbc690d CF |
384 | /* List of machines that should not be used by default when saved |
385 | in "last-mirror". */ | |
e5e2eba8 CF |
386 | #define NOSAVE1 "ftp://sourceware.org/" |
387 | #define NOSAVE1_LEN (sizeof (NOSAVE2) - 1) | |
388 | #define NOSAVE2 "ftp://sources.redhat.com/" | |
389 | #define NOSAVE2_LEN (sizeof (NOSAVE1) - 1) | |
6fbc690d | 390 | #define NOSAVE3 "ftp://gcc.gnu.org/" |
e5e2eba8 | 391 | #define NOSAVE3_LEN (sizeof (NOSAVE3) - 1) |
6fbc690d | 392 | |
dbdc1d9d RC |
393 | void |
394 | SiteSetting::registerSavedSite (const char * site) | |
f2ff9838 | 395 | { |
c4ae0173 | 396 | site_list_type tempSite(site, "", "", "", false); |
57ddb743 JT |
397 | |
398 | /* Don't default to certain machines if they suffer from bandwidth | |
399 | limitations. */ | |
400 | if (strnicmp (site, NOSAVE1, NOSAVE1_LEN) == 0 | |
401 | || strnicmp (site, NOSAVE2, NOSAVE2_LEN) == 0 | |
402 | || strnicmp (site, NOSAVE3, NOSAVE3_LEN) == 0) | |
403 | return; | |
404 | ||
405 | site_list_insert (all_site_list, tempSite); | |
406 | site_list.push_back (tempSite); | |
f2ff9838 RC |
407 | } |
408 | ||
dbdc1d9d RC |
409 | void |
410 | SiteSetting::getSavedSites () | |
ed3e8b9b | 411 | { |
c123d344 | 412 | const char *buf = UserSettings::instance().get (lastMirrorKey ()); |
ca09f44c DK |
413 | if (!buf) |
414 | return; | |
f26f525f CF |
415 | char *fg_ret = strdup (buf); |
416 | for (char *site = strtok (fg_ret, "\n"); site; site = strtok (NULL, "\n")) | |
417 | registerSavedSite (site); | |
418 | free (fg_ret); | |
ed3e8b9b DD |
419 | } |
420 | ||
45e01f23 | 421 | static DWORD WINAPI |
ab57ceaa | 422 | do_download_site_info_thread (void *p) |
23c9e63c | 423 | { |
ab57ceaa RC |
424 | HANDLE *context; |
425 | HINSTANCE hinst; | |
426 | HWND h; | |
427 | context = (HANDLE *) p; | |
428 | ||
069cfbb4 JT |
429 | SetThreadUILanguage(langid); |
430 | ||
072fb49a MB |
431 | try |
432 | { | |
433 | hinst = (HINSTANCE) (context[0]); | |
434 | h = (HWND) (context[1]); | |
898fa4a1 JT |
435 | static bool downloaded = false; |
436 | if (!downloaded && get_site_list (hinst, h)) | |
072fb49a MB |
437 | { |
438 | // Error: Couldn't download the site info. | |
439 | // Go back to the Net setup page. | |
17d64747 | 440 | mbox (h, IDS_GET_SITELIST_ERROR, MB_OK); |
ab57ceaa | 441 | |
072fb49a | 442 | // Tell the progress page that we're done downloading |
6ab6abae | 443 | Progress.PostMessageNow (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0, IDD_NET); |
072fb49a | 444 | } |
898fa4a1 | 445 | else |
dbdc1d9d | 446 | { |
898fa4a1 | 447 | downloaded = true; |
dbdc1d9d RC |
448 | // Everything worked, go to the site select page |
449 | // Tell the progress page that we're done downloading | |
6ab6abae | 450 | Progress.PostMessageNow (WM_APP_SITE_INFO_DOWNLOAD_COMPLETE, 0, IDD_SITE); |
dbdc1d9d | 451 | } |
072fb49a | 452 | } |
703f1a44 | 453 | TOPLEVEL_CATCH((HWND) context[1], "site"); |
ab57ceaa | 454 | |
45e01f23 | 455 | ExitThread(0); |
ab57ceaa RC |
456 | } |
457 | ||
458 | static HANDLE context[2]; | |
459 | ||
460 | void | |
461 | do_download_site_info (HINSTANCE hinst, HWND owner) | |
462 | { | |
463 | ||
464 | context[0] = hinst; | |
465 | context[1] = owner; | |
466 | ||
45e01f23 RC |
467 | DWORD threadID; |
468 | CreateThread (NULL, 0, do_download_site_info_thread, context, 0, &threadID); | |
ab57ceaa RC |
469 | } |
470 | ||
e08abe3f | 471 | static INT_PTR CALLBACK |
e5e2eba8 CF |
472 | drop_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) |
473 | { | |
474 | switch (message) | |
475 | { | |
476 | case WM_INITDIALOG: | |
477 | eset(h, IDC_DROP_MIRRORS, cache_warn_urls); | |
478 | /* Should this be set by default? */ | |
479 | // CheckDlgButton (h, IDC_DROP_NOWARN, BST_CHECKED); | |
480 | SetFocus (GetDlgItem(h, IDC_DROP_NOWARN)); | |
481 | return FALSE; | |
482 | break; | |
483 | case WM_COMMAND: | |
484 | switch (LOWORD (wParam)) | |
485 | { | |
486 | case IDYES: | |
487 | if (IsDlgButtonChecked (h, IDC_DROP_NOWARN) == BST_CHECKED) | |
488 | EndDialog (h, CACHE_ACCEPT_NOWARN); | |
489 | else | |
490 | EndDialog (h, CACHE_ACCEPT_WARN); | |
491 | break; | |
492 | ||
493 | case IDNO: | |
494 | EndDialog (h, CACHE_REJECT); | |
495 | break; | |
496 | ||
497 | default: | |
498 | return 0; | |
499 | } | |
500 | return TRUE; | |
501 | break; | |
502 | default: | |
503 | return FALSE; | |
504 | } | |
505 | } | |
506 | ||
507 | int check_dropped_mirrors (HWND h) | |
508 | { | |
509 | cache_warn_urls = ""; | |
510 | dropped_site_list.clear (); | |
511 | ||
512 | for (SiteList::const_iterator n = site_list.begin (); | |
513 | n != site_list.end (); ++n) | |
514 | { | |
515 | SiteList::iterator i = find (all_site_list.begin(), all_site_list.end(), | |
516 | *n); | |
c4ae0173 | 517 | if (i == all_site_list.end() || !i->from_mirrors_lst) |
e5e2eba8 CF |
518 | { |
519 | SiteList::iterator j = find (cached_site_list.begin(), | |
520 | cached_site_list.end(), *n); | |
521 | if (j != cached_site_list.end()) | |
522 | { | |
157dc2b8 | 523 | Log (LOG_PLAIN) << "Dropped selected mirror: " << n->url |
e5e2eba8 CF |
524 | << endLog; |
525 | dropped_site_list.push_back (*j); | |
526 | if (cache_warn_urls.size()) | |
527 | cache_warn_urls += "\r\n"; | |
528 | cache_warn_urls += i->url; | |
529 | } | |
530 | } | |
531 | } | |
532 | if (cache_warn_urls.size()) | |
533 | { | |
534 | if (unattended_mode) | |
535 | return CACHE_ACCEPT_WARN; | |
536 | return DialogBox (hinstance, MAKEINTRESOURCE (IDD_DROPPED), h, | |
537 | drop_proc); | |
538 | } | |
539 | return CACHE_ACCEPT_NOWARN; | |
540 | } | |
541 | ||
542 | void write_cache_list (io_stream *f, const SiteList& theSites) | |
543 | { | |
e5e2eba8 | 544 | for (SiteList::const_iterator n = theSites.begin (); |
f26f525f | 545 | n != theSites.end (); ++n) |
c4ae0173 | 546 | if (n->from_mirrors_lst) |
f26f525f CF |
547 | *f << (n->url + ";" + n->servername + ";" + n->area + ";" |
548 | + n->location); | |
e5e2eba8 CF |
549 | } |
550 | ||
551 | void save_cache_file (int cache_action) | |
552 | { | |
f26f525f | 553 | io_stream *f = UserSettings::instance().open ("mirrors-lst"); |
e5e2eba8 CF |
554 | if (f) |
555 | { | |
e5e2eba8 CF |
556 | write_cache_list (f, all_site_list); |
557 | if (cache_action == CACHE_ACCEPT_WARN) | |
558 | { | |
157dc2b8 | 559 | Log (LOG_PLAIN) << "Adding dropped mirrors to cache to warn again." |
e5e2eba8 | 560 | << endLog; |
f26f525f | 561 | *f << "# Following mirrors re-added by setup.exe to warn again about dropped urls."; |
e5e2eba8 CF |
562 | write_cache_list (f, dropped_site_list); |
563 | } | |
564 | delete f; | |
565 | } | |
566 | } | |
567 | ||
b7301c43 | 568 | bool SitePage::Create () |
ab57ceaa | 569 | { |
b7301c43 | 570 | return PropertyPage::Create (IDD_SITE); |
ab57ceaa RC |
571 | } |
572 | ||
ab57ceaa RC |
573 | long |
574 | SitePage::OnNext () | |
575 | { | |
576 | HWND h = GetHWND (); | |
e5e2eba8 | 577 | int cache_action = CACHE_ACCEPT_NOWARN; |
ab57ceaa RC |
578 | |
579 | save_dialog (h); | |
e5e2eba8 CF |
580 | |
581 | if (cache_is_usable && !(cache_action = check_dropped_mirrors (h))) | |
582 | return -1; | |
583 | ||
584 | if (cache_needs_writing) | |
585 | save_cache_file (cache_action); | |
ab57ceaa | 586 | |
3bac26a1 RC |
587 | // Log all the selected URLs from the list. |
588 | for (SiteList::const_iterator n = site_list.begin (); | |
589 | n != site_list.end (); ++n) | |
157dc2b8 | 590 | Log (LOG_PLAIN) << "site: " << n->url << endLog; |
ab57ceaa | 591 | |
b7301c43 RC |
592 | Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD); |
593 | return IDD_INSTATUS; | |
ab57ceaa RC |
594 | |
595 | return 0; | |
596 | } | |
597 | ||
598 | long | |
599 | SitePage::OnBack () | |
600 | { | |
601 | HWND h = GetHWND (); | |
602 | ||
603 | save_dialog (h); | |
b7301c43 RC |
604 | |
605 | // Go back to the net connection type page | |
ab57ceaa | 606 | return 0; |
23c9e63c | 607 | } |
b7301c43 RC |
608 | |
609 | void | |
610 | SitePage::OnActivate () | |
611 | { | |
612 | // Fill the list box with all known sites. | |
613 | PopulateListBox (); | |
614 | ||
3c054baf RC |
615 | // Load the user URL box with nothing - it is in the list already. |
616 | eset (GetHWND (), IDC_EDIT_USER_URL, ""); | |
b7301c43 RC |
617 | |
618 | // Get the enabled/disabled states of the controls set accordingly. | |
619 | CheckControlsAndDisableAccordingly (); | |
620 | } | |
621 | ||
f2ff9838 RC |
622 | long |
623 | SitePage::OnUnattended () | |
624 | { | |
625 | if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) | |
626 | return OnNext (); | |
627 | else | |
628 | return -2; | |
629 | } | |
630 | ||
b7301c43 RC |
631 | void |
632 | SitePage::CheckControlsAndDisableAccordingly () const | |
633 | { | |
634 | DWORD ButtonFlags = PSWIZB_BACK; | |
635 | ||
636 | // Check that at least one download site is selected. | |
637 | if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) | |
638 | { | |
3548fbc3 | 639 | // At least one site selected, enable "Next". |
b7301c43 RC |
640 | ButtonFlags |= PSWIZB_NEXT; |
641 | } | |
642 | GetOwner ()->SetButtons (ButtonFlags); | |
643 | } | |
644 | ||
645 | void | |
646 | SitePage::PopulateListBox () | |
647 | { | |
dd645a18 | 648 | std::vector <int> sel_indicies; |
b7301c43 RC |
649 | HWND listbox = GetDlgItem (IDC_URL_LIST); |
650 | ||
651 | // Populate the list box with the URLs. | |
652 | SendMessage (listbox, LB_RESETCONTENT, 0, 0); | |
3bac26a1 RC |
653 | for (SiteList::const_iterator i = all_site_list.begin (); |
654 | i != all_site_list.end (); ++i) | |
b7301c43 | 655 | { |
dd645a18 JT |
656 | // If selected, always show |
657 | SiteList::iterator f = find (site_list.begin(), site_list.end(), *i); | |
658 | if (f == site_list.end()) | |
659 | { | |
660 | // Otherwise, hide redundant legacy URLs: | |
661 | if (i->noshow) | |
662 | continue; | |
663 | } | |
664 | ||
665 | int j = SendMessage (listbox, LB_ADDSTRING, 0, | |
666 | (LPARAM) i->displayed_url.c_str()); | |
667 | // Set the ListBox item data to the index into all_site_list | |
668 | SendMessage (listbox, LB_SETITEMDATA, j, (i - all_site_list.begin())); | |
669 | ||
670 | // For every selected item, remember the index | |
671 | if (f != site_list.end()) | |
672 | { | |
673 | sel_indicies.push_back(j); | |
674 | } | |
b7301c43 RC |
675 | } |
676 | ||
677 | // Select the selected ones. | |
dd645a18 JT |
678 | for (std::vector <int>::const_iterator n = sel_indicies.begin (); |
679 | n != sel_indicies.end (); ++n) | |
b7301c43 | 680 | { |
dd645a18 JT |
681 | int index = *n; |
682 | // Highlight the selected item | |
683 | SendMessage (listbox, LB_SELITEMRANGE, TRUE, (index << 16) | index); | |
684 | // Make sure it's fully visible | |
685 | SendMessage (listbox, LB_SETCARETINDEX, index, FALSE); | |
b7301c43 RC |
686 | } |
687 | } | |
688 | ||
689 | bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code) | |
690 | { | |
691 | switch (id) | |
692 | { | |
693 | case IDC_EDIT_USER_URL: | |
694 | { | |
c3853939 KB |
695 | // Set the default pushbutton to ADD if the user is entering text. |
696 | if (code == EN_CHANGE) | |
697 | SendMessage (GetHWND (), DM_SETDEFID, (WPARAM) IDC_BUTTON_ADD_URL, 0); | |
b7301c43 RC |
698 | break; |
699 | } | |
700 | case IDC_URL_LIST: | |
701 | { | |
702 | if (code == LBN_SELCHANGE) | |
703 | { | |
704 | CheckControlsAndDisableAccordingly (); | |
3c054baf | 705 | save_dialog (GetHWND ()); |
b7301c43 RC |
706 | } |
707 | break; | |
708 | } | |
709 | case IDC_BUTTON_ADD_URL: | |
710 | { | |
711 | if (code == BN_CLICKED) | |
712 | { | |
713 | // User pushed the Add button. | |
08678720 | 714 | std::string other_url = egetString (GetHWND (), IDC_EDIT_USER_URL); |
3c054baf RC |
715 | if (other_url.size()) |
716 | { | |
c4ae0173 | 717 | site_list_type newsite (other_url, "", "", "", false); |
3bac26a1 RC |
718 | SiteList::iterator i = find (all_site_list.begin(), |
719 | all_site_list.end(), newsite); | |
720 | if (i == all_site_list.end()) | |
b7301c43 | 721 | { |
3bac26a1 | 722 | all_site_list.push_back (newsite); |
157dc2b8 | 723 | Log (LOG_BABBLE) << "Adding site: " << other_url << endLog; |
c4ae0173 | 724 | site_list.push_back (newsite); |
b7301c43 RC |
725 | } |
726 | else | |
c4ae0173 | 727 | site_list.push_back (*i); |
b7301c43 RC |
728 | |
729 | // Update the list box. | |
730 | PopulateListBox (); | |
3548fbc3 RC |
731 | // And allow the user to continue |
732 | CheckControlsAndDisableAccordingly (); | |
3c054baf RC |
733 | eset (GetHWND (), IDC_EDIT_USER_URL, ""); |
734 | } | |
b7301c43 RC |
735 | } |
736 | break; | |
737 | } | |
738 | default: | |
739 | // Wasn't recognized or handled. | |
740 | return false; | |
741 | } | |
742 | ||
743 | // Was handled since we never got to default above. | |
744 | return true; | |
745 | } |