lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [5304] Temporarily revert wxDVC census manager


From: Greg Chicares
Subject: [lmi-commits] [5304] Temporarily revert wxDVC census manager
Date: Wed, 26 Oct 2011 13:42:27 +0000

Revision: 5304
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5304
Author:   chicares
Date:     2011-10-26 13:42:26 +0000 (Wed, 26 Oct 2011)
Log Message:
-----------
Temporarily revert wxDVC census manager

Modified Paths:
--------------
    lmi/trunk/ChangeLog
    lmi/trunk/census_document.cpp
    lmi/trunk/census_document.hpp
    lmi/trunk/census_view.cpp
    lmi/trunk/census_view.hpp

Modified: lmi/trunk/ChangeLog
===================================================================
--- lmi/trunk/ChangeLog 2011-10-25 15:09:08 UTC (rev 5303)
+++ lmi/trunk/ChangeLog 2011-10-26 13:42:26 UTC (rev 5304)
@@ -28611,3 +28611,12 @@
   skin_coli_coli.xrc
 Improve consistency.
 
+20111026T1342Z <address@hidden> [625]
+
+  census_document.cpp
+  census_document.hpp
+  census_view.cpp
+  census_view.hpp
+Temporarily revert wxDVC census manager, in order to release only the
+input-sequence editor this month.
+

Modified: lmi/trunk/census_document.cpp
===================================================================
--- lmi/trunk/census_document.cpp       2011-10-25 15:09:08 UTC (rev 5303)
+++ lmi/trunk/census_document.cpp       2011-10-26 13:42:26 UTC (rev 5304)
@@ -49,9 +49,9 @@
 {
 }
 
-wxDataViewCtrl& CensusDocument::PredominantViewWindow() const
+wxListView& CensusDocument::PredominantViewWindow() const
 {
-    return ::PredominantViewWindow<CensusView,wxDataViewCtrl>
+    return ::PredominantViewWindow<CensusView,wxListView>
         (*this
         ,&CensusView::list_window_
         );

Modified: lmi/trunk/census_document.hpp
===================================================================
--- lmi/trunk/census_document.hpp       2011-10-25 15:09:08 UTC (rev 5303)
+++ lmi/trunk/census_document.hpp       2011-10-26 13:42:26 UTC (rev 5304)
@@ -32,7 +32,7 @@
 
 #include <wx/docview.h>
 
-class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
+class WXDLLIMPEXP_FWD_CORE wxListView;
 
 class CensusDocument
     :public  wxDocument
@@ -45,7 +45,7 @@
     virtual ~CensusDocument();
 
   private:
-    wxDataViewCtrl& PredominantViewWindow() const;
+    wxListView& PredominantViewWindow() const;
 
     // wxDocument overrides.
     virtual bool OnCreate(wxString const& filename, long int flags);

Modified: lmi/trunk/census_view.cpp
===================================================================
--- lmi/trunk/census_view.cpp   2011-10-25 15:09:08 UTC (rev 5303)
+++ lmi/trunk/census_view.cpp   2011-10-26 13:42:26 UTC (rev 5304)
@@ -34,25 +34,22 @@
 #include "configurable_settings.hpp"
 #include "contains.hpp"
 #include "default_view.hpp"
-#include "edit_mvc_docview_parameters.hpp"
 #include "illustration_view.hpp"
 #include "illustrator.hpp"
 #include "input.hpp"
-#include "input_sequence_entry.hpp"
 #include "ledger.hpp"
 #include "ledger_text_formats.hpp"
 #include "miscellany.hpp" // is_ok_for_cctype()
+#include "mvc_controller.hpp"
 #include "path_utility.hpp"
 #include "safely_dereference_as.hpp"
 #include "wx_new.hpp"
 #include "wx_utility.hpp" // class ClipboardEx
 
-#include <wx/dataview.h>
-#include <wx/datectrl.h>
 #include <wx/icon.h>
+#include <wx/listctrl.h>
 #include <wx/menu.h>
 #include <wx/msgdlg.h>
-#include <wx/spinctrl.h>
 #include <wx/xrc/xmlres.h>
 #include <wx/wupdlock.h>
 
@@ -68,735 +65,29 @@
 
 namespace
 {
-// TODO ?? Add description and unit tests; consider relocating,
-// and include "miscellany.hpp" only in ultimate location.
-std::string insert_spaces_between_words(std::string const& s)
-{
-    std::string r;
-    std::insert_iterator<std::string> j(r, r.begin());
-    std::string::const_iterator i;
-    for(i = s.begin(); i != s.end(); ++i)
-        {
-        if(is_ok_for_cctype(*i) && std::isupper(*i) && !r.empty())
+    // TODO ?? Add description and unit tests; consider relocating,
+    // and include "miscellany.hpp" only in ultimate location.
+    std::string insert_spaces_between_words(std::string const& s)
+    {
+        std::string r;
+        std::insert_iterator<std::string> j(r, r.begin());
+        std::string::const_iterator i;
+        for(i = s.begin(); i != s.end(); ++i)
             {
-            *j++ = ' ';
+            if(is_ok_for_cctype(*i) && std::isupper(*i) && !r.empty())
+                {
+                *j++ = ' ';
+                }
+            *j++ = *i;
             }
-        *j++ = *i;
-        }
-    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& value_, double min_, double max_)
-        :value(value_), min(min_), max(max_)
-    {
+        return r;
     }
-
-    tn_range_variant_data(tn_range_base const& r)
-        :value(r.str()), min(r.universal_minimum()), max(r.universal_maximum())
-    {
-    }
-
-    virtual bool Eq(wxVariantData& data) const
-    {
-        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;
-    }
-
-    virtual wxString GetType() const { return 
typeid(tn_range_variant_data).name(); }
-
-    virtual wxVariantData* Clone() const
-    {
-        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:
-    virtual bool HasEditorCtrl() const { return true; }
-    virtual wxWindow* CreateEditorCtrl(wxWindow* parent, wxRect labelRect, 
wxVariant const& value);
-    virtual bool GetValueFromEditorCtrl(wxWindow* editor, wxVariant& value);
-    virtual bool Render(wxRect rect, wxDC* dc, int state);
-    virtual wxSize GetSize() const;
-    virtual bool SetValue(wxVariant const& value);
-    virtual bool GetValue(wxVariant& value) const;
-
-  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 m_value;
-    double m_min, m_max;
-};
-
-RangeTypeRenderer::RangeTypeRenderer()
-    :wxDataViewCustomRenderer
-    (typeid(tn_range_variant_data).name()
-    ,wxDATAVIEW_CELL_EDITABLE
-    ,wxDVR_DEFAULT_ALIGNMENT)
-{
 }
 
-wxWindow* RangeTypeRenderer::CreateEditorCtrl(wxWindow* parent, wxRect 
labelRect, 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(labelRect);
-    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, m_min, m_max);
-    return true;
-}
-
-bool RangeTypeRenderer::Render(wxRect rect, wxDC* dc, int state)
-{
-    RenderText(m_value, 0, rect, dc, state);
-    return true;
-}
-
-wxSize RangeTypeRenderer::GetSize() const
-{
-    wxSize sz = GetTextExtent(m_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);
-
-    m_value = data->value;
-    m_min = data->min;
-    m_max = data->max;
-    return true;
-}
-
-bool RangeTypeRenderer::GetValue(wxVariant& value) const
-{
-    value = new(wx) tn_range_variant_data(m_value, m_min, m_max);
-    return true;
-}
-
-// class IntSpinRenderer
-
-class IntSpinRenderer
-    :public RangeTypeRenderer
-{
-  public:
-    IntSpinRenderer() : RangeTypeRenderer() {}
-
-  protected:
-    virtual wxWindow* DoCreateEditor(wxWindow* parent, wxRect const& rect, 
tn_range_variant_data const& data);
-    virtual std::string DoGetValueFromEditor(wxWindow* editor);
-};
-
-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
-        ,static_cast<long>(data.min)
-        ,static_cast<long>(data.max)
-        ,value_cast<long>(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 DoubleSpinRenderer
-
-class DoubleSpinRenderer
-    :public RangeTypeRenderer
-{
-  public:
-    DoubleSpinRenderer() : RangeTypeRenderer() {}
-
-  protected:
-    virtual wxWindow* DoCreateEditor(wxWindow* parent, wxRect const& rect, 
tn_range_variant_data const& data);
-    virtual std::string DoGetValueFromEditor(wxWindow* editor);
-};
-
-wxWindow* DoubleSpinRenderer::DoCreateEditor
-    (wxWindow* parent
-     ,wxRect const& rect
-     ,tn_range_variant_data const& data)
-{
-    return new(wx) wxSpinCtrlDouble
-        (parent
-        ,wxID_ANY
-        ,data.value
-        ,rect.GetTopLeft()
-        ,rect.GetSize()
-        ,wxSP_ARROW_KEYS | wxTE_PROCESS_ENTER
-        ,data.min
-        ,data.max
-        ,value_cast<double>(data.value));
-}
-
-std::string DoubleSpinRenderer::DoGetValueFromEditor(wxWindow* editor)
-{
-    wxSpinCtrlDouble* spin = dynamic_cast<wxSpinCtrlDouble*>(editor);
-    LMI_ASSERT(spin);
-
-    return value_cast<std::string>(spin->GetValue());
-}
-
-// class DateRenderer
-
-class DateRenderer
-    :public RangeTypeRenderer
-{
-  public:
-    DateRenderer() : RangeTypeRenderer() {}
-    virtual bool Render(wxRect rect, wxDC* dc, int state);
-
-  protected:
-    virtual wxWindow* DoCreateEditor(wxWindow* parent, wxRect const& rect, 
tn_range_variant_data const& data);
-    virtual std::string DoGetValueFromEditor(wxWindow* editor);
-};
-
-wxWindow* DateRenderer::DoCreateEditor
-    (wxWindow* parent
-     ,wxRect const& rect
-     ,tn_range_variant_data const& data)
-{
-    wxDatePickerCtrl* ctrl = new(wx) wxDatePickerCtrl
-        (parent
-        ,wxID_ANY
-        ,ConvertDateToWx(value_cast<calendar_date>(data.value))
-        ,rect.GetTopLeft()
-        ,rect.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>(m_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& value_, Input const* 
input_, std::string const& field_)
-        :value(value_), input(input_), field(field_)
-    {
-    }
-
-    virtual bool Eq(wxVariantData& data) const
-    {
-        input_sequence_variant_data* d = 
dynamic_cast<input_sequence_variant_data*>(&data);
-        if(!d)
-            return false;
-        return value == d->value;
-    }
-
-    virtual wxString GetType() const { return 
typeid(input_sequence_variant_data).name(); }
-
-    virtual wxVariantData* Clone() const
-    {
-        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();
-    virtual bool HasEditorCtrl() const { return true; }
-    virtual wxWindow* CreateEditorCtrl(wxWindow* parent, wxRect labelRect, 
wxVariant const& value);
-    virtual bool GetValueFromEditorCtrl(wxWindow* editor, wxVariant& value);
-    virtual bool Render(wxRect rect, wxDC* dc, int state);
-    virtual wxSize GetSize() const;
-    virtual bool SetValue(wxVariant const& value);
-    virtual bool GetValue(wxVariant& value) const;
-
-    std::string  m_value;
-    Input const* m_input;
-    std::string  m_field;
-};
-
-DatumSequenceRenderer::DatumSequenceRenderer()
-    :wxDataViewCustomRenderer(typeid(input_sequence_variant_data).name(), 
wxDATAVIEW_CELL_EDITABLE, wxDVR_DEFAULT_ALIGNMENT)
-    ,m_input(0)
-{
-}
-
-wxWindow* DatumSequenceRenderer::CreateEditorCtrl(wxWindow* parent, wxRect 
labelRect, 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);
-
-    // Always use default height for editor controls
-    wxRect rect(labelRect);
-    rect.height = -1;
-
-    ctrl->SetSize(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(m_value, 0, rect, dc, state);
-    return true;
-}
-
-wxSize DatumSequenceRenderer::GetSize() const
-{
-    wxSize sz = GetTextExtent(m_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);
-
-    m_value = data->value;
-    m_input = data->input;
-    m_field = data->field;
-    return true;
-}
-
-bool DatumSequenceRenderer::GetValue(wxVariant& value) const
-{
-    value = new(wx) input_sequence_variant_data(m_value, m_input, m_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_convertor
-{
-  public:
-    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& 
representative_value) const = 0;
-
-    static renderer_type_convertor const& get(any_member<Input> const& value);
-
-  private:
-    template<typename T>
-    static renderer_type_convertor const& get_impl();
-};
-
-// class renderer_bool_convertor
-
-class renderer_bool_convertor : public renderer_type_convertor
-{
-    virtual wxVariant to_variant(any_member<Input> const& x, Input const&, 
std::string const&) const
-    {
-        std::string const s(x.str());
-        return
-              "Yes" == s ? true
-            : "No"  == s ? false
-            : throw "Invalid boolean value."
-            ;
-    }
-
-    virtual std::string from_variant(wxVariant const& x) const
-    {
-        return x.GetBool() ? "Yes" : "No";
-    }
-
-    virtual char const* variant_type() const
-    {
-        return "bool";
-    }
-
-    virtual wxDataViewRenderer* create_renderer(any_member<Input> const&) const
-    {
-        return new(wx) wxDataViewToggleRenderer("bool", 
wxDATAVIEW_CELL_ACTIVATABLE, wxALIGN_CENTER);
-    }
-};
-
-// class renderer_enum_convertor
-
-class renderer_enum_convertor : public renderer_type_convertor
-{
-    virtual wxVariant to_variant(any_member<Input> const& x, Input const&, 
std::string const&) const
-    {
-        return wxString(x.str());
-    }
-
-    virtual std::string from_variant(wxVariant const& x) const
-    {
-        return x.GetString().ToStdString();
-    }
-
-    virtual char const* variant_type() const
-    {
-        return "string";
-    }
-
-    virtual wxDataViewRenderer* create_renderer(any_member<Input> const& 
representative_value) const
-    {
-        mc_enum_base const* as_enum = 
member_cast<mc_enum_base>(representative_value);
-
-        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_convertor
-
-class renderer_sequence_convertor : public renderer_type_convertor
-{
-  public:
-    virtual wxVariant to_variant(any_member<Input> const& x, Input const& row, 
std::string const& col) const
-    {
-        return new(wx) input_sequence_variant_data(x.str(), &row, col);
-    }
-
-    virtual std::string from_variant(wxVariant const& x) const
-    {
-        input_sequence_variant_data const* data = 
dynamic_cast<input_sequence_variant_data*>(x.GetData());
-        LMI_ASSERT(data);
-        return data->value;
-    }
-
-    virtual char const* variant_type() const
-    {
-        return typeid(input_sequence_variant_data).name();
-    }
-
-    virtual wxDataViewRenderer* create_renderer(any_member<Input> const&) const
-    {
-        return new(wx) DatumSequenceRenderer();
-    }
-};
-
-// class renderer_range_convertor
-
-class renderer_range_convertor : public renderer_type_convertor
-{
-  public:
-    virtual wxVariant to_variant(any_member<Input> const& x, Input const&, 
std::string const&) const
-    {
-        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);
-    }
-
-    virtual std::string from_variant(wxVariant const& x) const
-    {
-        tn_range_variant_data const* data = 
dynamic_cast<tn_range_variant_data*>(x.GetData());
-        LMI_ASSERT(data);
-        return data->value;
-    }
-
-    virtual char const* variant_type() const
-    {
-        return typeid(tn_range_variant_data).name();
-    }
-};
-
-class renderer_int_range_convertor : public renderer_range_convertor
-{
-  public:
-    virtual wxDataViewRenderer* create_renderer(any_member<Input> const&) const
-    {
-        return new(wx) IntSpinRenderer();
-    }
-};
-
-class renderer_double_range_convertor : public renderer_range_convertor
-{
-  public:
-    virtual wxDataViewRenderer* create_renderer(any_member<Input> const&) const
-    {
-        return new(wx) DoubleSpinRenderer();
-    }
-};
-
-class renderer_date_convertor : public renderer_range_convertor
-{
-  public:
-    virtual wxDataViewRenderer* create_renderer(any_member<Input> const&) const
-    {
-        return new(wx) DateRenderer();
-    }
-};
-
-// class renderer_fallback_convertor
-
-class renderer_fallback_convertor : public renderer_type_convertor
-{
-  public:
-    virtual wxVariant to_variant(any_member<Input> const& x, Input const&, 
std::string const&) const
-    {
-        return wxString(x.str());
-    }
-
-    virtual std::string from_variant(wxVariant const& x) const
-    {
-        return x.GetString().ToStdString();
-    }
-
-    virtual char const* variant_type() const
-    {
-        return "string";
-    }
-
-    virtual wxDataViewRenderer* create_renderer(any_member<Input> const&) const
-    {
-        return new(wx) wxDataViewTextRenderer("string", 
wxDATAVIEW_CELL_EDITABLE);
-    }
-};
-
-renderer_type_convertor const& renderer_type_convertor::get(any_member<Input> 
const& value)
-{
-    mc_enum_base const* as_enum = NULL;
-    datum_sequence const* as_sequence = NULL;
-    tn_range_base const* as_range = NULL;
-
-    any_member<Input>& nonconst_value = const_cast<any_member<Input>&>(value);
-
-    if(typeid(mce_yes_or_no Input::*) == value.type())
-        {
-        return get_impl<renderer_bool_convertor>();
-        }
-    else if(0 != reconstitutor<mc_enum_base  
,Input>::reconstitute(nonconst_value))
-        {
-        as_enum = member_cast<mc_enum_base>(value);
-        return get_impl<renderer_enum_convertor>();
-        }
-    else if(0 != 
reconstitutor<datum_sequence,Input>::reconstitute(nonconst_value))
-        {
-        as_sequence = member_cast<datum_sequence>(value);
-        return get_impl<renderer_sequence_convertor>();
-        }
-    else if(0 != reconstitutor<tn_range_base 
,Input>::reconstitute(nonconst_value))
-        {
-        as_range = member_cast<tn_range_base>(value);
-        if(typeid(int) == as_range->value_type())
-            return get_impl<renderer_int_range_convertor>();
-        else if(typeid(double) == as_range->value_type())
-            return get_impl<renderer_double_range_convertor>();
-        else if(typeid(calendar_date) == as_range->value_type())
-            return get_impl<renderer_date_convertor>();
-        // else: fall through
-        }
-
-    return get_impl<renderer_fallback_convertor>();
-}
-
-template<typename T>
-renderer_type_convertor const& renderer_type_convertor::get_impl()
-{
-    static const T singleton;
-    return singleton;
-}
-
-} // Unnamed namespace.
-
-/// Interface to the data for wxDataViewCtrl.
-
-class CensusViewDataViewModel : public wxDataViewIndexListModel
-{
-  public:
-    static unsigned int const Col_CellNum = 0;
-
-    CensusViewDataViewModel(CensusView& view)
-        :view_(view)
-    {
-    }
-
-    virtual void GetValueByRow(wxVariant& variant, unsigned int row, unsigned 
int col) const;
-    virtual bool SetValueByRow(wxVariant const&, unsigned int, unsigned int);
-
-    virtual unsigned int GetColumnCount() const;
-
-    virtual wxString GetColumnType(unsigned int col) const;
-
-    std::string const& col_name(unsigned col) const;
-    any_member<Input>& cell_at(unsigned row, unsigned col);
-    any_member<Input> const& cell_at(unsigned row, unsigned col) const;
-
-  private:
-    std::vector<std::string> const& all_headers() const;
-
-    CensusView& view_;
-};
-
-void CensusViewDataViewModel::GetValueByRow(wxVariant& variant, unsigned row, 
unsigned col) const
-{
-    if(col == Col_CellNum)
-        {
-        variant = static_cast<long>(1 + row);
-        }
-    else
-        {
-        any_member<Input> const& cell = cell_at(row, col);
-        renderer_type_convertor const& conv = 
renderer_type_convertor::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 
row, unsigned col)
-{
-    LMI_ASSERT(col != Col_CellNum);
-
-    any_member<Input>& cell = cell_at(row, col);
-    renderer_type_convertor const& conv = renderer_type_convertor::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;
-
-    view_.document().Modify(true);
-
-    return true;
-}
-
-unsigned int CensusViewDataViewModel::GetColumnCount() const
-{
-    return all_headers().size() + 1;
-}
-
-wxString CensusViewDataViewModel::GetColumnType(unsigned int col) const
-{
-    if(col == Col_CellNum)
-        {
-        return "long";
-        }
-    else
-        {
-        any_member<Input> const& representative_value = cell_at(0, col);
-        renderer_type_convertor const& conv = 
renderer_type_convertor::get(representative_value);
-
-        return conv.variant_type();
-        }
-}
-
-std::string const& CensusViewDataViewModel::col_name(unsigned col) const
-{
-    LMI_ASSERT(col > 0);
-    return all_headers()[col - 1];
-}
-
-inline any_member<Input>& CensusViewDataViewModel::cell_at(unsigned row, 
unsigned col)
-{
-    return view_.cell_parms()[row][col_name(col)];
-}
-
-inline any_member<Input> const& CensusViewDataViewModel::cell_at(unsigned row, 
unsigned 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();
-}
-
-// class CensusView
-
 IMPLEMENT_DYNAMIC_CLASS(CensusView, ViewEx)
 
 BEGIN_EVENT_TABLE(CensusView, ViewEx)
-    EVT_DATAVIEW_ITEM_CONTEXT_MENU(ID_LISTWINDOW, CensusView::UponRightClick)
+    EVT_CONTEXT_MENU(                        CensusView::UponRightClick)
     EVT_MENU(XRCID("edit_cell"             ),CensusView::UponEditCell )
     EVT_MENU(XRCID("edit_class"            ),CensusView::UponEditClass)
     EVT_MENU(XRCID("edit_case"             ),CensusView::UponEditCase )
@@ -812,33 +103,40 @@
     EVT_MENU(XRCID("column_width_varying"  
),CensusView::UponColumnWidthVarying)
     EVT_MENU(XRCID("column_width_fixed"    ),CensusView::UponColumnWidthFixed)
 
-    EVT_UPDATE_UI(XRCID("edit_cell"            
),CensusView::UponUpdateSingleSelection)
-    EVT_UPDATE_UI(XRCID("edit_class"           
),CensusView::UponUpdateSingleSelection)
-    EVT_UPDATE_UI(XRCID("edit_case"            
),CensusView::UponUpdateAlwaysEnabled)
-    EVT_UPDATE_UI(XRCID("run_cell"             
),CensusView::UponUpdateSingleSelection)
-    EVT_UPDATE_UI(XRCID("run_class"            
),CensusView::UponUpdateSingleSelection)
-    EVT_UPDATE_UI(XRCID("run_case"             
),CensusView::UponUpdateAlwaysEnabled)
-    EVT_UPDATE_UI(XRCID("print_case"           
),CensusView::UponUpdateAlwaysEnabled)
-    EVT_UPDATE_UI(XRCID("print_case_to_disk"   
),CensusView::UponUpdateAlwaysEnabled)
-    EVT_UPDATE_UI(XRCID("print_spreadsheet"    
),CensusView::UponUpdateAlwaysEnabled)
-    EVT_UPDATE_UI(XRCID("paste_census"         
),CensusView::UponUpdateAlwaysEnabled)
-    EVT_UPDATE_UI(XRCID("add_cell"             
),CensusView::UponUpdateAlwaysEnabled)
-    EVT_UPDATE_UI(XRCID("delete_cells"         
),CensusView::UponUpdateNonemptySelection)
-    EVT_UPDATE_UI(XRCID("column_width_varying" 
),CensusView::UponUpdateAlwaysEnabled)
-    EVT_UPDATE_UI(XRCID("column_width_fixed"   
),CensusView::UponUpdateAlwaysEnabled)
+// TODO ?? There has to be a better way than this.
+    EVT_UPDATE_UI(XRCID("edit_cell"            
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("edit_class"           
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("edit_case"            
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("run_cell"             
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("run_class"            
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("run_case"             
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("print_case"           
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("print_case_to_disk"   
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("print_spreadsheet"    
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("paste_census"         
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("add_cell"             
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("delete_cells"         
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("column_width_varying" 
),CensusView::UponUpdateApplicable)
+    EVT_UPDATE_UI(XRCID("column_width_fixed"   
),CensusView::UponUpdateApplicable)
+// TODO ?? Not label-edit.
+//    EVT_LIST_BEGIN_LABEL_EDIT(ID_LISTWINDOW,CensusView::UponBeginLabelEdit)
+// Don't do this either--it's triggered by spacebar.
+//    EVT_LIST_ITEM_ACTIVATED(ID_LISTWINDOW  ,CensusView::UponBeginLabelEdit)
 END_EVENT_TABLE()
 
 CensusView::CensusView()
     :ViewEx                          ()
     ,all_changes_have_been_validated_(true)
-    ,autosize_columns_               (false)
     ,composite_is_available_         (false)
     ,was_cancelled_                  (false)
     ,list_window_                    (0)
-    ,list_model_                     (new(wx) CensusViewDataViewModel(*this))
 {
 }
 
+CensusView::~CensusView()
+{
+}
+
 inline std::vector<Input>& CensusView::case_parms()
 {
     return document().doc_.case_parms_;
@@ -869,6 +167,7 @@
     return document().doc_.class_parms_;
 }
 
+// TODO ?? Is this abstraction actually useful?
 std::string CensusView::cell_title(int index)
 {
     std::string full_name(cell_parms()[index]["InsuredName"].str());
@@ -881,6 +180,7 @@
     return title.str();
 }
 
+// TODO ?? Is this abstraction actually useful?
 std::string CensusView::class_title(int index)
 {
     std::string class_name = class_name_from_cell_number(index);
@@ -898,6 +198,7 @@
     return title.str();
 }
 
+// TODO ?? Is this abstraction actually useful?
 std::string CensusView::class_name_from_cell_number(int cell_number) const
 {
     return cell_parms()[cell_number]["EmployeeClass"].str();
@@ -918,10 +219,9 @@
     return 0;
 }
 
-/// Determine which columns need to be displayed because their rows
-/// would not all be identical--i.e. because at least one cell or one
-/// class default differs from the case default wrt that column.
-
+    // Determine which columns need to be displayed because their rows
+    // would not all be identical--i.e. because at least one cell or one
+    // class default differs from the case default wrt that column.
 bool CensusView::column_value_varies_across_cells
     (std::string        const& header
     ,std::vector<Input> const& cells
@@ -940,28 +240,15 @@
 
 wxWindow* CensusView::CreateChildWindow()
 {
-    list_window_ = new(wx) wxDataViewCtrl
+    list_window_ = new(wx) wxListView
         (GetFrame()
         ,ID_LISTWINDOW
-        ,wxDefaultPosition
-        ,wxDefaultSize
-        ,wxDV_ROW_LINES | wxDV_MULTIPLE
         );
 
-    // Use same row height as used by wxListCtrl without icons. By default,
-    // wxDataViewCtrl uses slightly larger spacing, but we prefer to fit more
-    // on the screen over slightly improved readability.
-    list_window_->SetRowHeight(list_window_->GetCharHeight() + 1);
-
-    list_window_->AssociateModel(list_model_.get());
-
     // Show headers.
-    document().Modify(false);
-    list_model_->Reset(cell_parms().size());
     Update();
+    document().Modify(false);
 
-    list_window_->Select(list_model_->GetItem(0));
-
     status() << std::flush;
 
     return list_window_;
@@ -972,22 +259,60 @@
     return safely_dereference_as<CensusDocument>(GetDocument());
 }
 
-oenum_mvc_dv_rc CensusView::edit_parameters
-    (Input&             parameters
-    ,std::string const& title
+    // 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.
+//
+// Only DisplayAllVaryingData() uses the data member this assigns,
+// so move the logic into that function (if that remains true).
+//
+void CensusView::identify_varying_columns()
+{
+    headers_of_varying_parameters_.clear();
+    std::vector<std::string> const& 
all_headers(case_parms()[0].member_names());
+    std::vector<std::string>::const_iterator i;
+    for(i = all_headers.begin(); i != all_headers.end(); ++i)
+        {
+        if
+            (  column_value_varies_across_cells(*i, class_parms())
+            || column_value_varies_across_cells(*i, cell_parms ())
+            )
+            {
+            headers_of_varying_parameters_.push_back(*i);
+            }
+        }
+}
+
+int CensusView::edit_parameters
+    (Input&             lmi_input
+    ,std::string const& name
     )
 {
     if(is_invalid())
         {
-        return oe_mvc_dv_cancelled;
+        return false;
         }
 
-    return edit_mvc_docview_parameters<DefaultView>
-        (parameters
-        ,document()
-        ,GetFrame()
-        ,title
-        );
+    bool dirty = document().IsModified();
+
+    Input edited_lmi_input = lmi_input;
+    DefaultView const default_view;
+    MvcController controller(GetFrame(), edited_lmi_input, default_view);
+    controller.SetTitle(name);
+    int rc = controller.ShowModal();
+    if(wxID_OK == rc)
+        {
+        if(lmi_input != edited_lmi_input)
+            {
+            lmi_input = edited_lmi_input;
+            dirty = true;
+            }
+        document().Modify(dirty);
+        }
+    return rc;
 }
 
 bool CensusView::is_invalid()
@@ -1015,16 +340,27 @@
 
 int CensusView::selected_row()
 {
-    int row = list_model_->GetRow(list_window_->GetSelection());
-    LMI_ASSERT(0 <= row && static_cast<unsigned int>(row) < 
list_model_->GetCount());
+// TODO ?? Lossy type conversion: GetFirstSelected() returns a long
+// int, here and elsewhere in this file.
+    int row = list_window_->GetFirstSelected();
+    if(row < 0)
+        {
+        row = 0;
+// TODO ?? Reserve for grid implementation.
+//        fatal_error() << "No row selected." << LMI_FLUSH;
+        }
+    if(static_cast<int>(cell_parms().size()) <= row)
+        {
+// TODO ?? OK if about to delete?
+//        fatal_error() << "Invalid row selected." << LMI_FLUSH;
+        }
     return row;
 }
 
-/// Make a vector of all class names used by any individual, from
-/// scratch; and update the vector of class default parameters,
-/// adding any new classes, and purging any that are no longer in use
-/// by any cell.
-
+// Make a vector of all class names used by any individual, from
+// scratch; and update the vector of class default parameters,
+// adding any new classes, and purging any that are no longer in use
+// by any cell.
 void CensusView::update_class_names()
 {
     // Extract names and add them even if they might be duplicates.
@@ -1075,6 +411,7 @@
             // insert its parameters into the rebuilt vector.
             std::vector<Input>::const_iterator j = cell_parms().begin();
             bool found = false;
+            // TODO ?? There has to be a nicer way to do this with STL.
             while(j != cell_parms().end())
                 {
                 if(*n == (*j)["EmployeeClass"].str())
@@ -1203,55 +540,34 @@
     composite_is_available_ = false;
 }
 
-void CensusView::update_visible_columns()
+void CensusView::DisplayAllVaryingData()
 {
-    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("string", 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());
-    std::vector<std::string>::const_iterator i;
-    unsigned int column;
-    for(i = all_headers.begin(), column = 0; i != all_headers.end(); ++i, 
++column)
+    list_window_->InsertColumn(0, "Cell");
+    for(unsigned int column = 0; column < 
headers_of_varying_parameters_.size(); ++column)
         {
-        if
-            (  column_value_varies_across_cells(*i, class_parms())
-            || column_value_varies_across_cells(*i, cell_parms ())
-            )
-            {
-            any_member<Input> const& representative_value = 
list_model_->cell_at(0, 1 + column);
+        list_window_->InsertColumn
+            (1 + column
+            
,insert_spaces_between_words(headers_of_varying_parameters_[column])
+            );
+        }
+    for(unsigned int row = 0; row < cell_parms().size(); ++row)
+        {
+        list_window_->InsertItem
+            (row
+            ,value_cast<std::string>(row)
+            ,0
+            );
+        // TODO ?? Necessary? Move to subfunction?
+//        long index = ?
+//        list_window_->SetItemData(index, row);
 
-            wxDataViewRenderer* renderer = 
renderer_type_convertor::get(representative_value).create_renderer(representative_value);
-            LMI_ASSERT(renderer);
+        list_window_->SetItem(row, 0, value_cast<std::string>(1 + row));
 
-            list_window_->AppendColumn
-                (new(wx) wxDataViewColumn
-                    (insert_spaces_between_words(*i)
-                    ,renderer
-                    ,1 + column
-                    ,width
-                    ,wxALIGN_LEFT
-                    ,wxDATAVIEW_COL_RESIZABLE
-                    )
-                );
+        for(unsigned int column = 0; column < 
headers_of_varying_parameters_.size(); ++column)
+            {
+            std::string s = 
cell_parms()[row][headers_of_varying_parameters_[column]].str();
+            list_window_->SetItem(row, 1 + column, s);
             }
         }
 }
@@ -1266,15 +582,48 @@
     return MenuBarFromXmlResource("census_view_menu");
 }
 
+///* TODO expunge?
+// Double-click handler.
+// Factor out code: exact duplicate of CensusView::UponEditCell().
+void CensusView::UponBeginLabelEdit(wxListEvent& event)
+{
+    int cell_number = selected_row();
+    Input& original_parms = cell_parms()[cell_number];
+    Input temp_parms(original_parms);
+
+    if(wxID_OK != edit_parameters(temp_parms, cell_title(cell_number)))
+        {
+        return;
+        }
+
+    // TODO ?? Wouldn't it be better just to have edit_parameters()
+    // say whether it changed anything?
+    if(temp_parms != original_parms)
+        {
+        original_parms = temp_parms;
+        UpdatePreservingSelection();
+        document().Modify(true);
+        }
+}
+//*/
+
 void CensusView::UponEditCell(wxCommandEvent&)
 {
     int cell_number = selected_row();
-    Input& modifiable_parms = cell_parms()[cell_number];
-    std::string const title = cell_title(cell_number);
+    Input& original_parms = cell_parms()[cell_number];
+    Input temp_parms(original_parms);
 
-    if(oe_mvc_dv_changed == edit_parameters(modifiable_parms, title))
+    if(wxID_OK != edit_parameters(temp_parms, cell_title(cell_number)))
         {
-        Update();
+        return;
+        }
+
+    // TODO ?? Wouldn't it be better just to have edit_parameters()
+    // say whether it changed anything?
+    if(temp_parms != original_parms)
+        {
+        original_parms = temp_parms;
+        UpdatePreservingSelection();
         document().Modify(true);
         }
 }
@@ -1283,12 +632,16 @@
 {
     int cell_number = selected_row();
     std::string class_name = class_name_from_cell_number(cell_number);
-    Input& modifiable_parms = *class_parms_from_class_name(class_name);
-    Input const unmodified_parms(modifiable_parms);
-    std::string const title = class_title(cell_number);
+    Input& original_parms = *class_parms_from_class_name(class_name);
+    Input temp_parms(original_parms);
 
-    if(oe_mvc_dv_changed == edit_parameters(modifiable_parms, title))
+    if(wxID_OK != edit_parameters(temp_parms, class_title(cell_number)))
         {
+        return;
+        }
+
+    if(!(temp_parms == original_parms))
+        {
         int z = wxMessageBox
             ("Apply all changes to every cell in this class?"
             ,"Confirm changes"
@@ -1296,20 +649,24 @@
             );
         if(wxYES == z)
             {
-            apply_changes(modifiable_parms, unmodified_parms, true);
+            apply_changes(temp_parms, original_parms, true);
             }
-        Update();
+        original_parms = temp_parms;
+        UpdatePreservingSelection();
         document().Modify(true);
         }
 }
 
 void CensusView::UponEditCase(wxCommandEvent&)
 {
-    Input& modifiable_parms = case_parms()[0];
-    Input const unmodified_parms(modifiable_parms);
-    std::string const title = "Default parameters for case";
+    Input& original_parms = case_parms()[0];
+    Input temp_parms(original_parms);
+    if(wxID_OK != edit_parameters(temp_parms, "Default parameters for case"))
+        {
+        return;
+        }
 
-    if(oe_mvc_dv_changed == edit_parameters(modifiable_parms, title))
+    if(!(temp_parms == original_parms))
         {
         int z = wxMessageBox
             ("Apply all changes to every cell?"
@@ -1318,41 +675,47 @@
             );
         if(wxYES == z)
             {
-            apply_changes(modifiable_parms, unmodified_parms, false);
+            apply_changes(temp_parms, original_parms, false);
             }
-        Update();
+        original_parms = temp_parms;
+        UpdatePreservingSelection();
         document().Modify(true);
         }
 }
 
-/// Make each nonfrozen column wide enough to display its widest entry,
-/// ignoring column headers.
-
+// Make each nonfrozen column wide enough to display its widest entry,
+// ignoring column headers.
+//
+// VZ note from sample program (is this true?):
+// "note that under MSW for SetColumnWidth() to work we need to create the
+// items with images initially even if we specify dummy image id"
+//
+// TODO ?? Offer both ways of autosizing.
+//
 void CensusView::UponColumnWidthVarying(wxCommandEvent&)
 {
-    autosize_columns_ = true;
-
     wxWindowUpdateLocker u(list_window_);
-    for(unsigned int j = 0; j < list_window_->GetColumnCount(); ++j)
+    for(int j = 0; j < list_window_->GetColumnCount(); ++j)
         {
-        list_window_->GetColumn(j)->SetWidth(wxCOL_WIDTH_AUTOSIZE);
+// TODO ?? Pick one, and remove the other?
+//        list_window_->SetColumnWidth(j, wxLIST_AUTOSIZE);
+        list_window_->SetColumnWidth(j, wxLIST_AUTOSIZE_USEHEADER);
         }
 }
 
-/// Shrink all nonfrozen columns to default width.
-
+// Shrink all nonfrozen columns to default width.
 void CensusView::UponColumnWidthFixed(wxCommandEvent&)
 {
-    autosize_columns_ = false;
-
     wxWindowUpdateLocker u(list_window_);
-    for(unsigned int j = 0; j < list_window_->GetColumnCount(); ++j)
+    for(int j = 0; j < list_window_->GetColumnCount(); ++j)
         {
-        list_window_->GetColumn(j)->SetWidth(wxCOL_WIDTH_DEFAULT);
+        // WX !! Sad to hardcode '80', but that's the undocumented wx default.
+        // TODO ?? If it's a default, then why must it be specified?
+        list_window_->SetColumnWidth(j, 80);
         }
 }
 
-void CensusView::UponRightClick(wxDataViewEvent&)
+void CensusView::UponRightClick(wxContextMenuEvent&)
 {
     wxMenu* census_menu = wxXmlResource::Get()->LoadMenu("census_menu_ref");
     LMI_ASSERT(census_menu);
@@ -1360,46 +723,57 @@
     delete census_menu;
 }
 
-void CensusView::UponUpdateAlwaysEnabled(wxUpdateUIEvent& e)
+void CensusView::UponUpdateApplicable(wxUpdateUIEvent& e)
 {
     e.Enable(true);
 }
 
-void CensusView::UponUpdateSingleSelection(wxUpdateUIEvent& e)
-{
-    bool const is_single_sel = list_window_->GetSelection().IsOk();
-    e.Enable(is_single_sel);
-}
-
-void CensusView::UponUpdateNonemptySelection(wxUpdateUIEvent& e)
-{
-    wxDataViewItemArray selection;
-    unsigned int n_sel_items = list_window_->GetSelections(selection);
-    e.Enable(0 < n_sel_items);
-}
-
-/// Update the dataview display.
-///
-/// If a parameter was formerly the same for all cells but now differs due
-///  to editing, then display its column for all cells.
-/// If a column was previously displayed but is now the same for all cells
-///  due to editing, then display it no longer.
-/// Similarly, if an old employee class is no longer used, remove it; and
-///  if a new one comes into use, display it.
-
+// Update the spreadsheet display.
+// If a parameter was formerly the same for all cells but now differs due
+//  to editing, then display its column for all cells.
+// If a column was previously displayed but is now the same for all cells
+//  due to editing, then display it no longer.
+// Similarly, if an old employee class is no longer used, remove it; and
+//  if a new one comes into use, display it.
 void CensusView::Update()
 {
-    LMI_ASSERT(list_model_->GetCount() == cell_parms().size());
-
     wxWindowUpdateLocker u(list_window_);
 
+    list_window_->ClearAll();
+
     update_class_names();
-    update_visible_columns();
+    identify_varying_columns();
+    DisplayAllVaryingData();
 
     // All displayed data is valid when this function ends.
     all_changes_have_been_validated_ = true;
 }
 
+void CensusView::UpdatePreservingSelection()
+{
+    wxWindowUpdateLocker u(list_window_);
+
+    // Save active cell.
+    int selection = selected_row();
+    int top_row = list_window_->GetTopItem();
+// TODO ?? Reserve for grid implementation.
+//    int c = selected_column();
+
+    Update();
+
+    // Restore active cell.
+    // TODO ?? Better would be to restore to previously active col and row
+    // as determined by col hdr and cell #.
+    //
+    // This is kind of nasty. There's no SetTopItem(). Maybe it can be
+    // faked by 'ensuring' that the last row is visible first.
+    selection = std::min(selection, list_window_->GetItemCount());
+    list_window_->Select(selection);
+    list_window_->EnsureVisible(list_window_->GetItemCount());
+    list_window_->EnsureVisible(top_row);
+    list_window_->EnsureVisible(selection);
+}
+
 void CensusView::UponPrintCase(wxCommandEvent&)
 {
     DoAllCells(mce_emit_pdf_to_printer);
@@ -1489,15 +863,8 @@
         }
 
     cell_parms().push_back(case_parms()[0]);
-    list_model_->RowAppended();
-
-    Update();
+    UpdatePreservingSelection();
     document().Modify(true);
-
-    wxDataViewItem const& z = list_model_->GetItem(list_model_->GetCount() - 
1);
-    list_window_->UnselectAll();
-    list_window_->Select(z);
-    list_window_->EnsureVisible(z);
 }
 
 void CensusView::UponDeleteCells(wxCommandEvent&)
@@ -1507,12 +874,8 @@
         return;
         }
 
-    unsigned int n_items = list_model_->GetCount();
-    wxDataViewItemArray selection;
-    unsigned int n_sel_items = list_window_->GetSelections(selection);
-    LMI_ASSERT(n_sel_items == selection.size());
-    // This handler should have been disabled if no cell is selected.
-    LMI_ASSERT(0 < n_sel_items);
+    unsigned int n_items = list_window_->GetItemCount();
+    unsigned int n_sel_items = list_window_->GetSelectedItemCount();
 
     if(n_items == n_sel_items)
         {
@@ -1544,12 +907,14 @@
         return;
         }
 
-    wxArrayInt erasures;
-    typedef wxDataViewItemArray::const_iterator dvci;
-    for(dvci i = selection.begin(); i != selection.end(); ++i)
+    std::vector<unsigned int> erasures;
+    int index = list_window_->GetFirstSelected();
+    while(-1 != index)
         {
-        erasures.push_back(list_model_->GetRow(*i));
+        erasures.push_back(index);
+        index = list_window_->GetNextSelected(index);
         }
+
     std::sort(erasures.begin(), erasures.end());
 
     LMI_ASSERT(cell_parms().size() == n_items);
@@ -1571,33 +936,11 @@
 //    cell_parms().swap(expurgated_cell_parms); // TODO ?? Would this be 
better?
     cell_parms() = expurgated_cell_parms;
 
-#if !wxCHECK_VERSION(2,9,3)
-    // Remove selection to work around wx-2.9.2 bug in GetSelections()
-    // (we'll set it again below).
-    list_window_->UnselectAll();
-#endif
-
-    // 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(unsigned int j = erasures.front(); j < cell_parms().size(); ++j)
-        list_model_->RowValueChanged(j, CensusViewDataViewModel::Col_CellNum);
-
-    unsigned int const newsel = std::min
-        (static_cast<unsigned int>(erasures.front())
-        ,cell_parms().size() - 1
-        );
-    wxDataViewItem const& y = list_model_->GetItem(newsel);
-    list_window_->Select(y);
-    list_window_->EnsureVisible(y);
-
     Update();
     document().Modify(true);
 }
 
-/// Print tab-delimited output to file loadable in spreadsheet programs.
-
+// Print tab-delimited output to file loadable in spreadsheet programs.
 void CensusView::UponRunCaseToSpreadsheet(wxCommandEvent&)
 {
     std::string spreadsheet_filename =
@@ -1729,7 +1072,6 @@
     std::back_insert_iterator<std::vector<Input> > iip(cell_parms());
     std::copy(cells.begin(), cells.end(), iip);
     document().Modify(true);
-    list_model_->Reset(cell_parms().size());
     Update();
     status() << std::flush;
 

Modified: lmi/trunk/census_view.hpp
===================================================================
--- lmi/trunk/census_view.hpp   2011-10-25 15:09:08 UTC (rev 5303)
+++ lmi/trunk/census_view.hpp   2011-10-26 13:42:26 UTC (rev 5304)
@@ -30,37 +30,34 @@
 
 #include "input.hpp"
 #include "ledger.hpp"
-#include "mc_enum_type_enums.hpp"       // enum mcenum_emission
+#include "mc_enum_type_enums.hpp" // enum mcenum_emission
 #include "obstruct_slicing.hpp"
-#include "oecumenic_enumerations.hpp"
 #include "uncopyable_lmi.hpp"
 
 #include <boost/shared_ptr.hpp>
 
-#include <wx/object.h>                  // wxObjectDataPtr
+#include <wx/defs.h> // wx shared-library 'attributes'
 
 #include <string>
 #include <vector>
 
 class CensusDocument;
-class CensusViewDataViewModel;
+class WXDLLIMPEXP_FWD_CORE wxListEvent;
+class WXDLLIMPEXP_FWD_CORE wxListView;
 
-class WXDLLIMPEXP_FWD_ADV wxDataViewEvent;
-class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
-
 class CensusView
     :        public  ViewEx
     ,        private lmi::uncopyable <CensusView>
     ,virtual private obstruct_slicing<CensusView>
 {
     friend class CensusDocument;
-    friend class CensusViewDataViewModel;
 
   public:
     CensusView();
+    virtual ~CensusView();
 
   private:
-    void update_visible_columns();
+    void DisplayAllVaryingData();
 
     CensusDocument& document() const;
 
@@ -70,6 +67,7 @@
     virtual wxMenuBar* MenuBar() const;
 
     void UponAddCell                (wxCommandEvent&);
+    void UponBeginLabelEdit         (wxListEvent&); // TODO ?? Expunge.
     void UponDeleteCells            (wxCommandEvent&);
     void UponEditCell               (wxCommandEvent&);
     void UponEditClass              (wxCommandEvent&);
@@ -77,19 +75,18 @@
     void UponColumnWidthVarying     (wxCommandEvent&);
     void UponColumnWidthFixed       (wxCommandEvent&);
     void UponPasteCensus            (wxCommandEvent&);
-    void UponRightClick             (wxDataViewEvent&);
+    void UponRightClick             (wxContextMenuEvent&);
     void UponPrintCase              (wxCommandEvent&);
     void UponPrintCaseToDisk        (wxCommandEvent&);
     void UponRunCell                (wxCommandEvent&);
     void UponRunCase                (wxCommandEvent&);
     void UponRunCaseToSpreadsheet   (wxCommandEvent&);
-    void UponUpdateAlwaysEnabled    (wxUpdateUIEvent&);
-    void UponUpdateSingleSelection  (wxUpdateUIEvent&);
-    void UponUpdateNonemptySelection(wxUpdateUIEvent&);
+    void UponUpdateApplicable       (wxUpdateUIEvent&);
 
     bool DoAllCells(mcenum_emission);
 
     void Update();
+    void UpdatePreservingSelection();
     void ViewOneCell(int);
     void ViewComposite();
 
@@ -116,11 +113,13 @@
         ,std::vector<Input> const& cells
         ) const;
 
-    oenum_mvc_dv_rc edit_parameters
+    int edit_parameters
         (Input&             parameters
-        ,std::string const& title
+        ,std::string const& name
         );
 
+    void identify_varying_columns();
+
     bool is_invalid();
 
     int selected_column();
@@ -130,16 +129,15 @@
 
     bool all_changes_have_been_validated_;
 
-    bool autosize_columns_;
-
     bool composite_is_available_;
 
     boost::shared_ptr<Ledger const> composite_ledger_;
 
+    std::vector<std::string> headers_of_varying_parameters_;
+
     bool was_cancelled_;
 
-    wxDataViewCtrl* list_window_;
-    wxObjectDataPtr<CensusViewDataViewModel> list_model_;
+    wxListView* list_window_;
 
     DECLARE_DYNAMIC_CLASS(CensusView)
     DECLARE_EVENT_TABLE()




reply via email to

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