]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
avoid assert in DoGetBestSize() for an empty tree
[wxWidgets.git] / src / generic / grid.cpp
index 28923facce7b4c4c5a5171c1375d2267436348c7..0e77e10991d68a32df7cdd741bf6c354497f5e18 100644 (file)
@@ -18,6 +18,8 @@
 
 #if wxUSE_GRID
 
+#include "wx/grid.h"
+
 #ifndef WX_PRECOMP
     #include "wx/utils.h"
     #include "wx/dcclient.h"
 #include "wx/tokenzr.h"
 #include "wx/renderer.h"
 
-#include "wx/grid.h"
 #include "wx/generic/gridsel.h"
 
+const wxChar wxGridNameStr[] = wxT("grid");
+
 #if defined(__WXMOTIF__)
     #define WXUNUSED_MOTIF(identifier)  WXUNUSED(identifier)
 #else
@@ -1230,6 +1233,9 @@ bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event)
 // wxGridCellBoolEditor
 // ----------------------------------------------------------------------------
 
+// the default values for GetValue()
+wxString wxGridCellBoolEditor::ms_stringValues[2] = { _T(""), _T("1") };
+
 void wxGridCellBoolEditor::Create(wxWindow* parent,
                                   wxWindowID id,
                                   wxEvtHandler* evtHandler)
@@ -1335,7 +1341,19 @@ void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid)
     else
     {
         wxString cellval( grid->GetTable()->GetValue(row, col) );
-        m_startValue = !( !cellval || (cellval == wxT("0")) );
+
+        if ( cellval == ms_stringValues[false] )
+            m_startValue = false;
+        else if ( cellval == ms_stringValues[true] )
+            m_startValue = true;
+        else
+        {
+            // do not try to be smart here and convert it to true or false
+            // because we'll still overwrite it with something different and
+            // this risks to be very surprising for the user code, let them
+            // know about it
+            wxFAIL_MSG( _T("invalid value for a cell with bool editor!") );
+        }
     }
 
     CBox()->SetValue(m_startValue);
@@ -1355,10 +1373,11 @@ bool wxGridCellBoolEditor::EndEdit(int row, int col,
 
     if ( changed )
     {
-        if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
-            grid->GetTable()->SetValueAsBool(row, col, value);
+        wxGridTableBase * const table = grid->GetTable();
+        if ( table->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) )
+            table->SetValueAsBool(row, col, value);
         else
-            grid->GetTable()->SetValue(row, col, value ? _T("1") : wxEmptyString);
+            table->SetValue(row, col, GetValue());
     }
 
     return changed;
@@ -1413,12 +1432,23 @@ void wxGridCellBoolEditor::StartingKey(wxKeyEvent& event)
     }
 }
 
-
-// return the value as "1" for true and the empty string for false
 wxString wxGridCellBoolEditor::GetValue() const
 {
-  bool bSet = CBox()->GetValue();
-  return bSet ? _T("1") : wxEmptyString;
+  return ms_stringValues[CBox()->GetValue()];
+}
+
+/* static */ void
+wxGridCellBoolEditor::UseStringValues(const wxString& valueTrue,
+                                      const wxString& valueFalse)
+{
+    ms_stringValues[false] = valueFalse;
+    ms_stringValues[true] = valueTrue;
+}
+
+/* static */ bool
+wxGridCellBoolEditor::IsTrueValue(const wxString& value)
+{
+    return value == ms_stringValues[true];
 }
 
 #endif // wxUSE_CHECKBOX
@@ -2214,7 +2244,7 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid,
     else
     {
         wxString cellval( grid.GetTable()->GetValue(row, col) );
-        value = !( !cellval || (cellval == wxT("0")) );
+        value = wxGridCellBoolEditor::IsTrueValue(cellval);
     }
 
     if ( value )
@@ -2289,6 +2319,7 @@ wxGridCellAttr *wxGridCellAttr::Clone() const
     if ( IsReadOnly() )
         attr->SetReadOnly();
 
+    attr->SetOverflow( m_overflow == Overflow );
     attr->SetKind( m_attrkind );
 
     return attr;
@@ -3878,7 +3909,8 @@ void wxGridCornerLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
     GetClientSize( &client_width, &client_height );
 
     // VZ: any reason for this ifdef? (FIXME)
-#ifdef __WXGTK__
+#if 0
+def __WXGTK__
     wxRect rect;
     rect.SetX( 1 );
     rect.SetY( 1 );
@@ -4131,7 +4163,7 @@ wxGrid::wxGrid( wxWindow *parent,
     m_rowMinHeights(GRID_HASH_SIZE)
 {
     Create();
-    SetBestFittingSize(size);
+    SetInitialSize(size);
 }
 
 bool wxGrid::Create(wxWindow *parent, wxWindowID id,
@@ -4146,7 +4178,7 @@ bool wxGrid::Create(wxWindow *parent, wxWindowID id,
     m_rowMinHeights = wxLongToLongHashMap(GRID_HASH_SIZE);
 
     Create();
-    SetBestFittingSize(size);
+    SetInitialSize(size);
 
     return true;
 }
@@ -4166,8 +4198,12 @@ wxGrid::~wxGrid()
              total ? (gs_nAttrCacheHits*100) / total : 0);
 #endif
 
-    if (m_ownTable)
+    // if we own the table, just delete it, otherwise at least don't leave it
+    // with dangling view pointer
+    if ( m_ownTable )
         delete m_table;
+    else if ( m_table && m_table->GetView() == this )
+        m_table->SetView(NULL);
 
     delete m_typeRegistry;
     delete m_selection;
@@ -7066,8 +7102,10 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
         return;
     }
 
+#if !(defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS)
     wxClientDC dc( m_gridWin );
     PrepareDC( dc );
+#endif
 
     if ( m_currentCellCoords != wxGridNoCellCoords )
     {
@@ -7090,15 +7128,21 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
             // Otherwise refresh redraws the highlight!
             m_currentCellCoords = coords;
 
+#if defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS
+            m_gridWin->Refresh(true /*, & r */);
+#else
             DrawGridCellArea( dc, cells );
             DrawAllGridLines( dc, r );
+#endif
         }
     }
 
     m_currentCellCoords = coords;
 
     wxGridCellAttr *attr = GetCellAttr( coords );
+#if !(defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS)
     DrawCellHighlight( dc, attr );
+#endif
     attr->DecRef();
 }
 
@@ -7474,7 +7518,7 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
         // edit control is erased by this code after being rendered.
         // On wxMac (QD build only), the cell editor is a wxTextCntl and is rendered
         // implicitly, causing this out-of order render.
-#if !defined(__WXMAC__) || wxMAC_USE_CORE_GRAPHICS
+#if !defined(__WXMAC__)
         wxGridCellEditor *editor = attr->GetEditor(this, row, col);
         editor->PaintBackground(rect, attr);
         editor->DecRef();
@@ -7519,12 +7563,6 @@ void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr )
         rect.width -= penWidth - 1;
         rect.height -= penWidth - 1;
 
-#ifdef __WXGTK__
-        // FIXME: why is the rect drawn off-by-one?
-        if ((penWidth == 2) && (GetLayoutDirection() == wxLayout_RightToLeft))
-            rect.x -= 1;
-#endif
-
         // Now draw the rectangle
         // use the cellHighlightColour if the cell is inside a selection, this
         // will ensure the cell is always visible.
@@ -7675,17 +7713,16 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
     int rightCol = GetColPos( internalXToCol(right) );
     int bottomRow = internalYToRow(bottom);
 
-#ifndef __WXMAC__
-    // CS: I don't know why suddenly unscrolled coordinates are used for clipping
+#if !defined(__WXMAC__) || wxMAC_USE_CORE_GRAPHICS
     wxRegion clippedcells(0, 0, cw, ch);
 
     int i, j, cell_rows, cell_cols;
     wxRect rect;
 
-    for (j=topRow; j<bottomRow; j++)
+    for (j=topRow; j<=bottomRow; j++)
     {
         int colPos;
-        for (colPos=leftCol; colPos<rightCol; colPos++)
+        for (colPos=leftCol; colPos<=rightCol; colPos++)
         {
             i = GetColAt( colPos );
 
@@ -7710,9 +7747,9 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
     int i, j, cell_rows, cell_cols;
     wxRect rect;
 
-    for (j=topRow; j<bottomRow; j++)
+    for (j=topRow; j<=bottomRow; j++)
     {
-        for (i=leftCol; i<rightCol; i++)
+        for (i=leftCol; i<=rightCol; i++)
         {
             GetCellSize( j, i, &cell_rows, &cell_cols );
             if ((cell_rows > 1) || (cell_cols > 1))
@@ -7758,7 +7795,12 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
     {
         i = GetColAt( colPos );
 
-        int colRight = GetColRight(i) - 1;
+        int colRight = GetColRight(i);
+#ifdef __WXGTK__
+        if (GetLayoutDirection() != wxLayout_RightToLeft)
+#endif
+            colRight--;
+
         if ( colRight > right )
         {
             break;
@@ -7795,7 +7837,8 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row )
 
     wxRect rect;
 
-#ifdef __WXGTK20__
+#if 0
+def __WXGTK20__
     rect.SetX( 1 );
     rect.SetY( GetRowTop(row) + 1 );
     rect.SetWidth( m_rowLabelWidth - 2 );
@@ -7857,7 +7900,8 @@ void wxGrid::DrawColLabel( wxDC& dc, int col )
 
     wxRect rect;
 
-#ifdef __WXGTK20__
+#if 0
+def __WXGTK20__
     rect.SetX( colLeft + 1 );
     rect.SetY( 1 );
     rect.SetWidth( GetColWidth(col) - 2 );
@@ -10385,12 +10429,12 @@ void wxGrid::AutoSizeColOrRow( int colOrRow, bool setAsMin, bool column )
 
     if ( column )
     {
-        dc.GetTextExtent( GetColLabelValue(col), &w, &h );
+        dc.GetMultiLineTextExtent( GetColLabelValue(col), &w, &h );
         if ( GetColLabelTextOrientation() == wxVERTICAL )
             w = h;
     }
     else
-        dc.GetTextExtent( GetRowLabelValue(row), &w, &h );
+        dc.GetMultiLineTextExtent( GetRowLabelValue(row), &w, &h );
 
     extent = column ? w : h;
     if ( extent > extentMax )