This is done in two new files, usersite.h and usersite.cc, based on site.h and site.cc. The new page is activated after the mirror selection page if IDC_ALLOW_USER_URL is checked. --- Makefile.am | 2 + main.cc | 4 + res.rc | 25 ++++++ resource.h | 5 ++ site.cc | 19 +++-- usersite.cc | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ usersite.h | 43 ++++++++++ 7 files changed, 357 insertions(+), 9 deletions(-) create mode 100644 usersite.cc create mode 100644 usersite.h
diff --git a/Makefile.am b/Makefile.am index a238d88..a0b0450 100644 --- a/Makefile.am +++ b/Makefile.am @@ -258,6 +258,8 @@ inilint_SOURCES = \ threebar.h \ UserSettings.cc \ UserSettings.h \ + usersite.cc \ + usersite.h \ win32.cc \ win32.h \ window.cc \ diff --git a/main.cc b/main.cc index b44f9b6..a01fb43 100644 --- a/main.cc +++ b/main.cc @@ -53,6 +53,7 @@ #include "localdir.h" #include "net.h" #include "site.h" +#include "usersite.h" #include "choose.h" #include "prereq.h" #include "threebar.h" @@ -133,6 +134,7 @@ main_display () LocalDirPage LocalDir; NetPage Net; SitePage Site; + UserSitePage UserSite; ChooserPage Chooser; PrereqPage Prereq; DesktopSetupPage Desktop; @@ -173,6 +175,7 @@ main_display () LocalDir.Create (); Net.Create (); Site.Create (); + UserSite.Create (); Chooser.Create (); Prereq.Create (); Progress.Create (); @@ -187,6 +190,7 @@ main_display () MainWindow.AddPage (&LocalDir); MainWindow.AddPage (&Net); MainWindow.AddPage (&Site); + MainWindow.AddPage (&UserSite); MainWindow.AddPage (&Chooser); MainWindow.AddPage (&Prereq); MainWindow.AddPage (&Progress); diff --git a/res.rc b/res.rc index 5ea4c8b..85c7aea 100644 --- a/res.rc +++ b/res.rc @@ -154,6 +154,31 @@ BEGIN IDC_ALLOW_USER_URL,"Button",BS_AUTOCHECKBOX,15,171,350,8 END +IDD_USERSITE DIALOG DISCARDABLE 0, 0, SETUP_STANDARD_DIALOG_DIMS +STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_CHILD | WS_VISIBLE | + WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Cygwin Setup - Choose Additional Package Repositories" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_CYGWIN,IDC_HEADICON,SETUP_HEADICON_X,0,21,20 + LISTBOX IDC_USER_URL_LIST,66,45,185,110,LBS_NOINTEGRALHEIGHT | + LBS_EXTENDEDSEL | WS_VSCROLL | WS_HSCROLL | WS_GROUP | + WS_TABSTOP + LTEXT "Known sites:",IDC_STATIC,66,34,183,8,NOT + WS_GROUP + CONTROL "",IDC_HEADSEPARATOR,"Static",SS_BLACKFRAME | SS_SUNKEN,0,28, + SETUP_STANDARD_DIALOG_W,1 + LTEXT "Choose a site from this list, or add additional sites", + IDC_STATIC,21,9,239,16,NOT WS_GROUP + LTEXT "Choose A Site",IDC_STATIC_HEADER_TITLE,7,0,258, + 8,NOT WS_GROUP + EDITTEXT IDC_USERSITE_EDIT_URL,65,160,185,14,ES_AUTOHSCROLL | + WS_GROUP + LTEXT "User URL:",IDC_USERSITE_USERURL,15,162,45,8,NOT WS_GROUP + PUSHBUTTON "Add",IDC_BUTTON_ADD_USER_URL,255,160,50,14 +END + IDD_NET DIALOG DISCARDABLE 0, 0, SETUP_STANDARD_DIALOG_DIMS STYLE DS_MODALFRAME | DS_CENTER | WS_CHILD | WS_CAPTION | WS_SYSMENU CAPTION "Cygwin Setup - Select Connection Type" diff --git a/resource.h b/resource.h index ed4f605..79575fb 100644 --- a/resource.h +++ b/resource.h @@ -67,6 +67,7 @@ #define IDD_POSTINSTALL 222 #define IDD_FILE_INUSE 223 #define IDD_DOWNLOAD_ERROR 224 +#define IDD_USERSITE 225 // Bitmaps @@ -179,3 +180,7 @@ #define IDC_DOWNLOAD_EDIT 594 #define IDC_CHOOSE_DO_SEARCH 595 #define IDC_ALLOW_USER_URL 596 +#define IDC_USER_URL_LIST 597 +#define IDC_USERSITE_EDIT_URL 598 +#define IDC_USERSITE_USERURL 599 +#define IDC_BUTTON_ADD_USER_URL 600 diff --git a/site.cc b/site.cc index f2fa9fa..dc9b0ee 100644 --- a/site.cc +++ b/site.cc @@ -662,10 +662,10 @@ SitePage::OnNext () n != selected_mirror_list.end (); ++n) Log (LOG_PLAIN) << "mirror: " << n->url << endLog; + if (allow_user_url) + return IDD_USERSITE; Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD); return IDD_INSTATUS; - - return 0; } long @@ -695,7 +695,8 @@ SitePage::OnActivate () long SitePage::OnUnattended () { - if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) + if (allow_user_url + || SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) return OnNext (); else return -2; @@ -706,12 +707,11 @@ SitePage::CheckControlsAndDisableAccordingly () const { DWORD ButtonFlags = PSWIZB_BACK; - // Check that at least one download site is selected. - if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) - { - // At least one site selected, enable "Next". - ButtonFlags |= PSWIZB_NEXT; - } + // Enable Next if at least one mirror is selected or if we'll be + // going to the user URL page. + if (allow_user_url + || SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) + ButtonFlags |= PSWIZB_NEXT; GetOwner ()->SetButtons (ButtonFlags); } @@ -825,6 +825,7 @@ bool SitePage::OnMessageCmd (int id, HWND hwndctl, UINT code) allow_user_url = IsButtonChecked (IDC_ALLOW_USER_URL); if (!allow_user_url) selected_usersite_list.clear (); + CheckControlsAndDisableAccordingly (); } break; } diff --git a/usersite.cc b/usersite.cc new file mode 100644 index 0000000..91cabe7 --- /dev/null +++ b/usersite.cc @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2017, Ken Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Based on site.cc, written by DJ Delorie <d...@cygnus.com> + * + */ + +/* The purpose of this file is to let the user choose download sites + that are not cygwin.com mirrors. */ + +#include <string> +#include <algorithm> + +#include "usersite.h" +#include "site.h" +#include "win32.h" +#include "dialog.h" +#include "resource.h" +#include "state.h" +#include "LogSingleton.h" +#include "io_stream.h" +#include "propsheet.h" +#include "threebar.h" +#include "ControlAdjuster.h" + +using namespace std; + +extern ThreeBarProgressPage Progress; + +/* + Sizing information. + */ +static ControlAdjuster::ControlInfo UserSiteControlsInfo[] = { + {IDC_USER_URL_LIST, CP_STRETCH, CP_STRETCH}, + {IDC_USERSITE_EDIT_URL, CP_STRETCH, CP_BOTTOM}, + {IDC_BUTTON_ADD_USER_URL, CP_RIGHT, CP_BOTTOM}, + {IDC_USERSITE_USERURL, CP_LEFT, CP_BOTTOM}, + {0, CP_LEFT, CP_TOP} +}; + +UserSitePage::UserSitePage () +{ + sizeProcessor.AddControlInfo (UserSiteControlsInfo); +} + +using namespace std; + +// Recomputed by PopulateListBox() +SiteList all_usersite_list; + +// Selected sites; may be inaccurate until save_dialog() is called +extern SiteList site_list; + +// Selected mirrors +extern SiteList selected_mirror_list; + +// Selected URLs for non-mirror package repos; recomputed by save_dialog() +extern SiteList selected_usersite_list; + +static void +save_dialog (HWND h) +{ + // Remove anything that was previously in the selected usersite list. + selected_usersite_list.clear (); + + HWND listbox = GetDlgItem (h, IDC_USER_URL_LIST); + int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0); + if (sel_count > 0) + { + int sel_buffer[sel_count]; + SendMessage (listbox, LB_GETSELITEMS, sel_count, (LPARAM) sel_buffer); + for (int n = 0; n < sel_count; n++) + { + int mirror = + SendMessage (listbox, LB_GETITEMDATA, sel_buffer[n], 0); + selected_usersite_list.push_back (all_usersite_list[mirror]); + } + } + site_list = selected_mirror_list; + site_list.insert (site_list.end (), selected_usersite_list.begin (), + selected_usersite_list.end ()); +} + +bool UserSitePage::Create () +{ + return PropertyPage::Create (IDD_USERSITE); +} + +long +UserSitePage::OnNext () +{ + HWND h = GetHWND (); + + save_dialog (h); + + // Log all the selected URLs from the list. + for (SiteList::const_iterator n = selected_usersite_list.begin (); + n != selected_usersite_list.end (); ++n) + Log (LOG_PLAIN) << "user site: " << n->url << endLog; + + Progress.SetActivateTask (WM_APP_START_SETUP_INI_DOWNLOAD); + return IDD_INSTATUS; +} + +long +UserSitePage::OnBack () +{ + HWND h = GetHWND (); + + save_dialog (h); + + // Go back to the mirror selection page + return 0; +} + +void +UserSitePage::OnActivate () +{ + // Fill the list box with all known sites. + PopulateListBox (); + + // Load the user URL box with nothing - it is in the list already. + eset (GetHWND (), IDC_EDIT_USER_URL, ""); + + // Get the enabled/disabled states of the controls set accordingly. + CheckControlsAndDisableAccordingly (); +} + +long +UserSitePage::OnUnattended () +{ + if (site_list.size ()) + return OnNext (); + else + return -2; +} + +void +UserSitePage::CheckControlsAndDisableAccordingly () const +{ + DWORD ButtonFlags = PSWIZB_BACK; + + // Enable Next if at least one download site is selected. + if (selected_mirror_list.size () + || SendMessage (GetDlgItem (IDC_USER_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0) + ButtonFlags |= PSWIZB_NEXT; + GetOwner ()->SetButtons (ButtonFlags); +} + +void +UserSitePage::PopulateListBox () +{ + int j; + HWND listbox = GetDlgItem (IDC_USER_URL_LIST); + + // Recompute all_usersite_list. + all_usersite_list.clear (); + copy_if (all_site_list.begin (), all_site_list.end (), + back_inserter (all_usersite_list), + [] (site_list_type s) {return !s.is_mirror;}); + + // Populate the list box with the URLs. + SendMessage (listbox, LB_RESETCONTENT, 0, 0); + for (SiteList::const_iterator i = all_usersite_list.begin (); + i != all_usersite_list.end (); ++i) + { + j = SendMessage (listbox, LB_ADDSTRING, 0, + (LPARAM) i->displayed_url.c_str()); + SendMessage (listbox, LB_SETITEMDATA, j, j); + } + + // Select the selected ones. + for (SiteList::const_iterator n = selected_usersite_list.begin (); + n != selected_usersite_list.end (); ++n) + { + SiteList::iterator i = find (all_usersite_list.begin(), + all_usersite_list.end(), *n); + if (i != all_usersite_list.end()) + { + int index = i - all_usersite_list.begin(); + + // Highlight the selected item + SendMessage (listbox, LB_SELITEMRANGE, TRUE, (index << 16) | index); + // Make sure it's fully visible + SendMessage (listbox, LB_SETCARETINDEX, index, FALSE); + } + } +} + +bool UserSitePage::OnMessageCmd (int id, HWND hwndctl, UINT code) +{ + switch (id) + { + case IDC_USERSITE_EDIT_URL: + { + // Set the default pushbutton to ADD if the user is entering text. + if (code == EN_CHANGE) + SendMessage (GetHWND (), DM_SETDEFID, + (WPARAM) IDC_BUTTON_ADD_USER_URL, 0); + break; + } + case IDC_USER_URL_LIST: + { + if (code == LBN_SELCHANGE) + { + CheckControlsAndDisableAccordingly (); + save_dialog (GetHWND ()); + } + break; + } + case IDC_BUTTON_ADD_USER_URL: + { + if (code == BN_CLICKED) + { + // User pushed the Add button. + std::string other_url = egetString (GetHWND (), + IDC_USERSITE_EDIT_URL); + if (other_url.size()) + { + site_list_type newsite (other_url, "", "", "", false, false); + SiteList::iterator i = find (all_site_list.begin(), + all_site_list.end(), newsite); + if (i == all_site_list.end()) + { + all_site_list.push_back (newsite); + selected_usersite_list.push_back (newsite); + } + else if (!i->is_mirror) + selected_usersite_list.push_back (*i); + else + { + // Assume user knows what they're doing. + Log (LOG_BABBLE) << "Changing status of " << other_url + << " from mirror to user url." << endLog; + *i = newsite; + selected_usersite_list.push_back (newsite); + SiteList::iterator j = find (selected_mirror_list.begin (), + selected_mirror_list.end (), + newsite); + if (j != selected_mirror_list.end ()) + selected_mirror_list.erase (j); + } + + // Update the list box. + PopulateListBox (); + // And allow the user to continue + CheckControlsAndDisableAccordingly (); + eset (GetHWND (), IDC_USERSITE_EDIT_URL, ""); + } + } + break; + } + default: + // Wasn't recognized or handled. + return false; + } + + // Was handled since we never got to default above. + return true; +} diff --git a/usersite.h b/usersite.h new file mode 100644 index 0000000..842a0b0 --- /dev/null +++ b/usersite.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017, Ken Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Based on site.h, written by Robert Collins <rbtcoll...@hotmail.com> + * + */ + +#ifndef SETUP_USERSITE_H +#define SETUP_USERSITE_H + +#include "proppage.h" + +// For user URLs that are not mirrors of cygwin.com. +class UserSitePage : public PropertyPage +{ +public: + UserSitePage (); + virtual ~ UserSitePage () + { + }; + + bool Create (); + + virtual void OnActivate (); + virtual long OnNext (); + virtual long OnBack (); + virtual long OnUnattended (); + + virtual bool OnMessageCmd (int id, HWND hwndctl, UINT code); + + void PopulateListBox(); + void CheckControlsAndDisableAccordingly () const; +}; + +#endif /* SETUP_USERSITE_H */ -- 2.15.1