]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
Use wxStringBufferLength instead of wxXCharBuffer in constructors with conversion...
[wxWidgets.git] / src / generic / grid.cpp
index ea0184e2d0a67b0c9215bfe343d223f4b723ed03..9d0e0a9f69b26d8f37dda68b35109852ddc1570e 100644 (file)
@@ -109,6 +109,7 @@ DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_LEFT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_RIGHT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_LEFT_DCLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_RIGHT_DCLICK)
+DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_BEGIN_DRAG)
 DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_CLICK)
 DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_DCLICK)
@@ -205,7 +206,7 @@ public:
                   wxGridRowLabelWindow *rowLblWin,
                   wxGridColLabelWindow *colLblWin,
                   wxWindowID id, const wxPoint &pos, const wxSize &size );
-    ~wxGridWindow();
+    ~wxGridWindow(){}
 
     void ScrollWindow( int dx, int dy, const wxRect *rect );
 
@@ -412,6 +413,7 @@ static const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X;
 // in these hash tables is the number of rows/columns)
 static const int GRID_HASH_SIZE = 100;
 
+#if 0
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
@@ -425,6 +427,7 @@ static inline int GetScrollY(int y)
 {
     return (y + GRID_SCROLL_LINE_Y - 1) / GRID_SCROLL_LINE_Y;
 }
+#endif
 
 // ============================================================================
 // implementation
@@ -499,9 +502,11 @@ void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr)
             m_colBgOld = m_control->GetBackgroundColour();
             m_control->SetBackgroundColour(attr->GetBackgroundColour());
 
+           // Workaround for GTK+1 font setting problem on some platforms
+#if !defined(__WXGTK__) || defined(__WXGTK20__)
             m_fontOld = m_control->GetFont();
             m_control->SetFont(attr->GetFont());
-
+#endif
             // can't do anything more in the base class version, the other
             // attributes may only be used by the derived classes
         }
@@ -520,12 +525,14 @@ void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr)
             m_control->SetBackgroundColour(m_colBgOld);
             m_colBgOld = wxNullColour;
         }
-
+       // Workaround for GTK+1 font setting problem on some platforms
+#if !defined(__WXGTK__) || defined(__WXGTK20__)
         if ( m_fontOld.Ok() )
         {
             m_control->SetFont(m_fontOld);
             m_fontOld = wxNullFont;
         }
+#endif
     }
 }
 
@@ -1071,7 +1078,8 @@ void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event)
     char tmpbuf[2];
     tmpbuf[0] = (char) keycode;
     tmpbuf[1] = '\0';
-    bool is_decimal_point = ( wxString(tmpbuf, *wxConvCurrent) ==
+    wxString strbuf(tmpbuf, *wxConvCurrent);
+    bool is_decimal_point = ( strbuf ==
       wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) );
         if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-'
             || is_decimal_point
@@ -1179,10 +1187,10 @@ bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event)
                 char tmpbuf[2];
                 tmpbuf[0] = (char) keycode;
                 tmpbuf[1] = '\0';
-                bool is_decimal_point =
-                  ( wxString(tmpbuf, *wxConvCurrent) ==
-                    wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
-                                      wxLOCALE_CAT_NUMBER) );
+                wxString strbuf(tmpbuf, *wxConvCurrent);
+                bool is_decimal_point = 
+                    ( strbuf == wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
+                                                  wxLOCALE_CAT_NUMBER) );
                 if ( (keycode < 128) &&
                      (wxIsdigit(keycode) || tolower(keycode) == 'e' ||
                       is_decimal_point || keycode == '+' || keycode == '-') )
@@ -1460,18 +1468,12 @@ bool wxGridCellChoiceEditor::EndEdit(int row, int col,
                                      wxGrid* grid)
 {
     wxString value = Combo()->GetValue();
-    bool changed = value != m_startValue;
-
-    if ( changed )
-        grid->GetTable()->SetValue(row, col, value);
+    if ( value == m_startValue )
+        return false;
 
-    m_startValue = wxEmptyString;
-    if (m_allowOthers)
-        Combo()->SetValue(m_startValue);
-    else
-        Combo()->SetSelection(0);
+    grid->GetTable()->SetValue(row, col, value);
 
-    return changed;
+    return true;
 }
 
 void wxGridCellChoiceEditor::Reset()
@@ -2596,8 +2598,8 @@ wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col,
                     wxGridCellAttr *attrrow = m_data->m_rowAttrs.GetAttr(row);
                     wxGridCellAttr *attrcol = m_data->m_colAttrs.GetAttr(col);
 
-                    if((attrcell != attrrow) && (attrrow !=attrcol) && (attrcell != attrcol)){
-                        // Two or move are non NULL
+                    if((attrcell != attrrow) && (attrrow != attrcol) && (attrcell != attrcol)){
+                        // Two or more are non NULL
                         attr = new wxGridCellAttr;
                         attr->SetKind(wxGridCellAttr::Merged);
 
@@ -2619,11 +2621,21 @@ wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col,
                         //m_data->m_mergeAttr.SetAttr(attr, row, col);
                     }
                     else
-        {
+                    {
                         // one or none is non null return it or null.
                         if(attrrow) attr = attrrow;
-                        if(attrcol) attr = attrcol;
-                        if(attrcell) attr = attrcell;
+                        if(attrcol)
+                        {
+                            if(attr)
+                                attr->DecRef();
+                            attr = attrcol;
+                        }
+                        if(attrcell)
+                        {
+                            if(attr)
+                                attr->DecRef();
+                            attr = attrcell;
+                        }
                     }
                 }
             break;
@@ -2631,10 +2643,10 @@ wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col,
                 attr = m_data->m_cellAttrs.GetAttr(row, col);
             break;
             case (wxGridCellAttr::Col):
-                 attr = m_data->m_colAttrs.GetAttr(col);
+                attr = m_data->m_colAttrs.GetAttr(col);
             break;
             case (wxGridCellAttr::Row):
-            attr = m_data->m_rowAttrs.GetAttr(row);
+                attr = m_data->m_rowAttrs.GetAttr(row);
             break;
             default:
                 // unused as yet...
@@ -3692,11 +3704,6 @@ wxGridWindow::wxGridWindow( wxGrid *parent,
 }
 
 
-wxGridWindow::~wxGridWindow()
-{
-}
-
-
 void wxGridWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
 {
     wxPaintDC dc( this );
@@ -3820,7 +3827,7 @@ wxEND_HANDLERS_TABLE()
 wxCONSTRUCTOR_5( wxGrid , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle )
 
 /*
- TODO : Expose more information of a list's layout etc. via appropriate objects (à la NotebookPageInfo)
+ TODO : Expose more information of a list's layout etc. via appropriate objects (\81à la NotebookPageInfo)
 */
 #else
 IMPLEMENT_DYNAMIC_CLASS( wxGrid, wxScrolledWindow )
@@ -3855,6 +3862,7 @@ wxGrid::wxGrid( wxWindow *parent,
     m_rowMinHeights(GRID_HASH_SIZE)
 {
     Create();
+    SetBestFittingSize(size);
 }
 
 bool wxGrid::Create(wxWindow *parent, wxWindowID id,
@@ -3869,7 +3877,7 @@ bool wxGrid::Create(wxWindow *parent, wxWindowID id,
     m_rowMinHeights = wxLongToLongHashMap(GRID_HASH_SIZE) ;
 
     Create() ;
-
+    SetBestFittingSize(size);
 
     return true;
 }
@@ -3990,15 +3998,15 @@ void wxGrid::Create()
     wxColour lfg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
     wxColour lbg = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
 #endif
-    m_cornerLabelWin->SetDefaultForegroundColour(lfg);
-    m_cornerLabelWin->SetDefaultBackgroundColour(lbg);
-    m_rowLabelWin->SetDefaultForegroundColour(lfg);
-    m_rowLabelWin->SetDefaultBackgroundColour(lbg);
-    m_colLabelWin->SetDefaultForegroundColour(lfg);
-    m_colLabelWin->SetDefaultBackgroundColour(lbg);
+    m_cornerLabelWin->SetOwnForegroundColour(lfg);
+    m_cornerLabelWin->SetOwnBackgroundColour(lbg);
+    m_rowLabelWin->SetOwnForegroundColour(lfg);
+    m_rowLabelWin->SetOwnBackgroundColour(lbg);
+    m_colLabelWin->SetOwnForegroundColour(lfg);
+    m_colLabelWin->SetOwnBackgroundColour(lbg);
 
-    m_gridWin->SetDefaultForegroundColour(gfg);
-    m_gridWin->SetDefaultBackgroundColour(gbg);
+    m_gridWin->SetOwnForegroundColour(gfg);
+    m_gridWin->SetOwnBackgroundColour(gbg);
 
     Init();
 }
@@ -4139,6 +4147,7 @@ void wxGrid::Init()
     m_canDragRowSize = true;
     m_canDragColSize = true;
     m_canDragGridSize = true;
+    m_canDragCell = false;
     m_dragLastPos  = -1;
     m_dragRowOrCol = -1;
     m_isDragging = false;
@@ -4163,6 +4172,9 @@ void wxGrid::Init()
 
     m_extraWidth =
     m_extraHeight = 0;
+
+    m_scrollLineX = GRID_SCROLL_LINE_X;
+    m_scrollLineY = GRID_SCROLL_LINE_Y;
 }
 
 // ----------------------------------------------------------------------------
@@ -4312,16 +4324,16 @@ void wxGrid::CalcWindowSizes()
     int cw, ch;
     GetClientSize( &cw, &ch );
 
-    if ( m_cornerLabelWin->IsShown() )
+    if ( m_cornerLabelWin && m_cornerLabelWin->IsShown() )
         m_cornerLabelWin->SetSize( 0, 0, m_rowLabelWidth, m_colLabelHeight );
 
-    if ( m_colLabelWin->IsShown() )
+    if (  m_colLabelWin && m_colLabelWin->IsShown() )
         m_colLabelWin->SetSize( m_rowLabelWidth, 0, cw-m_rowLabelWidth, m_colLabelHeight);
 
-    if ( m_rowLabelWin->IsShown() )
+    if ( m_rowLabelWin && m_rowLabelWin->IsShown() )
         m_rowLabelWin->SetSize( 0, m_colLabelHeight, m_rowLabelWidth, ch-m_colLabelHeight);
 
-    if ( m_gridWin->IsShown() )
+    if ( m_gridWin && m_gridWin->IsShown() )
         m_gridWin->SetSize( m_rowLabelWidth, m_colLabelHeight, cw-m_rowLabelWidth, ch-m_colLabelHeight);
 }
 
@@ -5346,6 +5358,7 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
     XYToCell( x, y, coords );
 
     int cell_rows, cell_cols;
+    bool isFirstDrag = !m_isDragging;
     GetCellSize( coords.GetRow(), coords.GetCol(), &cell_rows, &cell_cols );
     if ((cell_rows < 0) || (cell_cols < 0))
     {
@@ -5396,6 +5409,19 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
                         m_selectingKeyboard = coords;
                     HighlightBlock ( m_selectingKeyboard, coords );
                 }
+                else if ( CanDragCell() )
+                {
+                    if ( isFirstDrag )
+                    {
+                        if ( m_selectingKeyboard == wxGridNoCellCoords)
+                            m_selectingKeyboard = coords;
+
+                        SendEvent( wxEVT_GRID_CELL_BEGIN_DRAG,
+                                   coords.GetRow(),
+                                   coords.GetCol(),
+                                   event );
+                    }
+                }
                 else
                 {
                     if ( !IsSelection() )
@@ -8871,14 +8897,24 @@ void wxGrid::SetDefaultCellFont( const wxFont& font )
     m_defaultCellAttr->SetFont(font);
 }
 
+
+// For editors and renderers the type registry takes precedence over the
+// default attr, so we need to register the new editor/renderer for the string
+// data type in order to make setting a default editor/renderer appear to
+// work correctly.
+
 void wxGrid::SetDefaultRenderer(wxGridCellRenderer *renderer)
 {
-    m_defaultCellAttr->SetRenderer(renderer);
+    RegisterDataType(wxGRID_VALUE_STRING,
+                     renderer,
+                     GetDefaultEditorForType(wxGRID_VALUE_STRING));
 }
 
 void wxGrid::SetDefaultEditor(wxGridCellEditor *editor)
 {
-    m_defaultCellAttr->SetEditor(editor);
+    RegisterDataType(wxGRID_VALUE_STRING,
+                     GetDefaultRendererForType(wxGRID_VALUE_STRING),
+                     editor);
 }
 
 // ----------------------------------------------------------------------------
@@ -9086,9 +9122,10 @@ wxGridCellAttr *wxGrid::GetCellAttr(int row, int col) const
 wxGridCellAttr *wxGrid::GetOrCreateCellAttr(int row, int col) const
 {
     wxGridCellAttr *attr = (wxGridCellAttr *)NULL;
+    bool canHave = ((wxGrid*)this)->CanHaveAttributes();
 
-    wxCHECK_MSG( m_table, attr,
-                  _T("we may only be called if CanHaveAttributes() returned true and then m_table should be !NULL") );
+    wxCHECK_MSG( canHave, attr, _T("Cell attributes not allowed"));
+    wxCHECK_MSG( m_table, attr, _T("must have a table") );
 
     attr = m_table->GetAttr(row, col, wxGridCellAttr::Cell);
     if ( !attr )
@@ -9395,6 +9432,10 @@ void wxGrid::EnableDragGridSize( bool enable )
     m_canDragGridSize = enable;
 }
 
+void wxGrid::EnableDragCell( bool enable )
+{
+    m_canDragCell = enable;
+}
 
 void wxGrid::SetDefaultRowSize( int height, bool resizeExistingRows )
 {
@@ -9504,26 +9545,30 @@ void wxGrid::SetColSize( int col, int width )
 void wxGrid::SetColMinimalWidth( int col, int width )
 {
     if (width > GetColMinimalAcceptableWidth()) {
-        m_colMinWidths[col] = width;
+        wxLongToLongHashMap::key_type key = (wxLongToLongHashMap::key_type)col;
+        m_colMinWidths[key] = width;
     }
 }
 
 void wxGrid::SetRowMinimalHeight( int row, int width )
 {
     if (width > GetRowMinimalAcceptableHeight()) {
-       m_rowMinHeights[row] = width;
+        wxLongToLongHashMap::key_type key = (wxLongToLongHashMap::key_type)row;
+        m_rowMinHeights[key] = width;
     }
 }
 
 int wxGrid::GetColMinimalWidth(int col) const
 {
-    wxLongToLongHashMap::const_iterator it = m_colMinWidths.find(col);
+    wxLongToLongHashMap::key_type key = (wxLongToLongHashMap::key_type)col;
+    wxLongToLongHashMap::const_iterator it = m_colMinWidths.find(key);
     return it != m_colMinWidths.end() ? (int)it->second : m_minAcceptableColWidth;
 }
 
 int wxGrid::GetRowMinimalHeight(int row) const
 {
-    wxLongToLongHashMap::const_iterator it = m_rowMinHeights.find(row);
+    wxLongToLongHashMap::key_type key = (wxLongToLongHashMap::key_type)row;
+    wxLongToLongHashMap::const_iterator it = m_rowMinHeights.find(key);
     return it != m_rowMinHeights.end() ? (int)it->second : m_minAcceptableRowHeight;
 }
 
@@ -9853,13 +9898,33 @@ wxSize wxGrid::DoGetBestSize() const
     width = self->SetOrCalcColumnSizes(true);
     height = self->SetOrCalcRowSizes(true);
 
+    if (!width) width=100;
+    if (!height) height=80;
+
+    // Round up to a multiple the scroll rate NOTE: this still doesn't get rid
+    // of the scrollbars, is there any magic incantaion for that?
+    int xpu, ypu;
+    GetScrollPixelsPerUnit(&xpu, &ypu);
+    if (xpu)
+        width  += 1 + xpu - (width  % xpu);
+    if (ypu)
+        height += 1 + ypu - (height % ypu);
+
+    // limit to 1/4 of the screen size
     int maxwidth, maxheight;
     wxDisplaySize( & maxwidth, & maxheight );
-
+    maxwidth /= 2;
+    maxheight /= 2;
     if ( width > maxwidth ) width = maxwidth;
     if ( height > maxheight ) height = maxheight;
 
-    return wxSize( width, height );
+
+    wxSize best(width, height);
+    // NOTE: This size should be cached, but first we need to add calls to
+    // InvalidateBestSize everywhere that could change the results of this
+    // calculation.
+    // CacheBestSize(size);
+    return best;
 }
 
 void wxGrid::Fit()