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