[PATCH setup v4 3/6] Create new page UserSitePage for user URLs

Ken Brown kbrown@cornell.edu
Sun Dec 10 17:49:00 GMT 2017


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 <dj@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 <rbtcollins@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



More information about the Cygwin-apps mailing list