]> cygwin.com Git - cygwin-apps/setup.git/blame - site.cc
Suppress bogus free-nonheap-object warning in iniparse.cc
[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
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
184bool
185site_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
190bool
191site_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*/
203static void
204site_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 219static void
b7301c43 220save_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
242void
243load_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
301static void
302migrate_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
330static int
331get_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
393void
394SiteSetting::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
409void
410SiteSetting::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 421static DWORD WINAPI
ab57ceaa 422do_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
458static HANDLE context[2];
459
460void
461do_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 471static INT_PTR CALLBACK
e5e2eba8
CF
472drop_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
507int 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
542void 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
551void 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 568bool SitePage::Create ()
ab57ceaa 569{
b7301c43 570 return PropertyPage::Create (IDD_SITE);
ab57ceaa
RC
571}
572
ab57ceaa
RC
573long
574SitePage::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
598long
599SitePage::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
609void
610SitePage::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
622long
623SitePage::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
631void
632SitePage::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
645void
646SitePage::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
689bool 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}
This page took 0.238383 seconds and 5 git commands to generate.