From 6e2594cfc937d76dc3b764592db68e0279a03875 Mon Sep 17 00:00:00 2001
From: Bruce Toll <btoll@dhsus.com>
Date: Mon, 17 Oct 2016 20:14:29 -0400
Subject: [PATCH 2/3] Minor improvements to Integration Example (part 1)

Updated FormModel.cpp to take advantage of more C++11 features,
including some which were already present in the comments. This makes
the code a little more compact and, hopefully, easier to read.
---
 examples/widgetgallery/examples/FormModel.cpp | 325 +++++++++++---------------
 1 file changed, 130 insertions(+), 195 deletions(-)

diff --git a/examples/widgetgallery/examples/FormModel.cpp b/examples/widgetgallery/examples/FormModel.cpp
index 4ec77cc..74c9615 100644
--- a/examples/widgetgallery/examples/FormModel.cpp
+++ b/examples/widgetgallery/examples/FormModel.cpp
@@ -22,39 +22,53 @@ class UserFormModel : public Wt::WFormModel
 {
 public:
     // Associate each field with a unique string literal.
-    static const Field FirstNameField;
-    static const Field LastNameField;
-    static const Field CountryField;
-    static const Field CityField;
-    static const Field BirthField;
-    static const Field ChildrenField;
-    static const Field RemarksField;
+    static const struct FieldNamesType {
+        Field FirstName = "first-name";
+        Field LastName = "last-name";
+        Field Country = "country";
+        Field City = "city";
+        Field Birth = "birth";
+        Field Children = "children";
+        Field Remarks = "remarks";
+    } Fld;
 
     UserFormModel(Wt::WObject *parent = 0)
         : Wt::WFormModel(parent)
     {
         initializeModels();
 
-        addField(FirstNameField);
-        addField(LastNameField);
-        addField(CountryField);
-        addField(CityField);
-        addField(BirthField);
-        addField(ChildrenField);
-        addField(RemarksField);
-
-        setValidator(FirstNameField, createNameValidator(FirstNameField));
-        setValidator(LastNameField, createNameValidator(LastNameField));
-        setValidator(CountryField, createCountryValidator());
-        setValidator(CityField, createCityValidator());
-        setValidator(BirthField, createBirthValidator());
-        setValidator(ChildrenField, createChildrenValidator());
+        addValidatedField(Fld.FirstName, createNameValidator(Fld.FirstName));
+        addValidatedField(Fld.LastName, createNameValidator(Fld.LastName));
+        addValidatedField(Fld.Country, new Wt::WValidator(true));
+        addValidatedField(Fld.City, new Wt::WValidator(true));
+        addValidatedField(Fld.Birth,
+            [=] () {
+                auto v = new Wt::WDateValidator();
+                v->setBottom(Wt::WDate(1900, 1, 1));
+                v->setTop(Wt::WDate::currentDate());
+                v->setFormat("dd/MM/yyyy");
+                v->setMandatory(true);
+                return v;
+            } ());
+        addValidatedField(Fld.Children,
+            [=] () {
+                auto v = new Wt::WIntValidator(0, MAX_CHILDREN);
+                v->setMandatory(true);
+                return v;
+            } ());
+        addField(Fld.Remarks);
 
         // Here you could populate the model with initial data using
         // setValue() for each field.
 
-        setValue(BirthField, Wt::WDate());
-        setValue(ChildrenField, Wt::WString());
+        setValue(Fld.Birth, Wt::WDate());
+        setValue(Fld.Children, Wt::WString());
+    }
+
+    void addValidatedField(Field field, Wt::WValidator* validator)
+    {
+        addField(field);
+        setValidator(field, validator);
     }
 
     Wt::WAbstractItemModel *countryModel() {
@@ -62,11 +76,11 @@ public:
     }
 
     int countryModelRow(const std::string& code) {
-	for (int i = 0; i < countryModel_->rowCount(); ++i)
-	    if (countryCode(i) == code)
-	        return i;
+        for (int i = 0; i < countryModel_->rowCount(); ++i)
+            if (countryCode(i) == code)
+                return i;
 
-	return -1;
+        return -1;
     }
 
     Wt::WAbstractItemModel *cityModel() {
@@ -100,20 +114,20 @@ public:
     // Get the user data from the model
     Wt::WString userData() {
         return
-        Wt::asString(value(FirstNameField)) + " " +
-        Wt::asString(value(LastNameField))
-        + ": country code=" + Wt::asString(value(CountryField))
-        + ", city=" + Wt::asString(value(CityField))
-        + ", birth=" + Wt::asString(value(BirthField))
-        + ", children=" + Wt::asString(value(ChildrenField))
-        + ", remarks=" + Wt::asString(value(RemarksField))
+        Wt::asString(value(Fld.FirstName)) + " " +
+        Wt::asString(value(Fld.LastName))
+        + ": country code=" + Wt::asString(value(Fld.Country))
+        + ", city=" + Wt::asString(value(Fld.City))
+        + ", birth=" + Wt::asString(value(Fld.Birth))
+        + ", children=" + Wt::asString(value(Fld.Children))
+        + ", remarks=" + Wt::asString(value(Fld.Remarks))
         + ".";
     }
 
     // Get the right code for the current index.
     std::string countryCode (int row) {
         return boost::any_cast<std::string>
-	  (countryModel_->data(row, 0, Wt::UserRole));
+          (countryModel_->data(row, 0, Wt::UserRole));
     }
 
     typedef std::map< std::string, std::vector<std::string> > CityMap;
@@ -147,10 +161,9 @@ private:
         // - set the country name for the display role,
         // - set the city names for the user role.
         row = 1;
-        for (CountryMap::const_iterator i = countries.begin();
-                                        i != countries.end(); ++i) {
-            countryModel_->setData(row, 0, i->second, Wt::DisplayRole);
-            countryModel_->setData(row++, 0, i->first, Wt::UserRole);
+        for (auto i: countries) {
+            countryModel_->setData(row, 0, i.second, Wt::DisplayRole);
+            countryModel_->setData(row++, 0, i.first, Wt::UserRole);
         }
 
         // Create a city model.
@@ -159,111 +172,33 @@ private:
     }
 
     Wt::WValidator *createNameValidator(const std::string& field) {
-        Wt::WLengthValidator *v = new Wt::WLengthValidator();
-        v->setMandatory(true);
-        v->setMinimumLength(1);
-        v->setMaximumLength(MAX_LENGTH);
-        return v;
-    }
-
-    Wt::WValidator *createCountryValidator() {
-        Wt::WLengthValidator *v = new Wt::WLengthValidator();
-        v->setMandatory(true);
-        return v;
-    }
-
-    Wt::WValidator *createCityValidator() {
-        Wt::WLengthValidator *v = new Wt::WLengthValidator();
-        v->setMandatory(true);
-        return v;
-    }
-
-    Wt::WValidator *createBirthValidator() {
-        Wt::WDateValidator *v = new Wt::WDateValidator();
-        v->setBottom(Wt::WDate(1900, 1, 1));
-        v->setTop(Wt::WDate::currentDate());
-        v->setFormat("dd/MM/yyyy");
+        Wt::WLengthValidator *v = new Wt::WLengthValidator(1, MAX_LENGTH);
         v->setMandatory(true);
         return v;
     }
+};
 
-    Wt::WValidator *createChildrenValidator() {
-        Wt::WIntValidator *v = new Wt::WIntValidator(0, MAX_CHILDREN);
-        v->setMandatory(true);
-        return v;
-    }
+const UserFormModel::FieldNamesType UserFormModel::Fld;
 
+const UserFormModel::CityMap UserFormModel::cities = {
+   { "BE", { "Antwerp", "Bruges", "Brussels", "Ghent" } },
+   { "NL", { "Amsterdam", "Eindhoven", "Rotterdam", "The Hague"} },
+   { "UK", { "London", "Bristol", "Oxford", "Stonehenge"} },
+   { "US", { "Boston", "Chicago", "Los Angeles", "New York"} }
 };
 
-const Wt::WFormModel::Field UserFormModel::FirstNameField = "first-name";
-const Wt::WFormModel::Field UserFormModel::LastNameField = "last-name";
-const Wt::WFormModel::Field UserFormModel::CountryField = "country";
-const Wt::WFormModel::Field UserFormModel::CityField = "city";
-const Wt::WFormModel::Field UserFormModel::BirthField = "birth";
-const Wt::WFormModel::Field UserFormModel::ChildrenField = "children";
-const Wt::WFormModel::Field UserFormModel::RemarksField = "remarks";
-
-// In C++11, this initializing can be done inline, within the declaration:
-//
-// const UserFormModel::CityMap UserFormModel::cities = {
-//    { "BE", { "Antwerp", "Bruges", "Brussels", "Ghent" } },
-//    { "NL", { "Amsterdam", "Eindhoven", "Rotterdam", "The Hague"} },
-//    { "UK", { "London", "Bristol", "Oxford", "Stonehenge"} },
-//    { "US", { "Boston", "Chicago", "Los Angeles", "New York"} }
-// };
-
-namespace {
-    UserFormModel::CountryMap getCountryMap() {
-	UserFormModel::CountryMap retval;
-	retval["BE"] = "Belgium";
-	retval["NL"] = "Netherlands";
-	retval["UK"] = "United Kingdom";
-	retval["US"] = "United States";
-	return retval;
-    }
-}
-const UserFormModel::CountryMap UserFormModel::countries = getCountryMap();
-
-namespace {
-    UserFormModel::CityMap getCityMap() {
-	std::vector<std::string> beCities;
-	beCities.push_back("Antwerp");
-	beCities.push_back("Bruges");
-	beCities.push_back("Brussels");
-	beCities.push_back("Ghent");
-
-	std::vector<std::string> nlCities;
-	nlCities.push_back("Amsterdam");
-	nlCities.push_back("Eindhoven");
-	nlCities.push_back("Rotterdam");
-	nlCities.push_back("The Hague");
-
-	std::vector<std::string> ukCities;
-	ukCities.push_back("London");
-	ukCities.push_back("Bristol");
-	ukCities.push_back("Oxford");
-	ukCities.push_back("Stonehenge");
-
-	std::vector<std::string> usCities;
-	usCities.push_back("Boston");
-	usCities.push_back("Chicago");
-        usCities.push_back("Los Angeles");
-	usCities.push_back("New York");
-
-	UserFormModel::CityMap retval;
-	retval["BE"] = beCities;
-	retval["NL"] = nlCities;
-	retval["UK"] = ukCities;
-        retval["US"] = usCities;
-	return retval;
-    }
-}
-
-const UserFormModel::CityMap UserFormModel::cities = getCityMap();
+const UserFormModel::CountryMap UserFormModel::countries = {
+   { "BE", "Belgium" },
+   { "NL", "Netherlands"},
+   { "UK", "United Kingdom"},
+   { "US", "United States"}
+};
 
 class UserFormView : public Wt::WTemplateFormView
 {
 public:
+    const UserFormModel::FieldNamesType& Fld = UserFormModel::Fld;
+
     // inline constructor
     UserFormView() {
         model = new UserFormModel(this);
@@ -271,71 +206,71 @@ public:
         setTemplateText(tr("userForm-template"));
 
         /*
-	 * First Name
-	 */
-	setFormWidget(UserFormModel::FirstNameField, new Wt::WLineEdit());
-
-	/*
-	 * Last Name
-	 */
-	setFormWidget(UserFormModel::LastNameField, new Wt::WLineEdit());
-
-	/*
-	 * Country
-	 */
-	Wt::WComboBox *countryCB = new Wt::WComboBox();
-	countryCB->setModel(model->countryModel());
-
-	countryCB->activated().connect(std::bind([=] () {
-	    std::string code = model->countryCode(countryCB->currentIndex());
-	    model->updateCityModel(code);
-	}));
-
-	setFormWidget(UserFormModel::CountryField, countryCB);
-
-	/*
-	 * City
-	 */
-	Wt::WComboBox *cityCB = new Wt::WComboBox();
-	cityCB->setModel(model->cityModel());
-	setFormWidget(UserFormModel::CityField, cityCB, 0,
+         * First Name
+         */
+        setFormWidget(Fld.FirstName, new Wt::WLineEdit());
+
+        /*
+         * Last Name
+         */
+        setFormWidget(Fld.LastName, new Wt::WLineEdit());
+
+        /*
+         * Country
+         */
+        auto countryCB = new Wt::WComboBox();
+        countryCB->setModel(model->countryModel());
+
+        countryCB->activated().connect(std::bind([=] () {
+            auto code = model->countryCode(countryCB->currentIndex());
+            model->updateCityModel(code);
+        }));
+
+        setFormWidget(Fld.Country, countryCB);
+
+        /*
+         * City
+         */
+        auto cityCB = new Wt::WComboBox();
+        cityCB->setModel(model->cityModel());
+        setFormWidget(Fld.City, cityCB, 0,
             [=] () { // updateModelValue()
-	        std::string countryCode = model->countryCode(countryCB->currentIndex());
-	        model->updateCityModel(countryCode);
-	        model->setValue(UserFormModel::CityField, cityCB->valueText());
+                auto countryCode = model->countryCode(countryCB->currentIndex());
+                model->updateCityModel(countryCode);
+                model->setValue(Fld.City, cityCB->valueText());
             });
 
-	/*
-	 * Birth Date
-	 */
-	setFormWidget(UserFormModel::BirthField, new Wt::WDateEdit());
+        /*
+         * Birth Date
+         */
+        setFormWidget(Fld.Birth, new Wt::WDateEdit());
 
         /*
-	 * Children
-	 */ 
-	Wt::WSpinBox *childrenSB = new Wt::WSpinBox();
-	setFormWidget(UserFormModel::ChildrenField, childrenSB,
+         * Children
+         */
+        auto childrenSB = new Wt::WSpinBox();
+        setFormWidget(Fld.Children, childrenSB,
             [=] () { // updateViewValue()
-	        if (childrenSB->validate() == Wt::WValidator::Valid)
-	            childrenSB->setValueText(boost::any_cast<Wt::WString>
-			(model->value(UserFormModel::ChildrenField)));
-	    }, 0);
-
-	/*
-	 * Remarks
-	 */
-	Wt::WTextArea *remarksTA = new Wt::WTextArea();
-	remarksTA->setColumns(40);
-	remarksTA->setRows(5);
-	setFormWidget(UserFormModel::RemarksField, remarksTA);
-
-	/*
-	 * Title & Buttons
-	 */
-        Wt::WString title = Wt::WString("Create new user");
+                if (childrenSB->validate() == Wt::WValidator::Valid)
+                    childrenSB->setValueText(boost::any_cast<Wt::WString>
+                        (model->value(Fld.Children)));
+            }, 0);
+
+        /*
+         * Remarks
+         */
+        auto remarksTA = new Wt::WTextArea();
+        remarksTA->setColumns(40);
+        remarksTA->setRows(5);
+        setFormWidget(Fld.Remarks, remarksTA);
+
+        /*
+         * Title & Buttons
+         */
+        auto title = Wt::WString("Create new user");
         bindString("title", title);
 
-        Wt::WPushButton *button = new Wt::WPushButton("Save");
+        auto button = new Wt::WPushButton("Save");
         bindWidget("submit-button", button);
 
         bindString("submit-info", Wt::WString());
@@ -353,12 +288,12 @@ private:
             // Do something with the data in the model: show it.
             bindString("submit-info",
                        Wt::WString::fromUTF8("Saved user data for ")
-		       + model->userData(), Wt::PlainText);
-            // Udate the view: Delete any validation message in the view, etc.
+                       + model->userData(), Wt::PlainText);
+            // Update the view: Delete any validation message in the view, etc.
             updateView(model);
             // Set the focus on the first field in the form.
-            Wt::WLineEdit *viewField =
-                    resolve<Wt::WLineEdit*>(UserFormModel::FirstNameField);
+            auto viewField =
+                    resolve<Wt::WLineEdit*>(Fld.FirstName);
             viewField->setFocus(true);
         } else {
             bindEmpty("submit-info"); // Delete the previous user data.
@@ -371,6 +306,6 @@ private:
 
 SAMPLE_BEGIN(FormModel)
 
-UserFormView *view = new UserFormView();
+auto view = new UserFormView();
 
 SAMPLE_END(return view)
-- 
2.1.4

