]> git.saurik.com Git - wxWidgets.git/commitdiff
Add support for custom numeric formats to wxGrid.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 28 Nov 2011 13:23:33 +0000 (13:23 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 28 Nov 2011 13:23:33 +0000 (13:23 +0000)
Allow %e and %g formats (as well as their upper-letter equivalents) in
addition to the default %f format for number display in wxGrid.

Closes #13583.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69856 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/generic/gridctrl.h
include/wx/generic/grideditors.h
interface/wx/grid.h
samples/grid/griddemo.cpp
src/generic/gridctrl.cpp
src/generic/grideditors.cpp

index 2f07b5e0c4cee32b8135378f47c3cb9ea2a44584..f3d6a10c09cb4e5c246ae1e84738b1f5c3fa06eb 100644 (file)
@@ -477,6 +477,7 @@ All (GUI):
 - Allow setting window shape to arbitrary wxGraphicsPath.
 - Added wxTextEntry::AutoCompleteDirectories().
 - Support float, double and file name values in wxGenericValidator (troelsk).
+- Add support for custom numeric formats to wxGrid (Kinaou HervĂ©).
 - Fix keyboard navigation in wxGrid with hidden columns (ivan_14_32).
 - Add wxDataViewEvent::IsEditCancelled() (Allonii).
 - Send EVT_DATAVIEW_ITEM_CONTEXT_MENU events even when not clicking on an item.
index 3ff43281fa1b94f9b93fe04a1d8ef2f4cdd869a9..b9ee0a1a0f027107067f6c207e2172d0f0f3ba54 100644 (file)
@@ -81,13 +81,17 @@ protected:
 class WXDLLIMPEXP_ADV wxGridCellFloatRenderer : public wxGridCellStringRenderer
 {
 public:
-    wxGridCellFloatRenderer(int width = -1, int precision = -1);
+    wxGridCellFloatRenderer(int width = -1,
+                            int precision = -1,
+                            int format = wxGRID_FLOAT_FORMAT_DEFAULT);
 
     // get/change formatting parameters
     int GetWidth() const { return m_width; }
     void SetWidth(int width) { m_width = width; m_format.clear(); }
     int GetPrecision() const { return m_precision; }
     void SetPrecision(int precision) { m_precision = precision; m_format.clear(); }
+    int GetFormat() const { return m_style; }
+    void SetFormat(int format) { m_style = format; m_format.clear(); }
 
     // draw the string right aligned with given width/precision
     virtual void Draw(wxGrid& grid,
@@ -102,7 +106,8 @@ public:
                                wxDC& dc,
                                int row, int col);
 
-    // parameters string format is "width[,precision]"
+    // parameters string format is "width[,precision[,format]]"
+    // with format being one of f|e|g|E|F|G
     virtual void SetParameters(const wxString& params);
 
     virtual wxGridCellRenderer *Clone() const;
@@ -115,6 +120,7 @@ private:
     int m_width,
         m_precision;
 
+    int m_style;
     wxString m_format;
 };
 
index a81b17c9d93e88e57d10cc2d98a5bc74e485df86..e76e61957601bcc71ceb8c2967ac4f0d3beb790b 100644 (file)
@@ -154,11 +154,38 @@ private:
     wxDECLARE_NO_COPY_CLASS(wxGridCellNumberEditor);
 };
 
+
+enum wxGridCellFloatFormat
+{
+    // Decimal floating point (%f)
+    wxGRID_FLOAT_FORMAT_FIXED      = 0x0010,
+
+    // Scientific notation (mantise/exponent) using e character (%e)
+    wxGRID_FLOAT_FORMAT_SCIENTIFIC = 0x0020,
+
+    // Use the shorter of %e or %f (%g)
+    wxGRID_FLOAT_FORMAT_COMPACT    = 0x0040,
+
+    // To use in combination with one of the above formats (%F/%E/%G)
+    wxGRID_FLOAT_FORMAT_UPPER      = 0x0080,
+
+    // Format used by default.
+    wxGRID_FLOAT_FORMAT_DEFAULT    = wxGRID_FLOAT_FORMAT_FIXED,
+
+    // A mask to extract format from the combination of flags.
+    wxGRID_FLOAT_FORMAT_MASK       = wxGRID_FLOAT_FORMAT_FIXED |
+                                     wxGRID_FLOAT_FORMAT_SCIENTIFIC |
+                                     wxGRID_FLOAT_FORMAT_COMPACT |
+                                     wxGRID_FLOAT_FORMAT_UPPER
+};
+
 // the editor for floating point numbers (double) data
 class WXDLLIMPEXP_ADV wxGridCellFloatEditor : public wxGridCellTextEditor
 {
 public:
-    wxGridCellFloatEditor(int width = -1, int precision = -1);
+    wxGridCellFloatEditor(int width = -1,
+                          int precision = -1,
+                          int format = wxGRID_FLOAT_FORMAT_DEFAULT);
 
     virtual void Create(wxWindow* parent,
                         wxWindowID id,
@@ -176,18 +203,22 @@ public:
     virtual wxGridCellEditor *Clone() const
         { return new wxGridCellFloatEditor(m_width, m_precision); }
 
-    // parameters string format is "width,precision"
+    // parameters string format is "width[,precision[,format]]"
+    // format to choose beween f|e|g|E|G (f is used by default)
     virtual void SetParameters(const wxString& params);
 
 protected:
     // string representation of our value
-    wxString GetString() const;
+    wxString GetString();
 
 private:
     int m_width,
         m_precision;
     double m_value;
 
+    int m_style;
+    wxString m_format;
+
     wxDECLARE_NO_COPY_CLASS(wxGridCellFloatEditor);
 };
 
index 332011b2a5eaf6204020d37f432fa6a7e3370d85..e7b9e566ef4ae43f1acb19607a3eefed1324d6bb 100644 (file)
@@ -178,6 +178,31 @@ public:
     virtual void SetParameters(const wxString& params);
 };
 
+/**
+    Specifier used to format the data to string for the numbers handled by
+    wxGridCellFloatRenderer and wxGridCellFloatEditor.
+
+    @since 2.9.3
+*/
+enum wxGridCellFloatFormat
+{
+    /// Decimal floating point (%f).
+    wxGRID_FLOAT_FORMAT_FIXED       = 0x0010,
+
+    /// Scientific notation (mantise/exponent) using e character (%e).
+    wxGRID_FLOAT_FORMAT_SCIENTIFIC  = 0x0020,
+
+    /// Use the shorter of %e or %f (%g).
+    wxGRID_FLOAT_FORMAT_COMPACT     = 0x0040,
+
+    /// To use in combination with one of the above formats for the upper
+    /// case version (%F/%E/%G)
+    wxGRID_FLOAT_FORMAT_UPPER       = 0x0080,
+
+    /// The format used by default (wxGRID_FLOAT_FORMAT_FIXED).
+    wxGRID_FLOAT_FORMAT_DEFAULT     = wxGRID_FLOAT_FORMAT_FIXED
+};
+
 /**
     @class wxGridCellFloatRenderer
 
@@ -201,8 +226,22 @@ public:
             Minimum number of characters to be shown.
         @param precision
             Number of digits after the decimal dot.
+        @param format
+            The format used to display the string, must be a combination of
+            wxGridCellFloatFormat enum elements. This parameter is only
+            available since wxWidgets 2.9.3.
     */
-    wxGridCellFloatRenderer(int width = -1, int precision = -1);
+    wxGridCellFloatRenderer(int width = -1, int precision = -1,
+                            int format = wxGRID_FLOAT_FORMAT_DEFAULT);
+
+    /**
+        Returns the specifier used to format the data to string.
+
+        The returned value is a combination of wxGridCellFloatFormat elements.
+
+        @since 2.9.3
+    */
+    int GetFormat() const;
 
     /**
         Returns the precision.
@@ -215,7 +254,18 @@ public:
     int GetWidth() const;
 
     /**
-        Parameters string format is "width[,precision]".
+        Set the format to use for display the number.
+
+        @param format
+            Must be a combination of wxGridCellFloatFormat enum elements.
+
+        @since 2.9.3
+    */
+    void SetFormat(int format);
+
+    /**
+        The parameters string format is "width[,precision[,format]]" where
+        @c format should be choosen beween f|e|g|E|G (f is used by default)
     */
     virtual void SetParameters(const wxString& params);
 
@@ -596,11 +646,17 @@ public:
             Minimum number of characters to be shown.
         @param precision
             Number of digits after the decimal dot.
+        @param format
+            The format to use for displaying the number, a combination of
+            wxGridCellFloatFormat enum elements. This parameter is only
+            available since wxWidgets 2.9.3.
     */
-    wxGridCellFloatEditor(int width = -1, int precision = -1);
+    wxGridCellFloatEditor(int width = -1, int precision = -1,
+                          int format = wxGRID_FLOAT_FORMAT_DEFAULT);
 
     /**
-        Parameters string format is "width,precision"
+        The parameters string format is "width[,precision[,format]]" where
+        @c format should be choosen beween f|e|g|E|G (f is used by default)
     */
     virtual void SetParameters(const wxString& params);
 };
index 93b1d9515534880adfdbcf8da9e2a601c3d14a55..aa3b4d59c4e21f65f31803634275a739d20df2a6 100644 (file)
@@ -439,22 +439,33 @@ GridFrame::GridFrame()
     grid->SetCellValue(5, 8, wxT("Bg from row attr\nText col from cell attr"));
     grid->SetCellValue(5, 5, wxT("Bg from row attr Text col from col attr and this text is so long that it covers over many many empty cells but is broken by one that isn't"));
 
+    // Some numeric columns with different formatting.
     grid->SetColFormatFloat(6);
-    grid->SetCellValue(0, 6, wxString::Format(wxT("%g"), 3.1415));
-    grid->SetCellValue(1, 6, wxString::Format(wxT("%g"), 1415.0));
-    grid->SetCellValue(2, 6, wxString::Format(wxT("%g"), 12345.67890));
+    grid->SetCellValue(0, 6, "Default\nfloat format");
+    grid->SetCellValue(1, 6, wxString::Format(wxT("%g"), 3.1415));
+    grid->SetCellValue(2, 6, wxString::Format(wxT("%g"), 1415.0));
+    grid->SetCellValue(3, 6, wxString::Format(wxT("%g"), 12345.67890));
 
     grid->SetColFormatFloat(7, 6, 2);
-    grid->SetCellValue(0, 7, wxString::Format(wxT("%g"), 3.1415));
-    grid->SetCellValue(1, 7, wxString::Format(wxT("%g"), 1415.0));
-    grid->SetCellValue(2, 7, wxString::Format(wxT("%g"), 12345.67890));
-
-    grid->SetColFormatNumber(8);
-    grid->SetCellValue(0, 8, "17");
-    grid->SetCellValue(1, 8, "0");
-    grid->SetCellValue(2, 8, "-666");
-    grid->SetCellAlignment(2, 8, wxALIGN_CENTRE, wxALIGN_TOP);
-    grid->SetCellValue(2, 9, "<- This numeric cell should be centred");
+    grid->SetCellValue(0, 7, "Width 6\nprecision 2");
+    grid->SetCellValue(1, 7, wxString::Format(wxT("%g"), 3.1415));
+    grid->SetCellValue(2, 7, wxString::Format(wxT("%g"), 1415.0));
+    grid->SetCellValue(3, 7, wxString::Format(wxT("%g"), 12345.67890));
+
+    grid->SetColFormatCustom(8,
+            wxString::Format("%s:%i,%i,%s", wxGRID_VALUE_FLOAT, -1, 4, "g"));
+    grid->SetCellValue(0, 8, "Compact\nformat");
+    grid->SetCellValue(1, 8, wxT("31415e-4"));
+    grid->SetCellValue(2, 8, wxT("1415"));
+    grid->SetCellValue(3, 8, wxT("123456789e-4"));
+
+    grid->SetColFormatNumber(9);
+    grid->SetCellValue(0, 9, "Integer\ncolumn");
+    grid->SetCellValue(1, 9, "17");
+    grid->SetCellValue(2, 9, "0");
+    grid->SetCellValue(3, 9, "-666");
+    grid->SetCellAlignment(3, 9, wxALIGN_CENTRE, wxALIGN_TOP);
+    grid->SetCellValue(3, 10, "<- This numeric cell should be centred");
 
     const wxString choices[] =
     {
index ff201c0189ac66a11bc733a6c4b2ae176b2e566d..65b7edd192acfe8b92a5f9b895ec99daabc1201a 100644 (file)
@@ -598,10 +598,13 @@ wxSize wxGridCellNumberRenderer::GetBestSize(wxGrid& grid,
 // wxGridCellFloatRenderer
 // ----------------------------------------------------------------------------
 
-wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision)
+wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width,
+                                                 int precision,
+                                                 int format)
 {
     SetWidth(width);
     SetPrecision(precision);
+    SetFormat(format);
 }
 
 wxGridCellRenderer *wxGridCellFloatRenderer::Clone() const
@@ -609,6 +612,7 @@ wxGridCellRenderer *wxGridCellFloatRenderer::Clone() const
     wxGridCellFloatRenderer *renderer = new wxGridCellFloatRenderer;
     renderer->m_width = m_width;
     renderer->m_precision = m_precision;
+    renderer->m_style = m_style;
     renderer->m_format = m_format;
 
     return renderer;
@@ -641,22 +645,30 @@ wxString wxGridCellFloatRenderer::GetString(const wxGrid& grid, int row, int col
                 if ( m_precision == -1 )
                 {
                     // default width/precision
-                    m_format = wxT("%f");
+                    m_format = wxT("%");
                 }
                 else
                 {
-                    m_format.Printf(wxT("%%.%df"), m_precision);
+                    m_format.Printf(wxT("%%.%d"), m_precision);
                 }
             }
             else if ( m_precision == -1 )
             {
                 // default precision
-                m_format.Printf(wxT("%%%d.f"), m_width);
+                m_format.Printf(wxT("%%%d."), m_width);
             }
             else
             {
-                m_format.Printf(wxT("%%%d.%df"), m_width, m_precision);
+                m_format.Printf(wxT("%%%d.%d"), m_width, m_precision);
             }
+
+            bool isUpper = ( ( m_style & wxGRID_FLOAT_FORMAT_UPPER ) == wxGRID_FLOAT_FORMAT_UPPER);
+            if ( ( m_style & wxGRID_FLOAT_FORMAT_SCIENTIFIC ) == wxGRID_FLOAT_FORMAT_SCIENTIFIC)
+                m_format += isUpper ? wxT('E') : wxT('e');
+            else if ( ( m_style & wxGRID_FLOAT_FORMAT_COMPACT ) == wxGRID_FLOAT_FORMAT_COMPACT)
+                m_format += isUpper ? wxT('G') : wxT('g');
+            else
+                m_format += wxT('f');
         }
 
         text.Printf(m_format, val);
@@ -704,10 +716,12 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params)
         // reset to defaults
         SetWidth(-1);
         SetPrecision(-1);
+        SetFormat(wxGRID_FLOAT_FORMAT_DEFAULT);
     }
     else
     {
-        wxString tmp = params.BeforeFirst(wxT(','));
+        wxString rest;
+        wxString tmp = params.BeforeFirst(wxT(','), &rest);
         if ( !tmp.empty() )
         {
             long width;
@@ -721,7 +735,7 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params)
             }
         }
 
-        tmp = params.AfterFirst(wxT(','));
+        tmp = rest.BeforeFirst(wxT(','));
         if ( !tmp.empty() )
         {
             long precision;
@@ -734,6 +748,43 @@ void wxGridCellFloatRenderer::SetParameters(const wxString& params)
                 wxLogDebug(wxT("Invalid wxGridCellFloatRenderer precision parameter string '%s ignored"), params.c_str());
             }
         }
+
+        tmp = rest.AfterFirst(wxT(','));
+        if ( !tmp.empty() )
+        {
+            if ( tmp[0] == wxT('f') )
+            {
+                SetFormat(wxGRID_FLOAT_FORMAT_FIXED);
+            }
+            else if ( tmp[0] == wxT('e') )
+            {
+                SetFormat(wxGRID_FLOAT_FORMAT_SCIENTIFIC);
+            }
+            else if ( tmp[0] == wxT('g') )
+            {
+                SetFormat(wxGRID_FLOAT_FORMAT_COMPACT);
+            }
+            else if ( tmp[0] == wxT('E') )
+            {
+                SetFormat(wxGRID_FLOAT_FORMAT_SCIENTIFIC |
+                          wxGRID_FLOAT_FORMAT_UPPER);
+            }
+            else if ( tmp[0] == wxT('F') )
+            {
+                SetFormat(wxGRID_FLOAT_FORMAT_FIXED |
+                          wxGRID_FLOAT_FORMAT_UPPER);
+            }
+            else if ( tmp[0] == wxT('G') )
+            {
+                SetFormat(wxGRID_FLOAT_FORMAT_COMPACT |
+                          wxGRID_FLOAT_FORMAT_UPPER);
+            }
+            else
+            {
+                wxLogDebug("Invalid wxGridCellFloatRenderer format "
+                           "parameter string '%s ignored", params);
+            }
+        }
     }
 }
 
index ac90aa3310bdb867d4a8c501a68a744f4fcfe730..d3113c686747dbacb862d08bb934a6e0a041dcfb 100644 (file)
@@ -862,10 +862,13 @@ wxString wxGridCellNumberEditor::GetValue() const
 // wxGridCellFloatEditor
 // ----------------------------------------------------------------------------
 
-wxGridCellFloatEditor::wxGridCellFloatEditor(int width, int precision)
+wxGridCellFloatEditor::wxGridCellFloatEditor(int width,
+                                             int precision,
+                                             int format)
 {
     m_width = width;
     m_precision = precision;
+    m_style = format;
 }
 
 void wxGridCellFloatEditor::Create(wxWindow* parent,
@@ -988,51 +991,113 @@ void wxGridCellFloatEditor::SetParameters(const wxString& params)
         // reset to default
         m_width =
         m_precision = -1;
+        m_style = wxGRID_FLOAT_FORMAT_DEFAULT;
+        m_format.clear();
     }
     else
     {
-        long tmp;
-        if ( params.BeforeFirst(wxT(',')).ToLong(&tmp) )
+        wxString rest;
+        wxString tmp = params.BeforeFirst(wxT(','), &rest);
+        if ( !tmp.empty() )
         {
-            m_width = (int)tmp;
-
-            if ( params.AfterFirst(wxT(',')).ToLong(&tmp) )
+            long width;
+            if ( tmp.ToLong(&width) )
+            {
+                m_width = (int)width;
+            }
+            else
             {
-                m_precision = (int)tmp;
+                wxLogDebug(wxT("Invalid wxGridCellFloatRenderer width parameter string '%s ignored"), params.c_str());
+            }
+        }
 
-                // skip the error message below
-                return;
+        tmp = rest.BeforeFirst(wxT(','));
+        if ( !tmp.empty() )
+        {
+            long precision;
+            if ( tmp.ToLong(&precision) )
+            {
+                m_precision = (int)precision;
+            }
+            else
+            {
+                wxLogDebug(wxT("Invalid wxGridCellFloatRenderer precision parameter string '%s ignored"), params.c_str());
             }
         }
 
-        wxLogDebug(wxT("Invalid wxGridCellFloatEditor parameter string '%s' ignored"), params.c_str());
+        tmp = rest.AfterFirst(wxT(','));
+        if ( !tmp.empty() )
+        {
+            if ( tmp[0] == wxT('f') )
+            {
+                m_style = wxGRID_FLOAT_FORMAT_FIXED;
+            }
+            else if ( tmp[0] == wxT('e') )
+            {
+                m_style = wxGRID_FLOAT_FORMAT_SCIENTIFIC;
+            }
+            else if ( tmp[0] == wxT('g') )
+            {
+                m_style = wxGRID_FLOAT_FORMAT_COMPACT;
+            }
+            else if ( tmp[0] == wxT('E') )
+            {
+                m_style = wxGRID_FLOAT_FORMAT_SCIENTIFIC |
+                          wxGRID_FLOAT_FORMAT_UPPER;
+            }
+            else if ( tmp[0] == wxT('F') )
+            {
+                m_style = wxGRID_FLOAT_FORMAT_FIXED |
+                          wxGRID_FLOAT_FORMAT_UPPER;
+            }
+            else if ( tmp[0] == wxT('G') )
+            {
+                m_style = wxGRID_FLOAT_FORMAT_COMPACT |
+                          wxGRID_FLOAT_FORMAT_UPPER;
+            }
+            else
+            {
+                wxLogDebug("Invalid wxGridCellFloatRenderer format "
+                           "parameter string '%s ignored", params);
+            }
+        }
     }
 }
 
-wxString wxGridCellFloatEditor::GetString() const
+wxString wxGridCellFloatEditor::GetString()
 {
-    wxString fmt;
-    if ( m_precision == -1 && m_width != -1)
+    if ( !m_format )
     {
-        // default precision
-        fmt.Printf(wxT("%%%d.f"), m_width);
-    }
-    else if ( m_precision != -1 && m_width == -1)
-    {
-        // default width
-        fmt.Printf(wxT("%%.%df"), m_precision);
-    }
-    else if ( m_precision != -1 && m_width != -1 )
-    {
-        fmt.Printf(wxT("%%%d.%df"), m_width, m_precision);
-    }
-    else
-    {
-        // default width/precision
-        fmt = wxT("%f");
+        if ( m_precision == -1 && m_width != -1)
+        {
+            // default precision
+            m_format.Printf(wxT("%%%d."), m_width);
+        }
+        else if ( m_precision != -1 && m_width == -1)
+        {
+            // default width
+            m_format.Printf(wxT("%%.%d"), m_precision);
+        }
+        else if ( m_precision != -1 && m_width != -1 )
+        {
+            m_format.Printf(wxT("%%%d.%d"), m_width, m_precision);
+        }
+        else
+        {
+            // default width/precision
+            m_format = wxT("%");
+        }
+
+        bool isUpper = (m_style & wxGRID_FLOAT_FORMAT_UPPER) != 0;
+        if ( m_style & wxGRID_FLOAT_FORMAT_SCIENTIFIC )
+            m_format += isUpper ? wxT('E') : wxT('e');
+        else if ( m_style & wxGRID_FLOAT_FORMAT_COMPACT )
+            m_format += isUpper ? wxT('G') : wxT('g');
+        else
+            m_format += wxT('f');
     }
 
-    return wxString::Format(fmt, m_value);
+    return wxString::Format(m_format, m_value);
 }
 
 bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event)