lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 1273a62: Remove wxDataViewCtrl implementation


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 1273a62: Remove wxDataViewCtrl implementation of the census view
Date: Wed, 19 Aug 2020 16:53:03 -0400 (EDT)

branch: master
commit 1273a6244bb4f853a5646cd8017bde622479456a
Author: Ilya Sinitsyn <isinitsyn@tt-solutions.com>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Remove wxDataViewCtrl implementation of the census view
    
    Keep only wxGrid census view implementation.
---
 census_document.cpp         |   17 +-
 census_document.hpp         |   35 +-
 census_view.cpp             | 1354 +------------------------------------------
 census_view.hpp             |  139 +----
 skeleton.cpp                |    6 +-
 wx_test_paste_census.cpp    |  287 ++-------
 wx_test_validate_output.cpp |   19 +-
 7 files changed, 122 insertions(+), 1735 deletions(-)

diff --git a/census_document.cpp b/census_document.cpp
index c7bc078..8e7071a 100644
--- a/census_document.cpp
+++ b/census_document.cpp
@@ -33,22 +33,13 @@
 
 #include <fstream>
 
-IMPLEMENT_DYNAMIC_CLASS(CensusDVCDocument, CensusDocument)
-IMPLEMENT_DYNAMIC_CLASS(CensusGridDocument, CensusDocument)
+IMPLEMENT_DYNAMIC_CLASS(CensusDocument, wxDocument)
 
-wxDataViewCtrl& CensusDVCDocument::PredominantViewWindow() const
+wxGrid& CensusDocument::PredominantViewWindow() const
 {
-    return ::PredominantViewWindow<CensusDVCView,wxDataViewCtrl>
+    return ::PredominantViewWindow<CensusView,wxGrid>
         (*this
-        ,&CensusDVCView::list_window_
-        );
-}
-
-wxGrid& CensusGridDocument::PredominantViewWindow() const
-{
-    return ::PredominantViewWindow<CensusGridView,wxGrid>
-        (*this
-        ,&CensusGridView::grid_window_
+        ,&CensusView::grid_window_
         );
 }
 
diff --git a/census_document.hpp b/census_document.hpp
index 30cffe2..f00d572 100644
--- a/census_document.hpp
+++ b/census_document.hpp
@@ -29,7 +29,6 @@
 
 #include <wx/docview.h>
 
-class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
 class WXDLLIMPEXP_FWD_ADV wxGrid;
 
 class CensusDocument
@@ -45,44 +44,16 @@ class CensusDocument
     CensusDocument(CensusDocument const&) = delete;
     CensusDocument& operator=(CensusDocument const&) = delete;
 
+    wxGrid& PredominantViewWindow() const;
+
     // wxDocument overrides.
     bool OnCreate(wxString const& filename, long int flags) override;
     bool DoOpenDocument(wxString const& filename) override;
     bool DoSaveDocument(wxString const& filename) override;
 
     multiple_cell_document doc_;
-};
-
-class CensusDVCDocument final
-    :public CensusDocument
-{
-  public:
-    CensusDVCDocument() = default;
-    ~CensusDVCDocument() override = default;
-
-  private:
-    CensusDVCDocument(CensusDVCDocument const&) = delete;
-    CensusDVCDocument& operator=(CensusDVCDocument const&) = delete;
-
-    wxDataViewCtrl& PredominantViewWindow() const;
-
-    DECLARE_DYNAMIC_CLASS(CensusDVCDocument)
-};
-
-class CensusGridDocument final
-    :public CensusDocument
-{
-  public:
-    CensusGridDocument() = default;
-    ~CensusGridDocument() override = default;
-
-  private:
-    CensusGridDocument(CensusGridDocument const&) = delete;
-    CensusGridDocument& operator=(CensusGridDocument const&) = delete;
-
-    wxGrid& PredominantViewWindow() const;
 
-    DECLARE_DYNAMIC_CLASS(CensusGridDocument)
+    DECLARE_DYNAMIC_CLASS(CensusDocument)
 };
 
 #endif // census_document_hpp
diff --git a/census_view.cpp b/census_view.cpp
index 214e149..c919081 100644
--- a/census_view.cpp
+++ b/census_view.cpp
@@ -52,7 +52,6 @@
 
 #include <boost/filesystem/convenience.hpp> // basename()
 
-#include <wx/dataview.h>
 #include <wx/datectrl.h>
 #include <wx/grid.h>
 #include <wx/headercol.h>               // wxCOL_WIDTH_DEFAULT
@@ -90,854 +89,6 @@ std::string insert_spaces_between_words(std::string const& 
s)
     return r;
 }
 
-/// Data needed to create UI for tn_range<> types.
-
-struct tn_range_variant_data
-    :public wxVariantData
-{
-    tn_range_variant_data(std::string const& a_value, double a_min, double 
a_max)
-        :value {a_value}
-        ,min   {a_min}
-        ,max   {a_max}
-    {
-    }
-
-    tn_range_variant_data(tn_range_base const& r)
-        :value {r.str()}
-        ,min   {r.universal_minimum()}
-        ,max   {r.universal_maximum()}
-    {
-    }
-
-    bool Eq(wxVariantData& data) const override
-    {
-        tn_range_variant_data* d = dynamic_cast<tn_range_variant_data*>(&data);
-        if(!d)
-            return false;
-        return value == d->value && min == d->min && max == d->max;
-    }
-
-    wxString GetType() const override { return 
typeid(tn_range_variant_data).name(); }
-
-    wxVariantData* Clone() const override
-    {
-        return new(wx) tn_range_variant_data(value, min, max);
-    }
-
-    std::string value;
-    double min, max;
-};
-
-// class RangeTypeRenderer
-
-class RangeTypeRenderer
-    :public wxDataViewCustomRenderer
-{
-  protected:
-    RangeTypeRenderer();
-
-  public:
-    bool HasEditorCtrl() const override { return true; }
-    wxWindow* CreateEditorCtrl
-        (wxWindow*        parent
-        ,wxRect           label_rect
-        ,wxVariant const& value
-        ) override;
-    bool GetValueFromEditorCtrl(wxWindow* editor, wxVariant& value) override;
-    bool Render(wxRect rect, wxDC* dc, int state) override;
-    wxSize GetSize() const override;
-    bool SetValue(wxVariant const& value) override;
-    bool GetValue(wxVariant& value) const override;
-
-  protected:
-    virtual wxWindow* DoCreateEditor
-        (wxWindow*                    parent
-        ,wxRect                const& rect
-        ,tn_range_variant_data const& data
-        ) = 0;
-    virtual std::string DoGetValueFromEditor(wxWindow* editor) = 0;
-
-    std::string value_;
-    double      min_;
-    double      max_;
-};
-
-RangeTypeRenderer::RangeTypeRenderer()
-    :wxDataViewCustomRenderer
-    (typeid(tn_range_variant_data).name()
-    ,wxDATAVIEW_CELL_EDITABLE
-    ,wxDVR_DEFAULT_ALIGNMENT
-    )
-{
-}
-
-wxWindow* RangeTypeRenderer::CreateEditorCtrl
-    (wxWindow*        parent
-    ,wxRect           label_rect
-    ,wxVariant const& value
-    )
-{
-    tn_range_variant_data const* data = 
dynamic_cast<tn_range_variant_data*>(value.GetData());
-    LMI_ASSERT(data);
-
-    // Always use default height for editor controls
-    wxRect rect(label_rect);
-    rect.height = -1;
-
-    return DoCreateEditor(parent, rect, *data);
-}
-
-bool RangeTypeRenderer::GetValueFromEditorCtrl(wxWindow* editor, wxVariant& 
value)
-{
-    std::string const val = DoGetValueFromEditor(editor);
-    value = new(wx) tn_range_variant_data(val, min_, max_);
-    return true;
-}
-
-bool RangeTypeRenderer::Render(wxRect rect, wxDC* dc, int state)
-{
-    RenderText(value_, 0, rect, dc, state);
-    return true;
-}
-
-wxSize RangeTypeRenderer::GetSize() const
-{
-    wxSize sz = GetTextExtent(value_);
-
-    // Allow some space for the spin button, which is approximately the size of
-    // a scrollbar (and getting pixel-exact value would be complicated). Also
-    // add some whitespace between the text and the button:
-    sz.x += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
-    sz.x += GetTextExtent("M").x;
-
-    return sz;
-}
-
-bool RangeTypeRenderer::SetValue(wxVariant const& value)
-{
-    tn_range_variant_data const* data = 
dynamic_cast<tn_range_variant_data*>(value.GetData());
-    LMI_ASSERT(data);
-
-    value_ = data->value;
-    min_   = data->min;
-    max_   = data->max;
-    return true;
-}
-
-bool RangeTypeRenderer::GetValue(wxVariant& value) const
-{
-    value = new(wx) tn_range_variant_data(value_, min_, max_);
-    return true;
-}
-
-// class IntSpinRenderer
-
-class IntSpinRenderer
-    :public RangeTypeRenderer
-{
-  public:
-    IntSpinRenderer() : RangeTypeRenderer() {}
-
-  protected:
-    wxWindow* DoCreateEditor
-        (wxWindow*                    parent
-        ,wxRect                const& rect
-        ,tn_range_variant_data const& data
-        ) override;
-    std::string DoGetValueFromEditor(wxWindow* editor) override;
-};
-
-wxWindow* IntSpinRenderer::DoCreateEditor
-    (wxWindow*                    parent
-    ,wxRect                const& rect
-    ,tn_range_variant_data const& data
-    )
-{
-    return new(wx) wxSpinCtrl
-        (parent
-        ,wxID_ANY
-        ,data.value
-        ,rect.GetTopLeft()
-        ,rect.GetSize()
-        ,wxSP_ARROW_KEYS | wxTE_PROCESS_ENTER
-        ,bourn_cast<int>(data.min)
-        ,bourn_cast<int>(data.max)
-        ,value_cast<int>(data.value)
-        );
-}
-
-std::string IntSpinRenderer::DoGetValueFromEditor(wxWindow* editor)
-{
-    wxSpinCtrl* spin = dynamic_cast<wxSpinCtrl*>(editor);
-    LMI_ASSERT(spin);
-
-    return value_cast<std::string>(spin->GetValue());
-}
-
-// class DoubleRangeRenderer
-
-class DoubleRangeRenderer
-    :public RangeTypeRenderer
-{
-  public:
-    DoubleRangeRenderer() : RangeTypeRenderer() {}
-
-  protected:
-    wxWindow* DoCreateEditor
-        (wxWindow*                    parent
-        ,wxRect                const& rect
-        ,tn_range_variant_data const& data
-        ) override;
-    std::string DoGetValueFromEditor(wxWindow* editor) override;
-};
-
-wxWindow* DoubleRangeRenderer::DoCreateEditor
-    (wxWindow*                    parent
-    ,wxRect                const& rect
-    ,tn_range_variant_data const& data
-    )
-{
-    wxFloatingPointValidator<double> val;
-    val.SetRange(data.min, data.max);
-
-    wxTextCtrl* ctrl = new(wx) wxTextCtrl
-        (parent
-        ,wxID_ANY
-        ,data.value
-        ,rect.GetTopLeft()
-        ,rect.GetSize()
-        ,wxTE_PROCESS_ENTER
-        ,val);
-
-    // select the text in the control an place the cursor at the end
-    // (same as wxDataViewTextRenderer)
-    ctrl->SetInsertionPointEnd();
-    ctrl->SelectAll();
-
-    return ctrl;
-}
-
-std::string DoubleRangeRenderer::DoGetValueFromEditor(wxWindow* editor)
-{
-    wxTextCtrl* ctrl = dynamic_cast<wxTextCtrl*>(editor);
-    LMI_ASSERT(ctrl);
-
-    return ctrl->GetValue().ToStdString();
-}
-
-// class DateRenderer
-
-class DateRenderer
-    :public RangeTypeRenderer
-{
-  public:
-    DateRenderer() : RangeTypeRenderer() {}
-    bool Render(wxRect rect, wxDC* dc, int state) override;
-
-  protected:
-    wxWindow* DoCreateEditor
-        (wxWindow*                    parent
-        ,wxRect                const& rect
-        ,tn_range_variant_data const& data
-        ) override;
-    std::string DoGetValueFromEditor(wxWindow* editor) override;
-};
-
-wxWindow* DateRenderer::DoCreateEditor
-    (wxWindow*                    parent
-    ,wxRect                const& rect
-    ,tn_range_variant_data const& data
-    )
-{
-    // Always use default height for editor controls
-    wxRect r(rect);
-    r.height = -1;
-
-    wxDatePickerCtrl* ctrl = new(wx) wxDatePickerCtrl
-        (parent
-        ,wxID_ANY
-        ,ConvertDateToWx(value_cast<calendar_date>(data.value))
-        ,r.GetTopLeft()
-        ,r.GetSize());
-
-    ctrl->SetRange
-        (ConvertDateToWx(jdn_t(static_cast<int>(data.min)))
-        ,ConvertDateToWx(jdn_t(static_cast<int>(data.max)))
-        );
-
-    return ctrl;
-}
-
-bool DateRenderer::Render(wxRect rect, wxDC* dc, int state)
-{
-    // Use wx for date formatting so that it is identical to the way 
wxDatePickerCtrl does it.
-    wxDateTime const date = ConvertDateToWx(value_cast<calendar_date>(value_));
-    RenderText(date.FormatDate(), 0, rect, dc, state);
-    return true;
-}
-
-std::string DateRenderer::DoGetValueFromEditor(wxWindow* editor)
-{
-    wxDatePickerCtrl* ctrl = dynamic_cast<wxDatePickerCtrl*>(editor);
-    LMI_ASSERT(ctrl);
-
-    return value_cast<std::string>(ConvertDateFromWx(ctrl->GetValue()));
-}
-
-/// Data needed to create UI for input sequences.
-
-struct input_sequence_variant_data
-    :public wxVariantData
-{
-    input_sequence_variant_data
-        (std::string const& a_value
-        ,Input       const* a_input
-        ,std::string const& a_field
-        )
-        :value {a_value}
-        ,input {a_input}
-        ,field {a_field}
-    {
-    }
-
-    input_sequence_variant_data(input_sequence_variant_data const&) = delete;
-    input_sequence_variant_data& operator=(input_sequence_variant_data const&) 
= delete;
-
-    bool Eq(wxVariantData& data) const override
-    {
-        input_sequence_variant_data* d = 
dynamic_cast<input_sequence_variant_data*>(&data);
-        if(!d)
-            return false;
-        return value == d->value;
-    }
-
-    wxString GetType() const override { return 
typeid(input_sequence_variant_data).name(); }
-
-    wxVariantData* Clone() const override
-    {
-        return new(wx) input_sequence_variant_data(value, input, field);
-    }
-
-    std::string value;
-    Input const* input;
-    std::string field;
-};
-
-class DatumSequenceRenderer
-    :public wxDataViewCustomRenderer
-{
-  public:
-    DatumSequenceRenderer();
-    DatumSequenceRenderer(DatumSequenceRenderer const&) = delete;
-    DatumSequenceRenderer& operator=(DatumSequenceRenderer const&) = delete;
-    bool HasEditorCtrl() const override { return true; }
-    wxWindow* CreateEditorCtrl
-        (wxWindow*        parent
-        ,wxRect           label_rect
-        ,wxVariant const& value
-        ) override;
-    bool GetValueFromEditorCtrl(wxWindow* editor, wxVariant& value) override;
-    bool Render(wxRect rect, wxDC* dc, int state) override;
-    wxSize GetSize() const override;
-    bool SetValue(wxVariant const& value) override;
-    bool GetValue(wxVariant& value) const override;
-
-    std::string  value_;
-    Input const* input_;
-    std::string  field_;
-};
-
-DatumSequenceRenderer::DatumSequenceRenderer()
-    :wxDataViewCustomRenderer
-        (typeid(input_sequence_variant_data).name()
-        ,wxDATAVIEW_CELL_EDITABLE
-        ,wxDVR_DEFAULT_ALIGNMENT
-        )
-    ,input_(nullptr)
-{
-}
-
-wxWindow* DatumSequenceRenderer::CreateEditorCtrl
-    (wxWindow*        parent
-    ,wxRect           label_rect
-    ,wxVariant const& value
-    )
-{
-    input_sequence_variant_data const* data = 
dynamic_cast<input_sequence_variant_data*>(value.GetData());
-    LMI_ASSERT(data);
-    LMI_ASSERT(data->input);
-
-    InputSequenceEntry* ctrl = new(wx) InputSequenceEntry(parent, wxID_ANY, 
"sequence_editor");
-
-    ctrl->text_ctrl().SetValue(data->value.c_str());
-    ctrl->input(*data->input);
-    ctrl->field_name(data->field);
-
-    ctrl->SetSize(label_rect);
-
-    return ctrl;
-}
-
-bool DatumSequenceRenderer::GetValueFromEditorCtrl(wxWindow* editor, 
wxVariant& value)
-{
-    InputSequenceEntry* ctrl = dynamic_cast<InputSequenceEntry*>(editor);
-    LMI_ASSERT(ctrl);
-
-    value = new(wx) input_sequence_variant_data
-        (ctrl->text_ctrl().GetValue().ToStdString()
-        ,&ctrl->input()
-        ,ctrl->field_name());
-    return true;
-}
-
-bool DatumSequenceRenderer::Render(wxRect rect, wxDC* dc, int state)
-{
-    RenderText(value_, 0, rect, dc, state);
-    return true;
-}
-
-wxSize DatumSequenceRenderer::GetSize() const
-{
-    wxSize sz = GetTextExtent(value_);
-
-    // Add size of the "..." button. We assume it will use the same font that 
this renderer
-    // uses and add some extra whitespace in addition to InputSequenceButton's 
8px padding.
-    sz.x += 16 + GetTextExtent("...").x;
-
-    return sz;
-}
-
-bool DatumSequenceRenderer::SetValue(wxVariant const& value)
-{
-    input_sequence_variant_data const* data = 
dynamic_cast<input_sequence_variant_data*>(value.GetData());
-    LMI_ASSERT(data);
-
-    value_ = data->value;
-    input_ = data->input;
-    field_ = data->field;
-    return true;
-}
-
-bool DatumSequenceRenderer::GetValue(wxVariant& value) const
-{
-    value = new(wx) input_sequence_variant_data(value_, input_, field_);
-    return true;
-}
-
-// This class is used to implement conversion to and from wxVariant for use by
-// wxDVC renderers in a single place.
-
-class renderer_type_converter
-{
-  public:
-    virtual ~renderer_type_converter() = default;
-    virtual wxVariant to_variant
-        (any_member<Input> const& x
-        ,Input             const& row
-        ,std::string       const& col
-        ) const = 0;
-    virtual std::string from_variant(wxVariant const& x) const = 0;
-    virtual char const* variant_type() const = 0;
-    virtual wxDataViewRenderer* create_renderer(any_member<Input> const& 
exemplar) const = 0;
-
-    static renderer_type_converter const& get(any_member<Input> const& value);
-
-  private:
-    template<typename T>
-    static renderer_type_converter const& get_impl();
-};
-
-// class renderer_bool_converter
-
-class renderer_bool_converter : public renderer_type_converter
-{
-    wxVariant to_variant
-        (any_member<Input> const& x
-        ,Input             const&
-        ,std::string       const&
-        ) const override
-    {
-        std::string const s(x.str());
-        return
-              "Yes" == s ? true
-            : "No"  == s ? false
-            : throw "Invalid boolean value."
-            ;
-    }
-
-    std::string from_variant(wxVariant const& x) const override
-    {
-        return x.GetBool() ? "Yes" : "No";
-    }
-
-    char const* variant_type() const override
-    {
-        return "bool";
-    }
-
-    wxDataViewRenderer* create_renderer(any_member<Input> const&) const 
override
-    {
-        return new(wx) wxDataViewToggleRenderer
-            ("bool"
-            ,wxDATAVIEW_CELL_ACTIVATABLE
-            ,wxALIGN_CENTER
-            );
-    }
-};
-
-// class renderer_enum_converter
-
-class renderer_enum_converter : public renderer_type_converter
-{
-    wxVariant to_variant
-        (any_member<Input> const& x
-        ,Input             const&
-        ,std::string       const&
-        ) const override
-    {
-        return wxString(x.str());
-    }
-
-    std::string from_variant(wxVariant const& x) const override
-    {
-        return x.GetString().ToStdString();
-    }
-
-    char const* variant_type() const override
-    {
-        return "string";
-    }
-
-    wxDataViewRenderer* create_renderer(any_member<Input> const& exemplar) 
const override
-    {
-        mc_enum_base const* as_enum = member_cast<mc_enum_base>(exemplar);
-
-        std::vector<std::string> const& all_strings = as_enum->all_strings();
-        wxArrayString choices;
-        choices.assign(all_strings.begin(), all_strings.end());
-        return new(wx) wxDataViewChoiceRenderer(choices, 
wxDATAVIEW_CELL_EDITABLE);
-    }
-};
-
-// class renderer_sequence_converter
-
-class renderer_sequence_converter : public renderer_type_converter
-{
-  public:
-    wxVariant to_variant
-        (any_member<Input> const& x
-        ,Input             const& row
-        ,std::string       const& col
-        ) const override
-    {
-        return new(wx) input_sequence_variant_data(x.str(), &row, col);
-    }
-
-    std::string from_variant(wxVariant const& x) const override
-    {
-        input_sequence_variant_data const* data = 
dynamic_cast<input_sequence_variant_data*>(x.GetData());
-        LMI_ASSERT(data);
-        return data->value;
-    }
-
-    char const* variant_type() const override
-    {
-        return typeid(input_sequence_variant_data).name();
-    }
-
-    wxDataViewRenderer* create_renderer(any_member<Input> const&) const 
override
-    {
-        return new(wx) DatumSequenceRenderer();
-    }
-};
-
-// class renderer_range_converter
-
-class renderer_range_converter : public renderer_type_converter
-{
-  public:
-    wxVariant to_variant
-        (any_member<Input> const& x
-        ,Input             const&
-        ,std::string       const&
-        ) const override
-    {
-        tn_range_base const* as_range = member_cast<tn_range_base>(x);
-        LMI_ASSERT(as_range);
-        return new(wx) tn_range_variant_data(*as_range);
-    }
-
-    std::string from_variant(wxVariant const& x) const override
-    {
-        tn_range_variant_data const* data = 
dynamic_cast<tn_range_variant_data*>(x.GetData());
-        LMI_ASSERT(data);
-        return data->value;
-    }
-
-    char const* variant_type() const override
-    {
-        return typeid(tn_range_variant_data).name();
-    }
-};
-
-class renderer_int_range_converter : public renderer_range_converter
-{
-  public:
-    wxDataViewRenderer* create_renderer(any_member<Input> const&) const 
override
-    {
-        return new(wx) IntSpinRenderer();
-    }
-};
-
-class renderer_double_range_converter : public renderer_range_converter
-{
-  public:
-    wxDataViewRenderer* create_renderer(any_member<Input> const&) const 
override
-    {
-        return new(wx) DoubleRangeRenderer();
-    }
-};
-
-class renderer_date_converter : public renderer_range_converter
-{
-  public:
-    wxDataViewRenderer* create_renderer(any_member<Input> const&) const 
override
-    {
-        return new(wx) DateRenderer();
-    }
-};
-
-// class renderer_fallback_converter
-
-class renderer_fallback_converter : public renderer_type_converter
-{
-  public:
-    wxVariant to_variant
-        (any_member<Input> const& x
-        ,Input             const&
-        ,std::string       const&
-        ) const override
-    {
-        // Strings containing new line characters are currently not displayed
-        // correctly by wxDataViewCtrl, so display the value on a single line
-        // after converting any optional new lines to the Unicode character
-        // representing them.
-        wxString s(x.str());
-        s.Replace("\n", RETURN_SYMBOL, true);
-        return s;
-    }
-
-    std::string from_variant(wxVariant const& x) const override
-    {
-        // Undo the replacement done above. Notice that this will (wrongly)
-        // translate any RETURN_SYMBOL characters entered by the user into the
-        // string to new lines, but this character is not supposed to be used
-        // in any of the cells values, so just ignore this problem for now.
-        wxString s = x.GetString();
-        s.Replace(RETURN_SYMBOL, "\n", true);
-        return s.ToStdString();
-    }
-
-    char const* variant_type() const override
-    {
-        return "string";
-    }
-
-    wxDataViewRenderer* create_renderer(any_member<Input> const&) const 
override
-    {
-        return new(wx) wxDataViewTextRenderer("string", 
wxDATAVIEW_CELL_EDITABLE);
-    }
-
-  private:
-    static const wchar_t RETURN_SYMBOL = 0x23ce;
-};
-
-renderer_type_converter const& renderer_type_converter::get(any_member<Input> 
const& value)
-{
-    if(exact_cast<mce_yes_or_no>(value))
-        {
-        return get_impl<renderer_bool_converter>();
-        }
-    else if(exact_cast<datum_string>(value))
-        {
-        return get_impl<renderer_fallback_converter>();
-        }
-    else if(is_reconstitutable_as<datum_sequence>(value))
-        {
-        return get_impl<renderer_sequence_converter>();
-        }
-    else if(is_reconstitutable_as<mc_enum_base  >(value))
-        {
-        return get_impl<renderer_enum_converter>();
-        }
-    else if(is_reconstitutable_as<tn_range_base >(value))
-        {
-        tn_range_base const* as_range = member_cast<tn_range_base>(value);
-        if(typeid(int) == as_range->value_type())
-            {
-            return get_impl<renderer_int_range_converter>();
-            }
-        else if(typeid(double) == as_range->value_type())
-            {
-            return get_impl<renderer_double_range_converter>();
-            }
-        else if(typeid(calendar_date) == as_range->value_type())
-            {
-            return get_impl<renderer_date_converter>();
-            }
-        else
-            {
-            // Fall through to warn and treat datum as string.
-            }
-        }
-    else
-        {
-        warning()
-            << "Type '"
-            << lmi::TypeInfo(value.type())
-            << "' not recognized. Please report this anomaly."
-            << LMI_FLUSH
-            ;
-        // Fall through to treat datum as string.
-        }
-
-    return get_impl<renderer_fallback_converter>();
-}
-
-template<typename T>
-renderer_type_converter const& renderer_type_converter::get_impl()
-{
-    static T singleton;
-    return singleton;
-}
-
-} // Unnamed namespace.
-
-/// Interface to the data for wxDataViewCtrl.
-
-class CensusViewDataViewModel : public wxDataViewIndexListModel
-{
-  public:
-    // Cell serial number: always shown in first column.
-    static int const Col_CellNum = 0;
-
-    CensusViewDataViewModel(CensusDVCView& view)
-        :view_ {view}
-    {
-    }
-
-    void GetValueByRow(wxVariant& variant, unsigned int row, unsigned int col) 
const override;
-    bool SetValueByRow(wxVariant const&, unsigned int, unsigned int) override;
-
-    unsigned int GetColumnCount() const override;
-
-    wxString GetColumnType(unsigned int col) const override;
-
-    std::string const& col_name(int col) const;
-    any_member<Input>& cell_at(int row, int col);
-    any_member<Input> const& cell_at(int row, int col) const;
-
-  private:
-    std::vector<std::string> const& all_headers() const;
-
-    CensusDVCView& view_;
-};
-
-void CensusViewDataViewModel::GetValueByRow
-    (wxVariant&   variant
-    ,unsigned int row
-    ,unsigned int col
-    ) const
-{
-    if(col == Col_CellNum)
-        {
-        // WX !! wxVariant::operator=() is overloaded for numerous
-        // types, including 'long int' but excluding 'int'.
-        variant = static_cast<long int>(bourn_cast<int>(1 + row));
-        }
-    else
-        {
-        any_member<Input> const& cell = cell_at(row, col);
-        renderer_type_converter const& conv = 
renderer_type_converter::get(cell);
-        Input const& row_data = view_.cell_parms()[row];
-
-        variant = conv.to_variant(cell, row_data, col_name(col));
-        }
-}
-
-bool CensusViewDataViewModel::SetValueByRow
-    (wxVariant const& variant
-    ,unsigned int     row
-    ,unsigned int     col
-    )
-{
-    LMI_ASSERT(col != Col_CellNum);
-
-    any_member<Input>& cell = cell_at(row, col);
-    renderer_type_converter const& conv = renderer_type_converter::get(cell);
-
-    std::string const prev_val = cell.str();
-    std::string new_val = conv.from_variant(variant);
-
-    if(prev_val == new_val)
-        return false;
-
-    cell = new_val;
-
-    Input& model = view_.cell_parms()[row];
-    model.Reconcile();
-
-    view_.document().Modify(true);
-
-    return true;
-}
-
-// Avoid using unsigned types in an interface.
-unsigned int CensusViewDataViewModel::GetColumnCount() const
-{
-    // "+ 1" for cell serial number in first column.
-    return bourn_cast<unsigned int>(lmi::ssize(all_headers()) + 1);
-}
-
-wxString CensusViewDataViewModel::GetColumnType(unsigned int col) const
-{
-    if(col == Col_CellNum)
-        {
-        return "long";
-        }
-    else
-        {
-        any_member<Input> const& exemplar = cell_at(0, col);
-        renderer_type_converter const& conv = 
renderer_type_converter::get(exemplar);
-        return conv.variant_type();
-        }
-}
-
-std::string const& CensusViewDataViewModel::col_name(int col) const
-{
-    LMI_ASSERT(0 < col);
-    // "- 1" because first column is cell serial number.
-    return all_headers()[col - 1];
-}
-
-inline any_member<Input>& CensusViewDataViewModel::cell_at(int row, int col)
-{
-    return view_.cell_parms()[row][col_name(col)];
-}
-
-inline any_member<Input> const& CensusViewDataViewModel::cell_at(int row, int 
col) const
-{
-    return view_.cell_parms()[row][col_name(col)];
-}
-
-inline std::vector<std::string> const& CensusViewDataViewModel::all_headers() 
const
-{
-    return view_.case_parms()[0].member_names();
-}
-
-namespace
-{
-
 // Declare free functions corresponding to their namesakes in 
CensusViewGridTable
 // that can be used in the implementation of the custom editors below, which
 // are defined before CensusViewGridTable is declared.
@@ -1482,7 +633,7 @@ class CensusViewGridTable
     // Cell serial number: always shown in the first column.
     static int const Col_CellNum = 0;
 
-    explicit CensusViewGridTable(CensusGridView& view);
+    explicit CensusViewGridTable(CensusView& view);
 
     // return the number of rows and columns in this table.
     int GetNumberRows() override;
@@ -1527,12 +678,12 @@ class CensusViewGridTable
     any_member<Input> const& cell_at(int row, std::string const& col) const;
     std::vector<std::string> const& all_headers() const;
 
-    CensusGridView&  view_;
+    CensusView&      view_;
 
     std::vector<int> visible_columns_;
 };
 
-CensusViewGridTable::CensusViewGridTable(CensusGridView& view)
+CensusViewGridTable::CensusViewGridTable(CensusView& view)
     :view_ {view}
 {
     wxGrid const* grid = view.grid_window_;
@@ -1785,7 +936,12 @@ std::string const& col_name(wxGridTableBase const& table, 
int col)
 
 // class CensusView
 
+IMPLEMENT_DYNAMIC_CLASS(CensusView, ViewEx)
+
 BEGIN_EVENT_TABLE(CensusView, ViewEx)
+    EVT_GRID_CELL_RIGHT_CLICK(                   CensusView::UponRightClick    
         )
+    EVT_GRID_CELL_CHANGED(                       CensusView::UponValueChanged  
         )
+    EVT_GRID_COL_AUTO_SIZE(                      
CensusView::UponColumnAutoSize         )
     EVT_MENU(XRCID("edit_cell"                 ),CensusView::UponEditCell      
         )
     EVT_MENU(XRCID("edit_class"                ),CensusView::UponEditClass     
         )
     EVT_MENU(XRCID("edit_case"                 ),CensusView::UponEditCase      
         )
@@ -1818,6 +974,7 @@ BEGIN_EVENT_TABLE(CensusView, ViewEx)
     EVT_UPDATE_UI(XRCID("copy_census"          
),CensusView::UponUpdateColumnValuesVary )
     EVT_UPDATE_UI(XRCID("paste_census"         
),CensusView::UponUpdateAlwaysEnabled    )
     EVT_UPDATE_UI(XRCID("add_cell"             
),CensusView::UponUpdateAlwaysEnabled    )
+    EVT_UPDATE_UI(XRCID("delete_cells"         
),CensusView::UponUpdateAlwaysEnabled    )
     EVT_UPDATE_UI(XRCID("column_width_varying" 
),CensusView::UponUpdateAlwaysEnabled    )
     EVT_UPDATE_UI(XRCID("column_width_fixed"   
),CensusView::UponUpdateAlwaysEnabled    )
     // Disable these printing commands on the "File" menu: specialized
@@ -1828,36 +985,12 @@ BEGIN_EVENT_TABLE(CensusView, ViewEx)
     EVT_UPDATE_UI(XRCID("print_pdf"            
),CensusView::UponUpdateAlwaysDisabled   )
 END_EVENT_TABLE()
 
-IMPLEMENT_DYNAMIC_CLASS(CensusDVCView, CensusView)
-
-BEGIN_EVENT_TABLE(CensusDVCView, CensusView)
-    EVT_DATAVIEW_ITEM_CONTEXT_MENU (wxID_ANY    ,CensusDVCView::UponRightClick 
            )
-    EVT_DATAVIEW_ITEM_VALUE_CHANGED(wxID_ANY    
,CensusDVCView::UponValueChanged           )
-    EVT_UPDATE_UI(XRCID("delete_cells"         
),CensusDVCView::UponUpdateNonemptySelection)
-END_EVENT_TABLE()
-
-IMPLEMENT_DYNAMIC_CLASS(CensusGridView, CensusView)
-
-BEGIN_EVENT_TABLE(CensusGridView, CensusView)
-    EVT_GRID_CELL_RIGHT_CLICK(                   
CensusGridView::UponRightClick         )
-    EVT_GRID_CELL_CHANGED(                       
CensusGridView::UponValueChanged       )
-    EVT_GRID_COL_AUTO_SIZE(                      
CensusGridView::UponColumnAutoSize     )
-    EVT_UPDATE_UI(XRCID("delete_cells"         
),CensusGridView::UponUpdateAlwaysEnabled)
-END_EVENT_TABLE()
-
 CensusView::CensusView()
     :ViewEx            {}
     ,autosize_columns_ {false}
 {
 }
 
-CensusDVCView::CensusDVCView()
-    :CensusView        {}
-    ,list_window_      {nullptr}
-    ,list_model_       {new(wx) CensusViewDataViewModel(*this)}
-{
-}
-
 inline std::vector<Input>& CensusView::case_parms()
 {
     return document().doc_.case_parms_;
@@ -1948,29 +1081,7 @@ bool 
CensusView::column_value_varies_across_cells(std::string const& header) con
     return false;
 }
 
-wxWindow* CensusDVCView::CreateChildWindow()
-{
-    list_window_ = new(wx) wxDataViewCtrl
-        (GetFrame()
-        ,wxID_ANY
-        ,wxDefaultPosition
-        ,wxDefaultSize
-        ,wxDV_ROW_LINES | wxDV_MULTIPLE
-        );
-
-    list_window_->AssociateModel(list_model_.get());
-
-    // Show headers.
-    document().Modify(false);
-    list_model_->Reset(lmi::ssize(cell_parms()));
-    Update();
-
-    list_window_->Select(list_model_->GetItem(0));
-
-    return list_window_;
-}
-
-wxWindow* CensusGridView::CreateChildWindow()
+wxWindow* CensusView::CreateChildWindow()
 {
     // Create and customize the grid window: we want to hide its row labels
     // because we show our own row number column, tweak its alignment slightly
@@ -2027,14 +1138,7 @@ oenum_mvc_dv_rc CensusView::edit_parameters
         );
 }
 
-int CensusDVCView::current_row()
-{
-    int row = list_model_->GetRow(list_window_->GetSelection());
-    LMI_ASSERT(0 <= row && row < bourn_cast<int>(list_model_->GetCount()));
-    return row;
-}
-
-int CensusGridView::current_row()
+int CensusView::current_row()
 {
     auto const& row = grid_window_->GetGridCursorRow();
     LMI_ASSERT(0 <= row && row < grid_table_->GetRowsCount());
@@ -2182,56 +1286,7 @@ void CensusView::apply_changes
         }
 }
 
-void CensusDVCView::update_visible_columns()
-{
-    int width = autosize_columns_ ? wxCOL_WIDTH_AUTOSIZE : wxCOL_WIDTH_DEFAULT;
-
-    list_window_->ClearColumns();
-
-    // Column zero (cell serial number) is always shown.
-    list_window_->AppendColumn
-        (new(wx) wxDataViewColumn
-            ("Cell"
-            ,new(wx) wxDataViewTextRenderer("long", wxDATAVIEW_CELL_INERT)
-            ,CensusViewDataViewModel::Col_CellNum
-            ,width
-            ,wxALIGN_LEFT
-            ,wxDATAVIEW_COL_RESIZABLE
-            )
-        );
-
-    // Display exactly those columns whose rows aren't all identical. For
-    // this purpose, consider as "rows" the individual cells--and also the
-    // case and class defaults, even though they aren't displayed in rows.
-    // Reason: although the case and class defaults are hidden, they're
-    // still information--so if the user made them different from any cell
-    // wrt some column, we respect that conscious decision.
-    std::vector<std::string> const& 
all_headers(case_parms()[0].member_names());
-    int column = 0;
-    for(auto const& header : all_headers)
-        {
-        ++column;
-        if(column_value_varies_across_cells(header))
-            {
-            any_member<Input> const& exemplar = list_model_->cell_at(0, 
column);
-            renderer_type_converter const& conv = 
renderer_type_converter::get(exemplar);
-            wxDataViewRenderer* renderer = conv.create_renderer(exemplar);
-            LMI_ASSERT(renderer);
-            list_window_->AppendColumn
-                (new(wx) wxDataViewColumn
-                    (insert_spaces_between_words(header)
-                    ,renderer
-                    ,column
-                    ,width
-                    ,wxALIGN_LEFT
-                    ,wxDATAVIEW_COL_RESIZABLE
-                    )
-                );
-            }
-        }
-}
-
-void CensusGridView::update_visible_columns()
+void CensusView::update_visible_columns()
 {
     // Display exactly those columns whose rows aren't all identical. For
     // this purpose, consider as "rows" the individual cells--and also the
@@ -2360,19 +1415,7 @@ void CensusView::UponEditCase(wxCommandEvent&)
 /// Make each nonfrozen column wide enough to display its widest entry,
 /// ignoring column headers.
 
-void CensusDVCView::UponColumnWidthVarying(wxCommandEvent&)
-{
-    autosize_columns_ = true;
-
-    wxWindowUpdateLocker u(list_window_);
-    for(int j = 0; j < bourn_cast<int>(list_window_->GetColumnCount()); ++j)
-        {
-        list_window_->GetColumn(j)->SetWidth(wxCOL_WIDTH_AUTOSIZE);
-        }
-    Update();
-}
-
-void CensusGridView::UponColumnWidthVarying(wxCommandEvent&)
+void CensusView::UponColumnWidthVarying(wxCommandEvent&)
 {
     autosize_columns_ = true;
 
@@ -2382,19 +1425,7 @@ void 
CensusGridView::UponColumnWidthVarying(wxCommandEvent&)
 
 /// Shrink all nonfrozen columns to default width.
 
-void CensusDVCView::UponColumnWidthFixed(wxCommandEvent&)
-{
-    autosize_columns_ = false;
-
-    wxWindowUpdateLocker u(list_window_);
-    for(int j = 0; j < bourn_cast<int>(list_window_->GetColumnCount()); ++j)
-        {
-        list_window_->GetColumn(j)->SetWidth(wxCOL_WIDTH_DEFAULT);
-        }
-    Update();
-}
-
-void CensusGridView::UponColumnWidthFixed(wxCommandEvent&)
+void CensusView::UponColumnWidthFixed(wxCommandEvent&)
 {
     autosize_columns_ = false;
 
@@ -2405,7 +1436,7 @@ void CensusGridView::UponColumnWidthFixed(wxCommandEvent&)
         }
 }
 
-void CensusGridView::UponRightClick(wxGridEvent&)
+void CensusView::UponRightClick(wxGridEvent&)
 {
     wxMenu* census_menu = wxXmlResource::Get()->LoadMenu("census_menu_ref");
     LMI_ASSERT(census_menu);
@@ -2413,37 +1444,14 @@ void CensusGridView::UponRightClick(wxGridEvent&)
     delete census_menu;
 }
 
-void CensusDVCView::UponRightClick(wxDataViewEvent& e)
-{
-    if(e.GetEventObject() != list_window_)
-        {
-        // This event should come only from the window pointed to by
-        // list_window_. Ignore it if it happens to come elsewhence.
-        e.Skip();
-        return;
-        }
-
-    wxMenu* census_menu = wxXmlResource::Get()->LoadMenu("census_menu_ref");
-    LMI_ASSERT(census_menu);
-    list_window_->PopupMenu(census_menu);
-    delete census_menu;
-}
-
-void CensusDVCView::UponValueChanged(wxDataViewEvent&)
-{
-    Timer timer;
-    Update();
-    status() << "Update: " << timer.stop().elapsed_msec_str() << std::flush;
-}
-
-void CensusGridView::UponValueChanged(wxGridEvent&)
+void CensusView::UponValueChanged(wxGridEvent&)
 {
     Timer timer;
     Update();
     status() << "Update: " << timer.stop().elapsed_msec_str() << std::flush;
 }
 
-void CensusGridView::UponColumnAutoSize(wxGridSizeEvent& e)
+void CensusView::UponColumnAutoSize(wxGridSizeEvent& e)
 {
     // Pass false to avoid setting min size to the best size.
     grid_window_->AutoSizeColumn(e.GetRowOrCol(), false);
@@ -2459,13 +1467,7 @@ void 
CensusView::UponUpdateAlwaysEnabled(wxUpdateUIEvent& e)
     e.Enable(true);
 }
 
-void CensusDVCView::UponUpdateSingleSelection(wxUpdateUIEvent& e)
-{
-    bool const is_single_sel = list_window_->GetSelection().IsOk();
-    e.Enable(is_single_sel);
-}
-
-void CensusGridView::UponUpdateSingleSelection(wxUpdateUIEvent& e)
+void CensusView::UponUpdateSingleSelection(wxUpdateUIEvent& e)
 {
     // We consider that in absence of any selected rows, the current row is the
     // selected/active one, so what we actually check for here is that we do
@@ -2484,13 +1486,7 @@ void 
CensusGridView::UponUpdateSingleSelection(wxUpdateUIEvent& e)
                 }
         }
 
-    e.Enable(is_single_sel);
-}
-
-void CensusDVCView::UponUpdateNonemptySelection(wxUpdateUIEvent& e)
-{
-    wxDataViewItemArray selection;
-    e.Enable(0 < list_window_->GetSelections(selection));
+    e.Enable(is_single_sel);
 }
 
 /// Conditionally enable copying.
@@ -2508,18 +1504,7 @@ void 
CensusDVCView::UponUpdateNonemptySelection(wxUpdateUIEvent& e)
 /// because if "IssueAge" varies, then so must either "DateOfBirth"
 /// or "EffectiveDate".
 
-void CensusDVCView::UponUpdateColumnValuesVary(wxUpdateUIEvent& e)
-{
-    static const std::string dob_header = 
insert_spaces_between_words("UseDOB");
-    int const n_cols = bourn_cast<int>(list_window_->GetColumnCount());
-    bool const disable =
-            1 == n_cols
-        || (2 == n_cols && dob_header == 
list_window_->GetColumn(1)->GetTitle())
-        ;
-    e.Enable(!disable);
-}
-
-void CensusGridView::UponUpdateColumnValuesVary(wxUpdateUIEvent& e)
+void CensusView::UponUpdateColumnValuesVary(wxUpdateUIEvent& e)
 {
     static const std::string dob_header = 
insert_spaces_between_words("UseDOB");
     int const n_cols = grid_table_->GetColsCount();
@@ -2539,7 +1524,7 @@ void 
CensusGridView::UponUpdateColumnValuesVary(wxUpdateUIEvent& e)
 /// Similarly, if an old employee class is no longer used, remove it; and
 ///  if a new one comes into use, display it.
 
-void CensusGridView::Update()
+void CensusView::Update()
 {
     LMI_ASSERT(grid_table_->GetRowsCount() == lmi::ssize(cell_parms()));
 
@@ -2549,16 +1534,6 @@ void CensusGridView::Update()
     update_visible_columns();
 }
 
-void CensusDVCView::Update()
-{
-    LMI_ASSERT(list_model_->GetCount() == cell_parms().size());
-
-    wxWindowUpdateLocker u(list_window_);
-
-    update_class_names();
-    update_visible_columns();
-}
-
 void CensusView::UponPrintCase(wxCommandEvent&)
 {
     DoAllCells(mce_emit_pdf_to_printer);
@@ -2624,26 +1599,7 @@ bool CensusView::DoAllCells(mcenum_emission emission)
     return true;
 }
 
-void CensusDVCView::UponAddCell(wxCommandEvent&)
-{
-    wxBusyCursor reverie;
-    Timer timer;
-
-    cell_parms().push_back(case_parms()[0]);
-    list_model_->RowAppended();
-
-    Update();
-    document().Modify(true);
-
-    wxDataViewItem const& z = list_model_->GetItem(list_model_->GetCount() - 
1);
-    list_window_->UnselectAll();
-    list_window_->Select(z);
-    list_window_->EnsureVisible(z);
-
-    status() << "Add: " << timer.stop().elapsed_msec_str() << std::flush;
-}
-
-void CensusGridView::UponAddCell(wxCommandEvent&)
+void CensusView::UponAddCell(wxCommandEvent&)
 {
     wxBusyCursor reverie;
     Timer timer;
@@ -2664,87 +1620,7 @@ void CensusGridView::UponAddCell(wxCommandEvent&)
     status() << "Add: " << timer.stop().elapsed_msec_str() << std::flush;
 }
 
-void CensusDVCView::UponDeleteCells(wxCommandEvent&)
-{
-    int n_items = bourn_cast<int>(list_model_->GetCount());
-    wxDataViewItemArray selection;
-    int n_sel_items = bourn_cast<int>(list_window_->GetSelections(selection));
-    LMI_ASSERT(n_sel_items == lmi::ssize(selection));
-    // This handler should have been disabled if no cell is selected.
-    LMI_ASSERT(0 < n_sel_items);
-
-    if(n_items == n_sel_items)
-        {
-        warning()
-            << "Cannot delete all cells. A census must always"
-            << " contain at least one cell."
-            << LMI_FLUSH
-            ;
-        return;
-        }
-
-    LMI_ASSERT(n_sel_items < n_items);
-
-    std::ostringstream oss;
-    oss
-        << "Irrevocably delete "
-        << n_sel_items
-        << " of "
-        << n_items
-        << " cells?"
-        ;
-    int yes_or_no = wxMessageBox
-        (oss.str()
-        ,"Confirm deletion"
-        ,wxYES_NO | wxICON_QUESTION
-        );
-    if(wxYES != yes_or_no)
-        {
-        return;
-        }
-
-    wxBusyCursor reverie;
-    Timer timer;
-
-    wxArrayInt erasures;
-    for(auto const& i : selection)
-        {
-        erasures.push_back(list_model_->GetRow(i));
-        }
-    std::sort(erasures.begin(), erasures.end());
-
-    LMI_ASSERT(lmi::ssize(cell_parms()) == n_items);
-
-    for(int j = lmi::ssize(erasures) - 1; 0 <= j; --j)
-        {
-        cell_parms().erase(erasures[j] + cell_parms().begin());
-        }
-    LMI_ASSERT(lmi::ssize(cell_parms()) == n_items - n_sel_items);
-
-    // Send notifications about changes to the wxDataViewCtrl model. Two things
-    // changed: some rows were deleted and cell number of some rows shifted
-    // accordingly.
-    list_model_->RowsDeleted(erasures);
-    for(int j = erasures.front(); j < lmi::ssize(cell_parms()); ++j)
-        {
-        list_model_->RowValueChanged(j, CensusViewDataViewModel::Col_CellNum);
-        }
-
-    int const newsel = std::min
-        (erasures.front()
-        ,lmi::ssize(cell_parms()) - 1
-        );
-    wxDataViewItem const& z = list_model_->GetItem(newsel);
-    list_window_->Select(z);
-    list_window_->EnsureVisible(z);
-
-    Update();
-    document().Modify(true);
-
-    status() << "Delete: " << timer.stop().elapsed_msec_str() << std::flush;
-}
-
-void CensusGridView::UponDeleteCells(wxCommandEvent&)
+void CensusView::UponDeleteCells(wxCommandEvent&)
 {
     auto const n_items = grid_table_->GetRowsCount();
 
@@ -2878,189 +1754,7 @@ void 
CensusView::UponRunCaseToGroupQuote(wxCommandEvent&)
 /// file are assumed to represent user intention). In this case,
 /// pasted data is appended to the cells that were already present.
 
-void CensusDVCView::UponPasteCensus(wxCommandEvent&)
-{
-    std::string const census_data = ClipboardEx::GetText();
-
-    std::vector<std::string> headers;
-    std::vector<Input> cells;
-
-    std::istringstream iss_census(census_data);
-    iss_census.imbue(tab_is_not_whitespace_locale());
-    std::string line;
-
-    // Get header line; parse into field names.
-    if(std::getline(iss_census, line, '\n'))
-        {
-        iss_census >> std::ws;
-
-        std::istringstream iss_line(line);
-        std::string token;
-
-        while(std::getline(iss_line, token, '\t'))
-            {
-            headers.push_back(token);
-            }
-        }
-    else
-        {
-        warning() << "Error pasting census data: no header line." << LMI_FLUSH;
-        return;
-        }
-
-    // Use a modifiable copy of case defaults as an archetype for new
-    // cells to be created by pasting. Modifications are conditionally
-    // written back to case defaults later.
-    Input archetype(case_parms()[0]);
-
-    // Force 'UseDOB' prn. Pasting it as a column never makes sense.
-    if(contains(headers, "UseDOB"))
-        {
-        warning() << "'UseDOB' is unnecessary and will be ignored." << 
std::flush;
-        }
-    bool const dob_pasted = contains(headers, "DateOfBirth");
-    bool const age_pasted = contains(headers, "IssueAge");
-    if(dob_pasted && age_pasted)
-        {
-        alarum()
-            << "Cannot paste both 'DateOfBirth' and 'IssueAge'."
-            << LMI_FLUSH
-            ;
-        }
-    else if(dob_pasted)
-        {
-        archetype["UseDOB"] = "Yes";
-        }
-    else if(age_pasted)
-        {
-        archetype["UseDOB"] = "No";
-        }
-    else
-        {
-        ; // Do nothing: neither age nor DOB pasted.
-        }
-
-    cells.reserve(std::count(census_data.begin(), census_data.end(), '\n'));
-
-    // Read each subsequent line into an input object representing one cell.
-    int current_line = 0;
-    while(std::getline(iss_census, line, '\n'))
-        {
-        ++current_line;
-
-        iss_census >> std::ws;
-
-        Input current_cell(archetype);
-
-        std::istringstream iss_line(line);
-        std::string token;
-        std::vector<std::string> values;
-
-        while(std::getline(iss_line, token, '\t'))
-            {
-            values.push_back(token);
-            }
-
-        if(values.size() != headers.size())
-            {
-            alarum()
-                << "Line #" << current_line << ": "
-                << "  (" << line << ") "
-                << "should have one value per column. "
-                << "Number of values: " << values.size() << "; "
-                << "number expected: " << headers.size() << "."
-                << LMI_FLUSH
-                ;
-            }
-
-        for(int j = 0; j < lmi::ssize(headers); ++j)
-            {
-            if(exact_cast<tnr_date>(current_cell[headers[j]]))
-                {
-                static int const jdn_min = calendar_date::gregorian_epoch_jdn;
-                static int const jdn_max = calendar_date::last_yyyy_date_jdn;
-                static int const ymd_min = JdnToYmd(jdn_t(jdn_min)).value();
-                static int const ymd_max = JdnToYmd(jdn_t(jdn_max)).value();
-                int z = value_cast<int>(values[j]);
-                if(jdn_min <= z && z <= jdn_max)
-                    {
-                    ; // Do nothing: JDN is the default expectation.
-                    }
-                else if(ymd_min <= z && z <= ymd_max)
-                    {
-                    z = YmdToJdn(ymd_t(z)).value();
-                    values[j] = value_cast<std::string>(z);
-                    }
-                else
-                    {
-                    alarum()
-                        << "Invalid date " << values[j]
-                        << " for '" << headers[j] << "'"
-                        << " on line " << current_line << "."
-                        << LMI_FLUSH
-                        ;
-                    }
-                }
-            current_cell[headers[j]] = values[j];
-            }
-        current_cell.Reconcile();
-        current_cell.RealizeAllSequenceInput();
-        cells.push_back(current_cell);
-
-        status() << "Added cell number " << cells.size() << '.' << std::flush;
-        }
-
-    if(0 == current_line)
-        {
-        warning() << "No cells to paste." << LMI_FLUSH;
-        return;
-        }
-
-    auto selection = lmi::ssize(cell_parms());
-
-    if(!document().IsModified() && !document().GetDocumentSaved())
-        {
-        case_parms ().clear();
-        case_parms ().push_back(archetype);
-        class_parms().clear();
-        class_parms().push_back(archetype);
-        cell_parms ().swap(cells);
-        selection = 0;
-        }
-    else if(configurable_settings::instance().census_paste_palimpsestically())
-        {
-        cell_parms().swap(cells);
-        // Cells that were copied from lmi have DOB and not IssueAge,
-        // so pasting them back in sets UseDOB. Force UseDOB for case
-        // and class defaults to prevent showing a UseDOB column with
-        // each cell set to "Yes".
-        for(auto& j : case_parms ()) {j["UseDOB"] = "Yes";}
-        for(auto& j : class_parms()) {j["UseDOB"] = "Yes";}
-        selection = 0;
-        }
-    else
-        {
-        cell_parms().reserve(cell_parms().size() + cells.size());
-        std::back_insert_iterator<std::vector<Input>> iip(cell_parms());
-        std::copy(cells.begin(), cells.end(), iip);
-        }
-
-    document().Modify(true);
-    list_model_->Reset(lmi::ssize(cell_parms()));
-    Update();
-    // Reset() leaves the listview unreachable from the keyboard
-    // because no row is selected--so select the first added row
-    // if possible, else the row after which no row was inserted.
-    wxDataViewItem const& z = list_model_->GetItem(selection);
-    list_window_->Select(z);
-    list_window_->EnsureVisible(z);
-
-    LMI_ASSERT(1 == case_parms().size());
-    LMI_ASSERT(!cell_parms ().empty());
-    LMI_ASSERT(!class_parms().empty());
-}
-
-void CensusGridView::UponPasteCensus(wxCommandEvent&)
+void CensusView::UponPasteCensus(wxCommandEvent&)
 {
     std::string const census_data = ClipboardEx::GetText();
 
diff --git a/census_view.hpp b/census_view.hpp
index ddf8568..50710c9 100644
--- a/census_view.hpp
+++ b/census_view.hpp
@@ -38,18 +38,18 @@
 #include <vector>
 
 class CensusDocument;
-class CensusViewDataViewModel;
 class CensusViewGridTable;
 
-class WXDLLIMPEXP_FWD_ADV wxDataViewEvent;
-class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
 class WXDLLIMPEXP_FWD_ADV wxGrid;
 class WXDLLIMPEXP_FWD_ADV wxGridEvent;
 class WXDLLIMPEXP_FWD_ADV wxGridSizeEvent;
 
-class CensusView
+class CensusView final
     :public ViewEx
 {
+    friend class CensusDocument;
+    friend class CensusViewGridTable;
+
   public:
     CensusView();
 
@@ -57,40 +57,43 @@ class CensusView
     CensusView(CensusView const&) = delete;
     CensusView& operator=(CensusView const&) = delete;
 
-    virtual void update_visible_columns() = 0;
+    void update_visible_columns();
 
-  protected:
     CensusDocument& document() const;
 
     // ViewEx required implementation.
+    wxWindow* CreateChildWindow() override;
     char const* icon_xrc_resource   () const override;
     char const* menubar_xrc_resource() const override;
 
     // Event handlers, in event-table order (reflecting GUI order)
-    void         UponEditCell               (wxCommandEvent&);
-    void         UponEditClass              (wxCommandEvent&);
-    void         UponEditCase               (wxCommandEvent&);
-    void         UponRunCell                (wxCommandEvent&);
-    void         UponRunCase                (wxCommandEvent&);
-    void         UponPrintCase              (wxCommandEvent&);
-    void         UponPrintCaseToDisk        (wxCommandEvent&);
-    void         UponRunCaseToSpreadsheet   (wxCommandEvent&);
-    void         UponRunCaseToGroupRoster   (wxCommandEvent&);
-    void         UponRunCaseToGroupQuote    (wxCommandEvent&);
-    void         UponCopyCensus             (wxCommandEvent&);
-    virtual void UponPasteCensus            (wxCommandEvent&) = 0;
-    virtual void UponAddCell                (wxCommandEvent&) = 0;
-    virtual void UponDeleteCells            (wxCommandEvent&) = 0;
-    virtual void UponColumnWidthVarying     (wxCommandEvent&) = 0;
-    virtual void UponColumnWidthFixed       (wxCommandEvent&) = 0;
-    void         UponUpdateAlwaysDisabled   (wxUpdateUIEvent&);
-    void         UponUpdateAlwaysEnabled    (wxUpdateUIEvent&);
-    virtual void UponUpdateSingleSelection  (wxUpdateUIEvent&) = 0;
-    virtual void UponUpdateColumnValuesVary (wxUpdateUIEvent&) = 0;
+    void UponRightClick             (wxGridEvent&);
+    void UponValueChanged           (wxGridEvent&);
+    void UponColumnAutoSize         (wxGridSizeEvent&);
+    void UponEditCell               (wxCommandEvent&);
+    void UponEditClass              (wxCommandEvent&);
+    void UponEditCase               (wxCommandEvent&);
+    void UponRunCell                (wxCommandEvent&);
+    void UponRunCase                (wxCommandEvent&);
+    void UponPrintCase              (wxCommandEvent&);
+    void UponPrintCaseToDisk        (wxCommandEvent&);
+    void UponRunCaseToSpreadsheet   (wxCommandEvent&);
+    void UponRunCaseToGroupRoster   (wxCommandEvent&);
+    void UponRunCaseToGroupQuote    (wxCommandEvent&);
+    void UponCopyCensus             (wxCommandEvent&);
+    void UponPasteCensus            (wxCommandEvent&);
+    void UponAddCell                (wxCommandEvent&);
+    void UponDeleteCells            (wxCommandEvent&);
+    void UponColumnWidthVarying     (wxCommandEvent&);
+    void UponColumnWidthFixed       (wxCommandEvent&);
+    void UponUpdateAlwaysDisabled   (wxUpdateUIEvent&);
+    void UponUpdateAlwaysEnabled    (wxUpdateUIEvent&);
+    void UponUpdateSingleSelection  (wxUpdateUIEvent&);
+    void UponUpdateColumnValuesVary (wxUpdateUIEvent&);
 
     bool DoAllCells(mcenum_emission);
 
-    virtual void Update() = 0;
+    void Update();
     void ViewOneCell(int);
     void ViewComposite();
 
@@ -119,7 +122,7 @@ class CensusView
         ,std::string const& title
         );
 
-    virtual int current_row() = 0;
+    int current_row();
 
     void update_class_names();
 
@@ -129,88 +132,10 @@ class CensusView
 
     std::shared_ptr<Ledger const> composite_ledger_;
 
-    DECLARE_EVENT_TABLE()
-};
-
-class CensusDVCView final
-    :public CensusView
-{
-    friend class CensusDVCDocument;
-    friend class CensusViewDataViewModel;
-
-  public:
-    CensusDVCView();
-
-  private:
-    CensusDVCView(CensusDVCView const&) = delete;
-    CensusDVCView& operator=(CensusDVCView const&) = delete;
-
-    void update_visible_columns() override;
-
-    // ViewEx required implementation.
-    wxWindow* CreateChildWindow() override;
-
-    // Event handlers, in event-table order (reflecting GUI order)
-    void UponRightClick             (wxDataViewEvent&);
-    void UponValueChanged           (wxDataViewEvent&);
-    void UponPasteCensus            (wxCommandEvent&) override;
-    void UponAddCell                (wxCommandEvent&) override;
-    void UponDeleteCells            (wxCommandEvent&) override;
-    void UponColumnWidthVarying     (wxCommandEvent&) override;
-    void UponColumnWidthFixed       (wxCommandEvent&) override;
-    void UponUpdateSingleSelection  (wxUpdateUIEvent&) override;
-    void UponUpdateNonemptySelection(wxUpdateUIEvent&);
-    void UponUpdateColumnValuesVary (wxUpdateUIEvent&) override;
-
-    void Update() override;
-
-    int current_row() override;
-
-    wxDataViewCtrl* list_window_;
-    wxObjectDataPtr<CensusViewDataViewModel> list_model_;
-
-    DECLARE_DYNAMIC_CLASS(CensusDVCView)
-    DECLARE_EVENT_TABLE()
-};
-
-class CensusGridView final
-    :public CensusView
-{
-    friend class CensusGridDocument;
-    friend class CensusViewGridTable;
-
-  public:
-    CensusGridView() = default;
-
-  private:
-    CensusGridView(CensusGridView const&) = delete;
-    CensusGridView& operator=(CensusGridView const&) = delete;
-
-    void update_visible_columns() override;
-
-    // ViewEx required implementation.
-    wxWindow* CreateChildWindow() override;
-
-    // Event handlers, in event-table order (reflecting GUI order)
-    void UponRightClick             (wxGridEvent&);
-    void UponValueChanged           (wxGridEvent&);
-    void UponColumnAutoSize         (wxGridSizeEvent&);
-    void UponPasteCensus            (wxCommandEvent&) override;
-    void UponAddCell                (wxCommandEvent&) override;
-    void UponDeleteCells            (wxCommandEvent&) override;
-    void UponColumnWidthVarying     (wxCommandEvent&) override;
-    void UponColumnWidthFixed       (wxCommandEvent&) override;
-    void UponUpdateSingleSelection  (wxUpdateUIEvent&) override;
-    void UponUpdateColumnValuesVary (wxUpdateUIEvent&) override;
-
-    void Update() override;
-
-    int current_row() override;
-
     wxGrid*              grid_window_ {nullptr};
     CensusViewGridTable* grid_table_  {nullptr};
 
-    DECLARE_DYNAMIC_CLASS(CensusGridView)
+    DECLARE_DYNAMIC_CLASS(CensusView)
     DECLARE_EVENT_TABLE()
 };
 
diff --git a/skeleton.cpp b/skeleton.cpp
index 74047fd..4686fb0 100644
--- a/skeleton.cpp
+++ b/skeleton.cpp
@@ -297,8 +297,6 @@ void Skeleton::InitDocManager()
     doc_manager_ = CreateDocManager();
     doc_manager_->FileHistoryLoad(*config_);
 
-    auto const use_grid =
-        contains(global_settings::instance().pyx(), "use_census_grid");
     new(wx) wxDocTemplate
         (doc_manager_
         ,"Census"
@@ -307,8 +305,8 @@ void Skeleton::InitDocManager()
         ,"cns"
         ,"Census document"
         ,"Census view"
-        ,use_grid ? CLASSINFO(CensusGridDocument) : 
CLASSINFO(CensusDVCDocument)
-        ,use_grid ? CLASSINFO(CensusGridView)     : CLASSINFO(CensusDVCView)
+        ,CLASSINFO(CensusDocument)
+        ,CLASSINFO(CensusView)
         );
 
     new(wx) wxDocTemplate
diff --git a/wx_test_paste_census.cpp b/wx_test_paste_census.cpp
index 8cb3f52..107ab4d 100644
--- a/wx_test_paste_census.cpp
+++ b/wx_test_paste_census.cpp
@@ -23,9 +23,7 @@
 
 #include "assert_lmi.hpp"
 #include "bourn_cast.hpp"
-#include "contains.hpp"
 #include "data_directory.hpp"
-#include "global_settings.hpp"
 #include "mvc_controller.hpp"
 #include "ssize_lmi.hpp"
 #include "wx_test_case.hpp"
@@ -34,7 +32,6 @@
 #include "wx_utility.hpp"
 
 #include <wx/app.h>
-#include <wx/dataview.h>
 #include <wx/dialog.h>
 #include <wx/grid.h>
 #include <wx/mdi.h>
@@ -51,12 +48,10 @@
 namespace
 {
 
-// wxDataViewCtrl functions.
-
-// Helper function to find the wxDataViewCtrl used for the census display.
+// Helper function to find the wxGrid used for the census display.
 //
 // Precondition: the currently active window must be a CensusView.
-wxDataViewCtrl* find_census_list_window()
+wxGrid* find_census_grid_window()
 {
     wxWindow* const top_window = wxTheApp->GetTopWindow();
     LMI_ASSERT(top_window);
@@ -72,25 +67,10 @@ wxDataViewCtrl* find_census_list_window()
     wxWindowList::const_iterator z = census_children.begin();
     LMI_ASSERT(z != census_children.end());
 
-    wxDataViewCtrl* const dvc = dynamic_cast<wxDataViewCtrl*>(*z);
-    LMI_ASSERT(dvc);
-
-    return dvc;
-}
-
-// Retrieve the list model from list window.
-//
-// Precondition: this wxDataViewCtrl must actually use a list model.
-wxDataViewListModel* get_census_list_model(wxDataViewCtrl* dvc)
-{
-    wxDataViewModel* const model = dvc->GetModel();
-    LMI_ASSERT(model);
-
-    wxDataViewListModel* const
-        list_model = dynamic_cast<wxDataViewListModel*>(model);
-    LMI_ASSERT(list_model);
+    wxGrid* const grid = dynamic_cast<wxGrid*>(*z);
+    LMI_ASSERT(grid);
 
-    return list_model;
+    return grid;
 }
 
 // Helper for building the diagnostic message.
@@ -122,86 +102,6 @@ std::string build_not_found_message(std::set<std::string> 
const& remaining)
 //
 // The 'when' parameter is used solely for the diagnostic messages in case of
 // the check failure.
-void check_list_columns
-    (wxDataViewCtrl* dvc
-    ,char const* when
-    ,std::set<std::string> const& expected
-    ,std::string const& unexpected = std::string()
-    )
-{
-    std::set<std::string> remaining(expected.begin(), expected.end());
-
-    for(int n = 0; n < bourn_cast<int>(dvc->GetColumnCount()); ++n)
-        {
-        std::string const title = dvc->GetColumn(n)->GetTitle().ToStdString();
-        LMI_ASSERT_WITH_MSG
-            (title != unexpected
-            ,"column '" << title << "' unexpectedly found " << when
-            );
-
-        // Notice that it is not an error if the column is not in the expected
-        // columns set, it is not exhaustive.
-        remaining.erase(title);
-        }
-
-    LMI_ASSERT_WITH_MSG
-        (remaining.empty()
-        ,build_not_found_message(remaining) << when
-        );
-}
-
-// Find the index of the column with the given title.
-//
-// Throws an exception if the column is not found.
-int find_model_column_by_title
-    (wxDataViewCtrl* dvc
-    ,std::string const& title
-    )
-{
-    for(int n = 0; n < bourn_cast<int>(dvc->GetColumnCount()); ++n)
-        {
-        wxDataViewColumn const* column = dvc->GetColumn(n);
-        if(column->GetTitle().ToStdString() == title)
-            {
-            return column->GetModelColumn();
-            }
-        }
-
-    throw std::runtime_error("column " + title + " not found");
-}
-
-// wxGrid functions.
-
-// Helper function to find the wxGrid used for the census display.
-//
-// Precondition: the currently active window must be a CensusView.
-wxGrid* find_census_grid_window()
-{
-    wxWindow* const top_window = wxTheApp->GetTopWindow();
-    LMI_ASSERT(top_window);
-
-    wxMDIParentFrame* const
-        parent_frame = dynamic_cast<wxMDIParentFrame*>(top_window);
-    LMI_ASSERT(parent_frame);
-
-    wxMDIChildFrame* const child_frame = parent_frame->GetActiveChild();
-    LMI_ASSERT(child_frame);
-
-    wxWindowList const& census_children = child_frame->GetChildren();
-    wxWindowList::const_iterator z = census_children.begin();
-    LMI_ASSERT(z != census_children.end());
-
-    wxGrid* const grid = dynamic_cast<wxGrid*>(*z);
-    LMI_ASSERT(grid);
-
-    return grid;
-}
-
-// Check for the presence of all columns with the given name and, if specified,
-// for the absence of the given one.
-//
-// The 'when' parameter is used solely for the diagnostic messages in case of
-// the check failure.
 void check_grid_columns
     (wxGrid* grid
     ,char const* when
@@ -332,9 +232,6 @@ LMI_WX_TEST_CASE(paste_census)
     // Put the data to paste on clipboard.
     ClipboardEx::SetText(census_data);
 
-    auto const use_grid =
-        contains(global_settings::instance().pyx(), "use_census_grid");
-
     // Create a new census.
     wx_test_new_census census;
 
@@ -343,70 +240,33 @@ LMI_WX_TEST_CASE(paste_census)
     ui.Char('s', wxMOD_CONTROL | wxMOD_SHIFT); // "Census | Paste census"
     wxYield();
 
-    wxGrid* grid_window = nullptr;
-    wxGridTableBase* table = nullptr;
-    wxDataViewCtrl* list_window = nullptr;
-    wxDataViewListModel* list_model = nullptr;
-
-    if (use_grid)
-        {
-        // Find the model containing the cells and check that it was filled in
-        // correctly.
-        grid_window = find_census_grid_window();
-        table = grid_window->GetTable();
-        LMI_ASSERT(table);
-        LMI_ASSERT_EQUAL(table->GetNumberRows(), number_of_rows);
-
-        check_grid_columns
-            (grid_window
-            ,"after pasting initial census data"
-            ,column_titles
-            );
-
-        // Change class defaults: this requires a selection, so ensure we have 
one
-        // by clicking somewhere inside the control.
-        ui.MouseMove
-            (grid_window->ClientToScreen
-                (wxPoint
-                    (10 * grid_window->GetCharWidth()
-                    , 3 * grid_window->GetCharHeight()
-                    )
-                )
-            );
-        ui.MouseClick();
-        wxYield();
-
-        LMI_ASSERT_EQUAL(lmi::ssize(grid_window->GetSelectedRows()), 1);
-        }
-    else
-        {
-        // Find the model containing the cells and check that it was filled in
-        // correctly.
-        list_window = find_census_list_window();
-        list_model = get_census_list_model(list_window);
-        LMI_ASSERT_EQUAL(bourn_cast<int>(list_model->GetCount()), 
number_of_rows);
-
-        check_list_columns
-            (list_window
-            ,"after pasting initial census data"
-            ,column_titles
-            );
+    // Find the model containing the cells and check that it was filled in
+    // correctly.
+    wxGrid* const grid_window = find_census_grid_window();
+    wxGridTableBase* const table = grid_window->GetTable();
+    LMI_ASSERT(table);
+    LMI_ASSERT_EQUAL(table->GetNumberRows(), number_of_rows);
+
+    check_grid_columns
+        (grid_window
+        ,"after pasting initial census data"
+        ,column_titles
+        );
 
-        // Change class defaults: this requires a selection, so ensure we have 
one
-        // by clicking somewhere inside the control.
-        ui.MouseMove
-            (list_window->ClientToScreen
-                (wxPoint
-                    (10 * list_window->GetCharWidth()
-                    , 3 * list_window->GetCharHeight()
-                    )
+    // Change class defaults: this requires a selection, so ensure we have one
+    // by clicking somewhere inside the control.
+    ui.MouseMove
+        (grid_window->ClientToScreen
+            (wxPoint
+                (10 * grid_window->GetCharWidth()
+                , 3 * grid_window->GetCharHeight()
                 )
-            );
-        ui.MouseClick();
-        wxYield();
+            )
+        );
+    ui.MouseClick();
+    wxYield();
 
-        LMI_ASSERT_EQUAL(list_window->GetSelectedItemsCount(), 1);
-        }
+    LMI_ASSERT_EQUAL(lmi::ssize(grid_window->GetSelectedRows()), 1);
 
     ui.Char('e', wxMOD_CONTROL | wxMOD_ALT); // "Census|Edit class defaults"
 
@@ -460,45 +320,21 @@ LMI_WX_TEST_CASE(paste_census)
             Describe("message box asking whether to apply gender changes to 
all")
         );
 
-    if (use_grid)
-        {
-        // Check that all columns, including the "Gender" one, are still shown.
-        check_grid_columns
-            (grid_window
-            ,"after changing gender in class defaults"
-            ,column_titles
-            );
+    // Check that all columns, including the "Gender" one, are still shown.
+    check_grid_columns
+        (grid_window
+        ,"after changing gender in class defaults"
+        ,column_titles
+        );
 
-        // Verify that the "Gender" column value is "Unisex" in every row now.
-        int const gender_column = find_table_column_by_title(grid_window, 
"Gender");
-        LMI_ASSERT_EQUAL(table->GetNumberRows(), number_of_rows);
-        // Only the first two rows are affected, because only they belong
-        // to the first employee class.
-        for(int row = 0; row < 2; ++row)
-            {
-            LMI_ASSERT_EQUAL(table->GetValue(row, gender_column), "Unisex");
-            }
-        }
-    else
+    // Verify that the "Gender" column value is "Unisex" in every row now.
+    int const gender_column = find_table_column_by_title(grid_window, 
"Gender");
+    LMI_ASSERT_EQUAL(table->GetNumberRows(), number_of_rows);
+    // Only the first two rows are affected, because only they belong
+    // to the first employee class.
+    for(int row = 0; row < 2; ++row)
         {
-        // Check that all columns, including the "Gender" one, are still shown.
-        check_list_columns
-            (list_window
-            ,"after changing gender in class defaults"
-            ,column_titles
-            );
-
-        // Verify that the "Gender" column value is "Unisex" in every row now.
-        int const gender_column = find_model_column_by_title(list_window, 
"Gender");
-        LMI_ASSERT_EQUAL(bourn_cast<int>(list_model->GetCount()), 
number_of_rows);
-        // Only the first two rows are affected, because only they belong
-        // to the first employee class.
-        for(int row = 0; row < 2; ++row)
-            {
-            wxVariant value;
-            list_model->GetValueByRow(value, row, gender_column);
-            LMI_ASSERT_EQUAL(value.GetString(), "Unisex");
-            }
+        LMI_ASSERT_EQUAL(table->GetValue(row, gender_column), "Unisex");
         }
 
     // Change the case defaults to get rid of the underwriting class.
@@ -550,34 +386,17 @@ LMI_WX_TEST_CASE(paste_census)
             Describe("message box asking whether to apply class changes to 
all")
         );
 
-    if (use_grid)
-        {
-        // Check that we still have the same cells but that now the 
underwriting
-        // class column has disappeared as its value has been fixed.
-        LMI_ASSERT_EQUAL(table->GetNumberRows(), number_of_rows);
-
-        column_titles.erase("Underwriting Class");
-        check_grid_columns
-            (grid_window
-            ,"after changing class in case defaults"
-            ,column_titles
-            ,"Underwriting Class"
-            );
-        }
-    else
-        {
-        // Check that we still have the same cells but that now the 
underwriting
-        // class column has disappeared as its value has been fixed.
-        LMI_ASSERT_EQUAL(bourn_cast<int>(list_model->GetCount()), 
number_of_rows);
-
-        column_titles.erase("Underwriting Class");
-        check_list_columns
-            (list_window
-            ,"after changing class in case defaults"
-            ,column_titles
-            ,"Underwriting Class"
-            );
-        }
+    // Check that we still have the same cells but that now the underwriting
+    // class column has disappeared as its value has been fixed.
+    LMI_ASSERT_EQUAL(table->GetNumberRows(), number_of_rows);
+
+    column_titles.erase("Underwriting Class");
+    check_grid_columns
+        (grid_window
+        ,"after changing class in case defaults"
+        ,column_titles
+        ,"Underwriting Class"
+        );
 
     // Finally save the census with the pasted data for later inspection.
     std::string const census_file_name = 
get_test_file_path_for("PasteCensus.cns");
diff --git a/wx_test_validate_output.cpp b/wx_test_validate_output.cpp
index 62277ac..c527848 100644
--- a/wx_test_validate_output.cpp
+++ b/wx_test_validate_output.cpp
@@ -23,7 +23,6 @@
 
 #include "assert_lmi.hpp"
 #include "configurable_settings.hpp"
-#include "contains.hpp"
 #include "mvc_controller.hpp"
 #include "path_utility.hpp"
 #include "wx_test_case.hpp"
@@ -345,21 +344,11 @@ void validate_run_cell_and_copy_output
 
     wxUIActionSimulator ui;
 
-    auto const use_grid =
-        contains(global_settings::instance().pyx(), "use_census_grid");
+    ui.Char(WXK_UP);                  // Clear the current selection if any.
+    ui.Char(WXK_HOME, wxMOD_CONTROL); // Go to the left top cell.
+    ui.Char(WXK_RIGHT, wxMOD_SHIFT);  // Select the first row.
 
-    if(use_grid)
-        {
-        ui.Char(WXK_UP);                  // Clear the current selection if 
any.
-        ui.Char(WXK_HOME, wxMOD_CONTROL); // Go to the left top cell.
-        ui.Char(WXK_RIGHT, wxMOD_SHIFT);  // Select the first row.
-        }
-    else
-        {
-        ui.Char(WXK_HOME);               // Select the first cell.
-        }
-
-    ui.Char('r', wxMOD_CONTROL);         // "Census|Run cell"
+    ui.Char('r', wxMOD_CONTROL);      // "Census|Run cell"
     wxYield();
 
     LMI_ASSERT_WITH_MSG



reply via email to

[Prev in Thread] Current Thread [Next in Thread]