1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGrid and related classes
4 // Author: Michael Bedward (based on code by Julian Smart, Robin Dunn)
8 // Copyright: (c) Michael Bedward (mbedward@ozemail.com.au)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "grid.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
25 #if !defined(wxUSE_NEW_GRID) || !(wxUSE_NEW_GRID)
31 #include "wx/dcclient.h"
32 #include "wx/settings.h"
36 #include "wx/generic/grid.h"
39 //////////////////////////////////////////////////////////////////////
41 wxGridCellCoords
wxGridNoCellCoords( -1, -1 );
42 wxRect
wxGridNoCellRect( -1, -1, -1, -1 );
46 //////////////////////////////////////////////////////////////////////
48 // Abstract base class for grid data (the model)
50 IMPLEMENT_ABSTRACT_CLASS( wxGridTableBase
, wxObject
)
53 wxGridTableBase::wxGridTableBase()
56 m_view
= (wxGrid
*) NULL
;
59 wxGridTableBase::~wxGridTableBase()
64 bool wxGridTableBase::InsertRows( size_t pos
, size_t numRows
)
66 wxLogWarning( wxT("Called grid table class function InsertRows(pos=%d, N=%d)\n"
67 "but your derived table class does not override this function"),
73 bool wxGridTableBase::AppendRows( size_t numRows
)
75 wxLogWarning( wxT("Called grid table class function AppendRows(N=%d)\n"
76 "but your derived table class does not override this function"),
82 bool wxGridTableBase::DeleteRows( size_t pos
, size_t numRows
)
84 wxLogWarning( wxT("Called grid table class function DeleteRows(pos=%d, N=%d)\n"
85 "but your derived table class does not override this function"),
91 bool wxGridTableBase::InsertCols( size_t pos
, size_t numCols
)
93 wxLogWarning( wxT("Called grid table class function InsertCols(pos=%d, N=%d)\n"
94 "but your derived table class does not override this function"),
100 bool wxGridTableBase::AppendCols( size_t numCols
)
102 wxLogWarning( wxT("Called grid table class function AppendCols(N=%d)\n"
103 "but your derived table class does not override this function"),
109 bool wxGridTableBase::DeleteCols( size_t pos
, size_t numCols
)
111 wxLogWarning( wxT("Called grid table class function DeleteCols(pos=%d, N=%d)\n"
112 "but your derived table class does not override this function"),
119 wxString
wxGridTableBase::GetRowLabelValue( int row
)
126 wxString
wxGridTableBase::GetColLabelValue( int col
)
128 // default col labels are:
129 // cols 0 to 25 : A-Z
130 // cols 26 to 675 : AA-ZZ
137 s
+= ('A' + (char)( col%26
));
139 if ( col
< 0 ) break;
142 // reverse the string...
144 for ( i
= 0; i
< n
; i
++ )
154 //////////////////////////////////////////////////////////////////////
156 // Message class for the grid table to send requests and notifications
160 wxGridTableMessage::wxGridTableMessage()
162 m_table
= (wxGridTableBase
*) NULL
;
168 wxGridTableMessage::wxGridTableMessage( wxGridTableBase
*table
, int id
,
169 int commandInt1
, int commandInt2
)
173 m_comInt1
= commandInt1
;
174 m_comInt2
= commandInt2
;
179 //////////////////////////////////////////////////////////////////////
181 // A basic grid table for string data. An object of this class will
182 // created by wxGrid if you don't specify an alternative table class.
186 // this is a magic incantation which must be done!
187 #include "wx/arrimpl.cpp"
189 WX_DEFINE_OBJARRAY(wxGridStringArray
)
191 IMPLEMENT_DYNAMIC_CLASS( wxGridStringTable
, wxGridTableBase
)
193 wxGridStringTable::wxGridStringTable()
198 wxGridStringTable::wxGridStringTable( int numRows
, int numCols
)
203 m_data
.Alloc( numRows
);
207 for ( col
= 0; col
< numCols
; col
++ )
209 sa
.Add( wxEmptyString
);
212 for ( row
= 0; row
< numRows
; row
++ )
218 wxGridStringTable::~wxGridStringTable()
222 long wxGridStringTable::GetNumberRows()
224 return m_data
.GetCount();
227 long wxGridStringTable::GetNumberCols()
229 if ( m_data
.GetCount() > 0 )
230 return m_data
[0].GetCount();
235 wxString
wxGridStringTable::GetValue( int row
, int col
)
237 // TODO: bounds checking
239 return m_data
[row
][col
];
242 void wxGridStringTable::SetValue( int row
, int col
, const wxString
& s
)
244 // TODO: bounds checking
246 m_data
[row
][col
] = s
;
249 bool wxGridStringTable::IsEmptyCell( int row
, int col
)
251 // TODO: bounds checking
253 return (m_data
[row
][col
] == wxEmptyString
);
257 void wxGridStringTable::Clear()
260 int numRows
, numCols
;
262 numRows
= m_data
.GetCount();
265 numCols
= m_data
[0].GetCount();
267 for ( row
= 0; row
< numRows
; row
++ )
269 for ( col
= 0; col
< numCols
; col
++ )
271 m_data
[row
][col
] = wxEmptyString
;
278 bool wxGridStringTable::InsertRows( size_t pos
, size_t numRows
)
282 size_t curNumRows
= m_data
.GetCount();
283 size_t curNumCols
= ( curNumRows
> 0 ? m_data
[0].GetCount() : 0 );
285 if ( pos
>= curNumRows
)
287 return AppendRows( numRows
);
291 sa
.Alloc( curNumCols
);
292 for ( col
= 0; col
< curNumCols
; col
++ )
294 sa
.Add( wxEmptyString
);
297 for ( row
= pos
; row
< pos
+ numRows
; row
++ )
299 m_data
.Insert( sa
, row
);
304 wxGridTableMessage
msg( this,
305 wxGRIDTABLE_NOTIFY_ROWS_INSERTED
,
309 GetView()->ProcessTableMessage( msg
);
315 bool wxGridStringTable::AppendRows( size_t numRows
)
319 size_t curNumRows
= m_data
.GetCount();
320 size_t curNumCols
= ( curNumRows
> 0 ? m_data
[0].GetCount() : 0 );
323 if ( curNumCols
> 0 )
325 sa
.Alloc( curNumCols
);
326 for ( col
= 0; col
< curNumCols
; col
++ )
328 sa
.Add( wxEmptyString
);
332 for ( row
= 0; row
< numRows
; row
++ )
339 wxGridTableMessage
msg( this,
340 wxGRIDTABLE_NOTIFY_ROWS_APPENDED
,
343 GetView()->ProcessTableMessage( msg
);
349 bool wxGridStringTable::DeleteRows( size_t pos
, size_t numRows
)
353 size_t curNumRows
= m_data
.GetCount();
355 if ( pos
>= curNumRows
)
357 wxLogError( wxT("Called wxGridStringTable::DeleteRows(pos=%d, N=%d)...\n"
358 "Pos value is invalid for present table with %d rows"),
359 pos
, numRows
, curNumRows
);
363 if ( numRows
> curNumRows
- pos
)
365 numRows
= curNumRows
- pos
;
368 if ( numRows
>= curNumRows
)
370 m_data
.Empty(); // don't release memory just yet
374 for ( n
= 0; n
< numRows
; n
++ )
376 m_data
.Remove( pos
);
382 wxGridTableMessage
msg( this,
383 wxGRIDTABLE_NOTIFY_ROWS_DELETED
,
387 GetView()->ProcessTableMessage( msg
);
393 bool wxGridStringTable::InsertCols( size_t pos
, size_t numCols
)
397 size_t curNumRows
= m_data
.GetCount();
398 size_t curNumCols
= ( curNumRows
> 0 ? m_data
[0].GetCount() : 0 );
400 if ( pos
>= curNumCols
)
402 return AppendCols( numCols
);
405 for ( row
= 0; row
< curNumRows
; row
++ )
407 for ( col
= pos
; col
< pos
+ numCols
; col
++ )
409 m_data
[row
].Insert( wxEmptyString
, col
);
415 wxGridTableMessage
msg( this,
416 wxGRIDTABLE_NOTIFY_COLS_INSERTED
,
420 GetView()->ProcessTableMessage( msg
);
426 bool wxGridStringTable::AppendCols( size_t numCols
)
430 size_t curNumRows
= m_data
.GetCount();
433 // TODO: something better than this ?
435 wxLogError( wxT("Unable to append cols to a grid table with no rows.\n"
436 "Call AppendRows() first") );
440 for ( row
= 0; row
< curNumRows
; row
++ )
442 for ( n
= 0; n
< numCols
; n
++ )
444 m_data
[row
].Add( wxEmptyString
);
450 wxGridTableMessage
msg( this,
451 wxGRIDTABLE_NOTIFY_COLS_APPENDED
,
454 GetView()->ProcessTableMessage( msg
);
460 bool wxGridStringTable::DeleteCols( size_t pos
, size_t numCols
)
464 size_t curNumRows
= m_data
.GetCount();
465 size_t curNumCols
= ( curNumRows
> 0 ? m_data
[0].GetCount() : 0 );
467 if ( pos
>= curNumCols
)
469 wxLogError( wxT("Called wxGridStringTable::DeleteCols(pos=%d, N=%d)...\n"
470 "Pos value is invalid for present table with %d cols"),
471 pos
, numCols
, curNumCols
);
475 if ( numCols
> curNumCols
- pos
)
477 numCols
= curNumCols
- pos
;
480 for ( row
= 0; row
< curNumRows
; row
++ )
482 if ( numCols
>= curNumCols
)
488 for ( n
= 0; n
< numCols
; n
++ )
490 m_data
[row
].Remove( pos
);
497 wxGridTableMessage
msg( this,
498 wxGRIDTABLE_NOTIFY_COLS_DELETED
,
502 GetView()->ProcessTableMessage( msg
);
508 wxString
wxGridStringTable::GetRowLabelValue( int row
)
510 if ( row
> (int)(m_rowLabels
.GetCount()) - 1 )
512 // using default label
514 return wxGridTableBase::GetRowLabelValue( row
);
518 return m_rowLabels
[ row
];
522 wxString
wxGridStringTable::GetColLabelValue( int col
)
524 if ( col
> (int)(m_colLabels
.GetCount()) - 1 )
526 // using default label
528 return wxGridTableBase::GetColLabelValue( col
);
532 return m_colLabels
[ col
];
536 void wxGridStringTable::SetRowLabelValue( int row
, const wxString
& value
)
538 if ( row
> (int)(m_rowLabels
.GetCount()) - 1 )
540 int n
= m_rowLabels
.GetCount();
542 for ( i
= n
; i
<= row
; i
++ )
544 m_rowLabels
.Add( wxGridTableBase::GetRowLabelValue(i
) );
548 m_rowLabels
[row
] = value
;
551 void wxGridStringTable::SetColLabelValue( int col
, const wxString
& value
)
553 if ( col
> (int)(m_colLabels
.GetCount()) - 1 )
555 int n
= m_colLabels
.GetCount();
557 for ( i
= n
; i
<= col
; i
++ )
559 m_colLabels
.Add( wxGridTableBase::GetColLabelValue(i
) );
563 m_colLabels
[col
] = value
;
569 //////////////////////////////////////////////////////////////////////
571 IMPLEMENT_DYNAMIC_CLASS( wxGridTextCtrl
, wxTextCtrl
)
573 BEGIN_EVENT_TABLE( wxGridTextCtrl
, wxTextCtrl
)
574 EVT_KEY_DOWN( wxGridTextCtrl::OnKeyDown
)
578 wxGridTextCtrl::wxGridTextCtrl( wxWindow
*par
,
581 const wxString
& value
,
585 : wxTextCtrl( par
, id
, value
, pos
, size
, style
)
587 m_isCellControl
= isCellControl
;
591 void wxGridTextCtrl::OnKeyDown( wxKeyEvent
& ev
)
593 switch ( ev
.KeyCode() )
596 ((wxGrid
*)GetParent())->SetEditControlValue( startValue
);
597 SetInsertionPointEnd();
607 if ( m_isCellControl
)
609 // send the event to the parent grid, skipping the
610 // event if nothing happens
612 ev
.Skip( !GetParent()->ProcessEvent( ev
) );
616 // default text control response within the top edit
625 if ( m_isCellControl
)
627 // send the event to the parent grid, skipping the
628 // event if nothing happens
630 ev
.Skip( !GetParent()->ProcessEvent( ev
) );
634 // default text control response within the top edit
646 void wxGridTextCtrl::SetStartValue( const wxString
& s
)
649 wxTextCtrl::SetValue( s
.c_str() );
653 //////////////////////////////////////////////////////////////////////
655 IMPLEMENT_DYNAMIC_CLASS( wxGrid
, wxPanel
)
658 BEGIN_EVENT_TABLE( wxGrid
, wxPanel
)
659 EVT_PAINT( wxGrid::OnPaint
)
660 EVT_SIZE( wxGrid::OnSize
)
661 EVT_MOUSE_EVENTS( wxGrid::OnMouse
)
662 EVT_KEY_DOWN( wxGrid::OnKeyDown
)
663 EVT_TEXT( wxGRID_CELLCTRL
, wxGrid::OnText
)
664 EVT_TEXT( wxGRID_TOPCTRL
, wxGrid::OnText
)
665 EVT_COMMAND_SCROLL( wxGRID_HORIZSCROLL
, wxGrid::OnGridScroll
)
666 EVT_COMMAND_SCROLL( wxGRID_VERTSCROLL
, wxGrid::OnGridScroll
)
677 // ----- internal init and update functions
680 void wxGrid::Create()
682 m_table
= (wxGridTableBase
*) NULL
;
683 m_topEditCtrl
= (wxWindow
*) NULL
;
684 m_cellEditCtrl
= (wxWindow
*) NULL
;
685 m_horizScrollBar
= (wxScrollBar
*) NULL
;
686 m_vertScrollBar
= (wxScrollBar
*) NULL
;
700 // TODO: perhaps have a style flag for control panel
702 m_topEditCtrlEnabled
= FALSE
;
703 m_topEditCtrl
= new wxGridTextCtrl( this,
708 wxSize(WXGRID_DEFAULT_TOPEDIT_WIDTH
,
709 WXGRID_DEFAULT_TOPEDIT_HEIGHT
),
711 m_topEditCtrl
->Show( FALSE
);
713 if ( m_numRows
<= 0 )
714 m_numRows
= WXGRID_DEFAULT_NUMBER_ROWS
;
716 if ( m_numCols
<= 0 )
717 m_numCols
= WXGRID_DEFAULT_NUMBER_COLS
;
719 m_rowLabelWidth
= WXGRID_DEFAULT_ROW_LABEL_WIDTH
;
720 m_colLabelHeight
= WXGRID_DEFAULT_COL_LABEL_HEIGHT
;
722 // default labels are pale grey with black text
724 m_labelBackgroundColour
= wxColour( 192, 192, 192 );
725 m_labelTextColour
= wxColour( 0, 0, 0 );
727 // TODO: something better than this ?
729 m_labelFont
= this->GetFont();
730 m_labelFont
.SetWeight( m_labelFont
.GetWeight() + 2 );
732 m_rowLabelHorizAlign
= wxLEFT
;
733 m_rowLabelVertAlign
= wxCENTRE
;
735 m_colLabelHorizAlign
= wxCENTRE
;
736 m_colLabelVertAlign
= wxTOP
;
738 m_defaultRowHeight
= WXGRID_DEFAULT_ROW_HEIGHT
;
739 m_defaultColWidth
= WXGRID_DEFAULT_COL_WIDTH
;
741 m_rowHeights
.Alloc( m_numRows
);
742 m_rowBottoms
.Alloc( m_numRows
);
744 for ( i
= 0; i
< m_numRows
; i
++ )
746 m_rowHeights
.Add( m_defaultRowHeight
);
747 m_rowBottoms
.Add( 0 ); // set by CalcDimensions()
749 m_sumRowHeights
= m_defaultRowHeight
* m_numRows
;
751 m_colWidths
.Alloc( m_numCols
);
752 m_colRights
.Alloc( m_numRows
);
754 for ( i
= 0; i
< m_numCols
; i
++ )
756 m_colWidths
.Add( m_defaultColWidth
);
757 m_colRights
.Add( 0 ); // set by CalcDimensions()
759 m_sumColWidths
= m_defaultColWidth
* m_numCols
;
761 // TODO: improve this ?
763 m_defaultCellFont
= this->GetFont();
765 m_gridLineColour
= wxColour( 0, 0, 255 );
766 m_gridLinesEnabled
= TRUE
;
768 m_scrollBarWidth
= WXGRID_DEFAULT_SCROLLBAR_WIDTH
;
770 m_horizScrollBar
= new wxScrollBar( this,
776 m_vertScrollBar
= new wxScrollBar( this,
783 m_wholeColsVisible
= 0;
784 m_wholeRowsVisible
= 0;
787 m_inOnKeyDown
= FALSE
;
790 m_cursorMode
= WXGRID_CURSOR_DEFAULT
;
793 m_isDragging
= FALSE
;
795 m_rowResizeCursor
= wxCursor( wxCURSOR_SIZENS
);
796 m_colResizeCursor
= wxCursor( wxCURSOR_SIZEWE
);
798 m_currentCellCoords
= wxGridNoCellCoords
;
799 m_currentCellHighlighted
= FALSE
;
801 m_selectedTopLeft
= wxGridNoCellCoords
;
802 m_selectedBottomRight
= wxGridNoCellCoords
;
804 m_editable
= TRUE
; // default for whole grid
806 // TODO: extend this to other types of controls
808 m_cellEditCtrl
= new wxGridTextCtrl( this,
815 , wxTE_MULTILINE
| wxTE_NO_VSCROLL
819 m_cellEditCtrl
->Show( FALSE
);
820 m_cellEditCtrlEnabled
= TRUE
;
821 m_editCtrlType
= wxGRID_TEXTCTRL
;
823 // This is here in case OnSize does not get called when the grid is
830 void wxGrid::CalcDimensions()
834 if ( IsTopEditControlEnabled() )
837 m_topEditCtrl
->GetSize( &ctrlW
, &ctrlH
);
846 // check to see if either of the scroll bars are required
849 GetClientSize(&cw
, &ch
);
851 // begin by assuming that we don't need either scroll bar
853 int vertScrollBarWidth
= 0;
854 int horizScrollBarHeight
= 0;
856 // Each scroll bar needs to eventually know if the other one is
857 // required in deciding whether or not it is also required - hence
858 // this loop. A bit inelegant but simple and it works.
861 for ( check
= 0; check
< 2; check
++ )
863 if ( m_top
+ m_colLabelHeight
+ m_sumRowHeights
+ horizScrollBarHeight
> ch
)
865 vertScrollBarWidth
= m_scrollBarWidth
;
868 if ( m_left
+ m_rowLabelWidth
+ m_sumColWidths
+ vertScrollBarWidth
> cw
)
870 horizScrollBarHeight
= m_scrollBarWidth
;
875 // if the window has been resized while scrolled then the scroll
876 // position might need to be adjusted...
878 bool adjustScrollPos
= FALSE
;
879 if ( !vertScrollBarWidth
)
883 adjustScrollPos
= TRUE
;
887 if ( !horizScrollBarHeight
)
891 adjustScrollPos
= TRUE
;
897 // calculate the coords of row bottom edges and col right edges
899 int bottom
= m_top
+ m_colLabelHeight
;
900 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
902 bottom
+= m_rowHeights
[i
];
903 m_rowBottoms
[i
] = bottom
;
906 int right
= m_left
+ m_rowLabelWidth
;
907 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
909 right
+= m_colWidths
[i
];
910 m_colRights
[i
] = right
;
914 // check how many rows and cols are visible
916 m_wholeRowsVisible
= 0;
919 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
921 // A partial row doesn't count, we still have to scroll to
922 // see the rest of it
923 if ( m_rowBottoms
[i
] + horizScrollBarHeight
> ch
) break;
925 m_wholeRowsVisible
++ ;
929 m_wholeColsVisible
= 0;
932 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
934 // A partial col doesn't count, we still have to scroll to
935 // see the rest of it
936 if ( m_colRights
[i
] + vertScrollBarWidth
> cw
) break;
938 m_wholeColsVisible
++ ;
942 if ( m_vertScrollBar
)
944 if ( !vertScrollBarWidth
)
946 m_vertScrollBar
->Show(FALSE
);
950 m_vertScrollBar
->Show(TRUE
);
951 m_vertScrollBar
->SetScrollbar(
953 wxMax(m_wholeRowsVisible
, 1),
954 (m_wholeRowsVisible
== 0 ? 1 : m_numRows
),
955 wxMax(m_wholeRowsVisible
, 1) );
957 m_vertScrollBar
->SetSize( cw
- m_scrollBarWidth
,
960 ch
- m_top
- horizScrollBarHeight
);
964 if ( m_horizScrollBar
)
966 if ( !horizScrollBarHeight
)
968 m_horizScrollBar
->Show(FALSE
);
972 m_horizScrollBar
->Show(TRUE
);
974 m_horizScrollBar
->SetScrollbar(
976 wxMax(m_wholeColsVisible
, 1),
977 (m_wholeColsVisible
== 0) ? 1 : m_numCols
,
978 wxMax(m_wholeColsVisible
, 1) );
980 m_horizScrollBar
->SetSize( m_left
,
981 ch
- m_scrollBarWidth
,
982 cw
- m_left
- vertScrollBarWidth
,
987 m_bottom
= m_right
= 0;
990 m_bottom
= wxMin( m_rowBottoms
[m_numRows
-1],
991 ch
- horizScrollBarHeight
);
995 m_right
= wxMin( m_colRights
[m_numCols
-1],
996 cw
- vertScrollBarWidth
);
999 // if the scroll position was adjusted (due to a window resize)
1000 // ensure that the cell highlight and edit control are displayed
1003 if ( adjustScrollPos
) SelectCell( m_currentCellCoords
);
1007 bool wxGrid::IsOnScreen()
1010 GetClientSize( &cw
, &ch
);
1015 // this is called when the grid table sends a message to say that it
1016 // has been redimensioned
1018 bool wxGrid::Redimension( wxGridTableMessage
& msg
)
1022 switch ( msg
.GetId() )
1024 case wxGRIDTABLE_NOTIFY_ROWS_INSERTED
:
1026 size_t pos
= msg
.GetCommandInt();
1027 int numRows
= msg
.GetCommandInt2();
1028 for ( i
= 0; i
< numRows
; i
++ )
1030 m_rowHeights
.Insert( m_defaultRowHeight
, pos
);
1031 m_rowBottoms
.Insert( 0, pos
);
1032 m_sumRowHeights
+= m_defaultRowHeight
;
1034 m_numRows
+= numRows
;
1039 case wxGRIDTABLE_NOTIFY_ROWS_APPENDED
:
1041 int numRows
= msg
.GetCommandInt();
1042 for ( i
= 0; i
< numRows
; i
++ )
1044 m_rowHeights
.Add( m_defaultRowHeight
);
1045 m_rowBottoms
.Add( 0 );
1046 m_sumRowHeights
+= m_defaultRowHeight
;
1048 m_numRows
+= numRows
;
1053 case wxGRIDTABLE_NOTIFY_ROWS_DELETED
:
1055 size_t pos
= msg
.GetCommandInt();
1056 int numRows
= msg
.GetCommandInt2();
1057 for ( i
= 0; i
< numRows
; i
++ )
1059 m_sumRowHeights
-= m_rowHeights
[ pos
];
1060 m_rowHeights
.Remove( pos
);
1061 m_rowBottoms
.Remove( pos
);
1063 m_numRows
-= numRows
;
1065 // TODO: improve these adjustments...
1067 if ( m_scrollPosY
>= m_numRows
)
1073 m_colWidths
.Clear();
1074 m_colRights
.Clear();
1075 m_currentCellCoords
= wxGridNoCellCoords
;
1077 else if ( m_currentCellCoords
.GetRow() >= m_numRows
)
1079 m_currentCellCoords
.Set( 0, 0 );
1085 case wxGRIDTABLE_NOTIFY_COLS_INSERTED
:
1087 size_t pos
= msg
.GetCommandInt();
1088 int numCols
= msg
.GetCommandInt2();
1089 for ( i
= 0; i
< numCols
; i
++ )
1091 m_colWidths
.Insert( m_defaultColWidth
, pos
);
1092 m_colRights
.Insert( 0, pos
);
1093 m_sumColWidths
+= m_defaultColWidth
;
1095 m_numCols
+= numCols
;
1100 case wxGRIDTABLE_NOTIFY_COLS_APPENDED
:
1102 int numCols
= msg
.GetCommandInt();
1103 for ( i
= 0; i
< numCols
; i
++ )
1105 m_colWidths
.Add( m_defaultColWidth
);
1106 m_colRights
.Add( 0 );
1107 m_sumColWidths
+= m_defaultColWidth
;
1109 m_numCols
+= numCols
;
1114 case wxGRIDTABLE_NOTIFY_COLS_DELETED
:
1116 size_t pos
= msg
.GetCommandInt();
1117 int numCols
= msg
.GetCommandInt2();
1118 for ( i
= 0; i
< numCols
; i
++ )
1120 m_sumColWidths
-= m_colWidths
[ pos
];
1121 m_colWidths
.Remove( pos
);
1122 m_colRights
.Remove( pos
);
1124 m_numCols
-= numCols
;
1126 // TODO: improve these adjustments...
1128 if ( m_scrollPosX
>= m_numCols
)
1133 #if 0 // leave the row alone here so that AppendCols will work subsequently
1135 m_rowHeights
.Clear();
1136 m_rowBottoms
.Clear();
1138 m_currentCellCoords
= wxGridNoCellCoords
;
1140 else if ( m_currentCellCoords
.GetCol() >= m_numCols
)
1142 m_currentCellCoords
.Set( 0, 0 );
1154 // ----- event handlers
1157 // Generate a grid event based on a mouse event and
1158 // return the result of ProcessEvent()
1160 bool wxGrid::SendEvent( const wxEventType type
,
1162 wxMouseEvent
& mouseEv
)
1164 if ( type
== EVT_GRID_ROW_SIZE
||
1165 type
== EVT_GRID_COL_SIZE
)
1167 int rowOrCol
= (row
== -1 ? col
: row
);
1169 wxGridSizeEvent
gridEvt( GetId(),
1173 mouseEv
.GetX(), mouseEv
.GetY(),
1174 mouseEv
.ControlDown(),
1175 mouseEv
.ShiftDown(),
1177 mouseEv
.MetaDown() );
1179 return GetEventHandler()->ProcessEvent(gridEvt
);
1181 else if ( type
== EVT_GRID_RANGE_SELECT
)
1183 wxGridRangeSelectEvent
gridEvt( GetId(),
1187 m_selectedBottomRight
,
1188 mouseEv
.ControlDown(),
1189 mouseEv
.ShiftDown(),
1191 mouseEv
.MetaDown() );
1193 return GetEventHandler()->ProcessEvent(gridEvt
);
1197 wxGridEvent
gridEvt( GetId(),
1201 mouseEv
.GetX(), mouseEv
.GetY(),
1202 mouseEv
.ControlDown(),
1203 mouseEv
.ShiftDown(),
1205 mouseEv
.MetaDown() );
1207 return GetEventHandler()->ProcessEvent(gridEvt
);
1212 // Generate a grid event of specified type and return the result
1213 // of ProcessEvent().
1215 bool wxGrid::SendEvent( const wxEventType type
,
1218 if ( type
== EVT_GRID_ROW_SIZE
||
1219 type
== EVT_GRID_COL_SIZE
)
1221 int rowOrCol
= (row
== -1 ? col
: row
);
1223 wxGridSizeEvent
gridEvt( GetId(),
1228 return GetEventHandler()->ProcessEvent(gridEvt
);
1232 wxGridEvent
gridEvt( GetId(),
1237 return GetEventHandler()->ProcessEvent(gridEvt
);
1242 void wxGrid::OnPaint( wxPaintEvent
& WXUNUSED(ev
) )
1244 wxPaintDC
dc( this );
1246 if ( !m_batchCount
)
1248 // define a clipping region to avoid painting over the scroll bars
1251 if ( m_vertScrollBar
&& m_vertScrollBar
->IsShown() )
1252 vs
= m_scrollBarWidth
;
1255 if ( m_horizScrollBar
&& m_horizScrollBar
->IsShown() )
1256 hs
= m_scrollBarWidth
;
1259 GetClientSize( &cw
, &ch
);
1260 dc
.SetClippingRegion( 0, 0, cw
- vs
, ch
- hs
);
1262 HideCurrentCellHighlight( dc
);
1264 DrawLabelAreas( dc
);
1265 DrawColLabels( dc
);
1266 DrawRowLabels( dc
);
1268 DrawGridLines( dc
);
1271 // TODO: something more elegant than this...
1275 if ( m_currentCellCoords
== wxGridNoCellCoords
)
1276 m_currentCellCoords
.Set(0, 0);
1278 SetEditControlValue();
1279 ShowCellEditControl();
1280 m_firstPaint
= FALSE
;
1283 ShowCurrentCellHighlight( dc
);
1285 dc
.DestroyClippingRegion();
1290 void wxGrid::OnSize( wxSizeEvent
& WXUNUSED(ev
) )
1292 if ( m_created
) CalcDimensions();
1296 void wxGrid::OnMouse( wxMouseEvent
& ev
)
1302 // ------------------------------------------------------------
1306 if ( ev
.Dragging() )
1308 m_isDragging
= TRUE
;
1310 if ( ev
.LeftIsDown() )
1312 switch( m_cursorMode
)
1314 case WXGRID_CURSOR_SELECT_CELL
:
1316 wxGridCellCoords cellCoords
;
1317 XYToCell( x
, y
, cellCoords
);
1318 if ( cellCoords
!= wxGridNoCellCoords
)
1320 if ( !IsSelection() )
1322 SelectBlock( cellCoords
, cellCoords
);
1326 // check for the mouse being outside the cell area
1327 // (we still want to let the user grow the selected block)
1329 if ( cellCoords
.GetCol() == -1 )
1332 cellCoords
.SetCol( m_numCols
-1 );
1334 cellCoords
.SetCol( m_scrollPosX
);
1337 if ( cellCoords
.GetRow() == -1 )
1339 if ( y
>= m_bottom
)
1340 cellCoords
.SetRow( m_numRows
-1 );
1342 cellCoords
.SetRow( m_scrollPosY
);
1345 if ( !IsInSelection( cellCoords
) )
1346 SelectBlock( m_currentCellCoords
, cellCoords
);
1352 case WXGRID_CURSOR_RESIZE_ROW
:
1354 wxClientDC
dc(this);
1355 dc
.SetLogicalFunction(wxXOR
);
1356 if ( m_dragLastPos
>= 0 )
1358 dc
.DrawLine( m_left
, m_dragLastPos
,
1359 m_right
, m_dragLastPos
);
1361 dc
.DrawLine( m_left
, ev
.GetY(),
1362 m_right
, ev
.GetY());
1364 m_dragLastPos
= ev
.GetY();
1368 case WXGRID_CURSOR_RESIZE_COL
:
1370 wxClientDC
dc(this);
1371 dc
.SetLogicalFunction(wxINVERT
);
1372 if ( m_dragLastPos
>= 0 )
1374 dc
.DrawLine( m_dragLastPos
, m_top
,
1375 m_dragLastPos
, m_bottom
);
1377 dc
.DrawLine( ev
.GetX(), m_top
,
1378 ev
.GetX(), m_bottom
);
1380 m_dragLastPos
= ev
.GetX();
1384 case WXGRID_CURSOR_SELECT_ROW
:
1386 if ( (row
= YToRow( y
)) >= 0 &&
1387 !IsInSelection( row
, 0 ) )
1389 SelectRow( row
, TRUE
);
1394 case WXGRID_CURSOR_SELECT_COL
:
1396 if ( (col
= XToCol( x
)) >= 0 &&
1397 !IsInSelection( 0, col
) )
1399 SelectCol( col
, TRUE
);
1408 m_isDragging
= FALSE
;
1410 // ------------------------------------------------------------
1412 // Left mouse button down
1414 if ( ev
.LeftDown() )
1418 wxGridCellCoords cellCoords
;
1420 switch( XYToArea( x
, y
) )
1422 case WXGRID_ROWLABEL
:
1424 // don't send a label click event for a hit on the
1425 // edge of the row label - this is probably the user
1426 // wanting to resize the row
1428 if ( YToEdgeOfRow(y
) < 0 )
1431 if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK
, row
, col
, ev
) )
1433 SelectRow( row
, ev
.ShiftDown() );
1434 m_cursorMode
= WXGRID_CURSOR_SELECT_ROW
;
1440 case WXGRID_COLLABEL
:
1442 // don't send a label click event for a hit on the
1443 // edge of the col label - this is probably the user
1444 // wanting to resize the col
1446 if ( XToEdgeOfCol(x
) < 0 )
1449 if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK
, row
, col
, ev
) )
1451 SelectCol( col
, ev
.ShiftDown() );
1452 m_cursorMode
= WXGRID_CURSOR_SELECT_COL
;
1458 case WXGRID_CORNERLABEL
:
1460 // leave both row and col as -1
1462 if ( !SendEvent( EVT_GRID_LABEL_LEFT_CLICK
, row
, col
, ev
) )
1471 XYToCell( x
, y
, cellCoords
);
1472 if ( !SendEvent( EVT_GRID_CELL_LEFT_CLICK
,
1473 cellCoords
.GetRow(),
1474 cellCoords
.GetCol(),
1477 MakeCellVisible( cellCoords
);
1478 SelectCell( cellCoords
);
1485 wxLogMessage( "outside grid area" );
1490 // ------------------------------------------------------------
1492 // Left mouse button double click
1494 else if ( ev
.LeftDClick() )
1498 wxGridCellCoords cellCoords
;
1500 switch( XYToArea( x
, y
) )
1502 case WXGRID_ROWLABEL
:
1504 // don't send a label click event for a hit on the
1505 // edge of the row label - this is probably the user
1506 // wanting to resize the row
1508 if ( YToEdgeOfRow(y
) < 0 )
1511 SendEvent( EVT_GRID_LABEL_LEFT_DCLICK
, row
, col
, ev
);
1516 case WXGRID_COLLABEL
:
1518 // don't send a label click event for a hit on the
1519 // edge of the col label - this is probably the user
1520 // wanting to resize the col
1522 if ( XToEdgeOfCol(x
) < 0 )
1525 SendEvent( EVT_GRID_LABEL_LEFT_DCLICK
, row
, col
, ev
);
1530 case WXGRID_CORNERLABEL
:
1532 // leave both row and col as -1
1534 SendEvent( EVT_GRID_LABEL_LEFT_DCLICK
, row
, col
, ev
);
1540 XYToCell( x
, y
, cellCoords
);
1541 SendEvent( EVT_GRID_CELL_LEFT_DCLICK
,
1542 cellCoords
.GetRow(),
1543 cellCoords
.GetCol(),
1550 wxLogMessage( "outside grid area" );
1555 // ------------------------------------------------------------
1557 // Left mouse button released
1559 else if ( ev
.LeftUp() )
1561 switch ( m_cursorMode
)
1563 case WXGRID_CURSOR_RESIZE_ROW
:
1565 if ( m_dragLastPos
>= 0 )
1567 // erase the last line and resize the row
1569 wxClientDC
dc( this );
1570 dc
.SetLogicalFunction( wxINVERT
);
1571 dc
.DrawLine( m_left
, m_dragLastPos
,
1572 m_right
, m_dragLastPos
);
1573 HideCellEditControl();
1574 int top
= m_top
+ m_colLabelHeight
;
1575 if ( m_dragRowOrCol
> 0 )
1576 top
= m_rowBottoms
[m_dragRowOrCol
-1];
1578 m_sumRowHeights
-= m_rowHeights
[ m_dragRowOrCol
];
1579 m_rowHeights
[m_dragRowOrCol
] = wxMax( ev
.GetY() - top
,
1580 WXGRID_MIN_ROW_HEIGHT
);
1581 m_sumRowHeights
+= m_rowHeights
[ m_dragRowOrCol
];
1583 ShowCellEditControl();
1586 // Note: we are ending the event *after* doing
1587 // default processing in this case
1589 SendEvent( EVT_GRID_ROW_SIZE
, m_dragRowOrCol
, -1, ev
);
1594 case WXGRID_CURSOR_RESIZE_COL
:
1596 if ( m_dragLastPos
>= 0 )
1598 // erase the last line and resize the col
1600 wxClientDC
dc( this );
1601 dc
.SetLogicalFunction( wxINVERT
);
1602 dc
.DrawLine( m_left
, m_dragLastPos
,
1603 m_right
, m_dragLastPos
);
1604 HideCellEditControl();
1605 int left
= m_left
+ m_rowLabelWidth
;
1606 if ( m_dragRowOrCol
> 0 )
1607 left
= m_colRights
[m_dragRowOrCol
-1];
1609 m_sumColWidths
-= m_colWidths
[m_dragRowOrCol
];
1610 m_colWidths
[m_dragRowOrCol
] = wxMax( ev
.GetX() - left
,
1611 WXGRID_MIN_COL_WIDTH
);
1612 m_sumColWidths
+= m_colWidths
[m_dragRowOrCol
];
1615 ShowCellEditControl();
1618 // Note: we are ending the event *after* doing
1619 // default processing in this case
1621 SendEvent( EVT_GRID_COL_SIZE
, -1, m_dragRowOrCol
, ev
);
1626 case WXGRID_CURSOR_SELECT_CELL
:
1628 if ( IsSelection() )
1630 // Note: we are ending the event *after* doing
1631 // default processing in this case
1633 SendEvent( EVT_GRID_RANGE_SELECT
, -1, -1, ev
);
1641 // ------------------------------------------------------------
1643 // Right mouse button down
1645 else if ( ev
.RightDown() )
1649 wxGridCellCoords cellCoords
;
1651 switch( XYToArea( x
, y
) )
1654 case WXGRID_ROWLABEL
:
1657 if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK
, row
, col
, ev
) )
1659 // TODO: default processing ?
1664 case WXGRID_COLLABEL
:
1667 if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK
, row
, col
, ev
) )
1669 // TODO: default processing ?
1674 case WXGRID_CORNERLABEL
:
1676 // leave both row and col as -1
1678 if ( !SendEvent( EVT_GRID_LABEL_RIGHT_CLICK
, row
, col
, ev
) )
1680 // TODO: default processing ?
1687 XYToCell( x
, y
, cellCoords
);
1688 if ( !SendEvent( EVT_GRID_CELL_RIGHT_CLICK
,
1689 cellCoords
.GetRow(),
1690 cellCoords
.GetCol(),
1693 // TODO: default processing ?
1700 wxLogMessage( "outside grid area" );
1705 // ------------------------------------------------------------
1707 // Right mouse button double click
1709 else if ( ev
.RightDClick() )
1713 wxGridCellCoords cellCoords
;
1715 switch( XYToArea( x
, y
) )
1718 case WXGRID_ROWLABEL
:
1721 SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK
, row
, col
, ev
);
1725 case WXGRID_COLLABEL
:
1728 SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK
, row
, col
, ev
);
1732 case WXGRID_CORNERLABEL
:
1734 // leave both row and col as -1
1736 SendEvent( EVT_GRID_LABEL_RIGHT_DCLICK
, row
, col
, ev
);
1742 XYToCell( x
, y
, cellCoords
);
1743 SendEvent( EVT_GRID_CELL_RIGHT_DCLICK
,
1744 cellCoords
.GetRow(),
1745 cellCoords
.GetCol(),
1752 wxLogMessage( "outside grid area" );
1757 // ------------------------------------------------------------
1759 // No buttons down and mouse moving
1761 else if ( ev
.Moving() )
1763 switch( XYToArea( x
, y
) )
1765 case WXGRID_ROWLABEL
:
1767 m_dragRowOrCol
= YToEdgeOfRow( y
);
1768 if ( m_dragRowOrCol
>= 0 )
1770 if ( m_cursorMode
== WXGRID_CURSOR_SELECT_CELL
)
1772 m_cursorMode
= WXGRID_CURSOR_RESIZE_ROW
;
1773 SetCursor( m_rowResizeCursor
);
1778 if ( m_cursorMode
!= WXGRID_CURSOR_SELECT_CELL
)
1780 m_cursorMode
= WXGRID_CURSOR_SELECT_CELL
;
1781 SetCursor( *wxSTANDARD_CURSOR
);
1787 case WXGRID_COLLABEL
:
1789 m_dragRowOrCol
= XToEdgeOfCol( x
);
1790 if ( m_dragRowOrCol
>= 0 )
1792 if ( m_cursorMode
== WXGRID_CURSOR_SELECT_CELL
)
1794 m_cursorMode
= WXGRID_CURSOR_RESIZE_COL
;
1795 SetCursor( m_colResizeCursor
);
1800 if ( m_cursorMode
!= WXGRID_CURSOR_SELECT_CELL
)
1802 m_cursorMode
= WXGRID_CURSOR_SELECT_CELL
;
1803 SetCursor( *wxSTANDARD_CURSOR
);
1811 if ( m_cursorMode
!= WXGRID_CURSOR_SELECT_CELL
)
1813 m_cursorMode
= WXGRID_CURSOR_SELECT_CELL
;
1814 SetCursor( *wxSTANDARD_CURSOR
);
1823 void wxGrid::OnKeyDown( wxKeyEvent
& ev
)
1825 if ( m_inOnKeyDown
)
1827 // shouldn't be here - we are going round in circles...
1829 wxLogFatalError( wxT("wxGrid::OnKeyDown called while alread active") );
1832 m_inOnKeyDown
= TRUE
;
1834 // propagate the event up and see if it gets processed
1836 wxWindow
*parent
= GetParent();
1837 wxKeyEvent
keyEvt( ev
);
1838 keyEvt
.SetEventObject( parent
);
1840 if ( !parent
->GetEventHandler()->ProcessEvent( keyEvt
) )
1842 // try local handlers
1844 switch ( ev
.KeyCode() )
1847 if ( ev
.ControlDown() )
1849 MoveCursorUpBlock();
1858 if ( ev
.ControlDown() )
1860 MoveCursorDownBlock();
1869 if ( ev
.ControlDown() )
1871 MoveCursorLeftBlock();
1880 if ( ev
.ControlDown() )
1882 MoveCursorRightBlock();
1895 if ( ev
.ControlDown() )
1897 MakeCellVisible( 0, 0 );
1907 if ( ev
.ControlDown() )
1909 MakeCellVisible( m_numRows
-1, m_numCols
-1 );
1910 SelectCell( m_numRows
-1, m_numCols
-1 );
1927 // now try the cell edit control
1929 if ( IsCellEditControlEnabled() )
1931 ev
.SetEventObject( m_cellEditCtrl
);
1932 m_cellEditCtrl
->GetEventHandler()->ProcessEvent( ev
);
1938 m_inOnKeyDown
= FALSE
;
1942 // Text updated in an edit control - either a text control or a
1945 void wxGrid::OnText( wxCommandEvent
& ev
)
1950 wxWindow
*ctrl
= (wxWindow
*)ev
.GetEventObject();
1952 if ( ctrl
== m_cellEditCtrl
&&
1953 IsTopEditControlEnabled() )
1955 // set the value of the top edit control
1957 switch ( m_editCtrlType
)
1959 case wxGRID_TEXTCTRL
:
1960 ((wxTextCtrl
*)m_topEditCtrl
)->
1961 SetValue(((wxTextCtrl
*)ctrl
)->GetValue());
1964 case wxGRID_COMBOBOX
:
1965 ((wxComboBox
*)m_topEditCtrl
)->
1966 SetValue(((wxComboBox
*)ctrl
)->GetValue());
1970 else if ( ctrl
== m_topEditCtrl
)
1972 if ( IsCellEditControlEnabled() )
1974 switch ( m_editCtrlType
)
1976 case wxGRID_TEXTCTRL
:
1977 ((wxTextCtrl
*)m_cellEditCtrl
)->
1978 SetValue(((wxTextCtrl
*)ctrl
)->GetValue());
1981 case wxGRID_COMBOBOX
:
1982 ((wxComboBox
*)m_cellEditCtrl
)->
1983 SetValue(((wxComboBox
*)ctrl
)->GetValue());
1989 // in the case when in-place editing is turned off we just want to
1990 // echo the text changes in the cell but not yet update the grid table
1992 switch ( m_editCtrlType
)
1994 case wxGRID_TEXTCTRL
:
1995 DrawCellValue( m_currentCellCoords
, ((wxTextCtrl
*)ctrl
)->GetValue() );
1998 case wxGRID_COMBOBOX
:
1999 DrawCellValue( m_currentCellCoords
, ((wxComboBox
*)ctrl
)->GetValue() );
2009 void wxGrid::OnGridScroll( wxScrollEvent
& ev
)
2011 // propagate the event up and see if it gets processed
2013 wxWindow
*parent
= GetParent();
2014 wxScrollEvent
scrollEvt( ev
);
2015 if (parent
->GetEventHandler()->ProcessEvent( scrollEvt
)) return;
2017 HideCellEditControl();
2019 if ( ev
.GetEventObject() == m_horizScrollBar
)
2021 if ( ev
.GetPosition() != m_scrollPosX
)
2023 SetHorizontalScrollPos( ev
.GetPosition() );
2028 if ( ev
.GetPosition() != m_scrollPosY
)
2030 SetVerticalScrollPos( ev
.GetPosition() );
2034 ShowCellEditControl();
2038 void wxGrid::SelectCell( const wxGridCellCoords
& coords
)
2040 if ( SendEvent( EVT_GRID_SELECT_CELL
, coords
.GetRow(), coords
.GetCol() ) )
2042 // the event has been intercepted - do nothing
2046 wxClientDC
dc( this );
2048 if ( m_currentCellCoords
!= wxGridNoCellCoords
)
2050 HideCurrentCellHighlight( dc
);
2051 HideCellEditControl();
2052 SaveEditControlValue();
2055 m_currentCellCoords
= coords
;
2057 SetEditControlValue();
2060 ShowCellEditControl();
2061 ShowCurrentCellHighlight( dc
);
2064 if ( IsSelection() )
2067 if ( !GetBatchCount() ) Refresh();
2072 void wxGrid::ShowCellEditControl()
2076 if ( IsCellEditControlEnabled() )
2078 if ( !IsVisible( m_currentCellCoords
) )
2084 rect
= CellToRect( m_currentCellCoords
);
2086 m_cellEditCtrl
->SetSize( rect
);
2087 m_cellEditCtrl
->Show( TRUE
);
2089 switch ( m_editCtrlType
)
2091 case wxGRID_TEXTCTRL
:
2092 ((wxTextCtrl
*) m_cellEditCtrl
)->SetInsertionPointEnd();
2095 case wxGRID_CHECKBOX
:
2096 // TODO: anything ???
2101 // TODO: anything ???
2105 case wxGRID_COMBOBOX
:
2106 // TODO: anything ???
2111 m_cellEditCtrl
->SetFocus();
2117 void wxGrid::HideCellEditControl()
2119 if ( IsCellEditControlEnabled() )
2121 m_cellEditCtrl
->Show( FALSE
);
2125 void wxGrid::SetEditControlValue( const wxString
& value
)
2131 s
= GetCellValue(m_currentCellCoords
);
2135 if ( IsTopEditControlEnabled() )
2137 switch ( m_editCtrlType
)
2139 case wxGRID_TEXTCTRL
:
2140 ((wxGridTextCtrl
*)m_topEditCtrl
)->SetStartValue(s
);
2143 case wxGRID_CHECKBOX
:
2144 // TODO: implement this
2149 // TODO: implement this
2153 case wxGRID_COMBOBOX
:
2154 // TODO: implement this
2160 if ( IsCellEditControlEnabled() )
2162 switch ( m_editCtrlType
)
2164 case wxGRID_TEXTCTRL
:
2165 ((wxGridTextCtrl
*)m_cellEditCtrl
)->SetStartValue(s
);
2168 case wxGRID_CHECKBOX
:
2169 // TODO: implement this
2174 // TODO: implement this
2178 case wxGRID_COMBOBOX
:
2179 // TODO: implement this
2187 void wxGrid::SaveEditControlValue()
2191 wxWindow
*ctrl
= (wxWindow
*)NULL
;
2193 if ( IsCellEditControlEnabled() )
2195 ctrl
= m_cellEditCtrl
;
2197 else if ( IsTopEditControlEnabled() )
2199 ctrl
= m_topEditCtrl
;
2206 bool valueChanged
= FALSE
;
2208 switch ( m_editCtrlType
)
2210 case wxGRID_TEXTCTRL
:
2211 valueChanged
= (((wxGridTextCtrl
*)ctrl
)->GetValue() !=
2212 ((wxGridTextCtrl
*)ctrl
)->GetStartValue());
2213 SetCellValue( m_currentCellCoords
,
2214 ((wxTextCtrl
*) ctrl
)->GetValue() );
2217 case wxGRID_CHECKBOX
:
2218 // TODO: implement this
2223 // TODO: implement this
2227 case wxGRID_COMBOBOX
:
2228 // TODO: implement this
2235 SendEvent( EVT_GRID_CELL_CHANGE
,
2236 m_currentCellCoords
.GetRow(),
2237 m_currentCellCoords
.GetCol() );
2243 int wxGrid::XYToArea( int x
, int y
)
2245 if ( x
> m_left
&& x
< m_right
&&
2246 y
> m_top
&& y
< m_bottom
)
2248 if ( y
< m_top
+ m_colLabelHeight
)
2250 if ( x
> m_left
+ m_rowLabelWidth
)
2252 return WXGRID_COLLABEL
;
2256 return WXGRID_CORNERLABEL
;
2259 else if ( x
<= m_left
+ m_rowLabelWidth
)
2261 return WXGRID_ROWLABEL
;
2269 return WXGRID_NOAREA
;
2273 void wxGrid::XYToCell( int x
, int y
, wxGridCellCoords
& coords
)
2275 coords
.SetRow( YToRow(y
) );
2276 coords
.SetCol( XToCol(x
) );
2280 int wxGrid::YToRow( int y
)
2284 if ( y
> m_top
+ m_colLabelHeight
)
2286 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
2288 if ( y
< m_rowBottoms
[i
] )
2299 int wxGrid::XToCol( int x
)
2303 if ( x
> m_left
+ m_rowLabelWidth
)
2305 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
2307 if ( x
< m_colRights
[i
] )
2318 // return the row number that that the y coord is near the edge of, or
2319 // -1 if not near an edge
2321 int wxGrid::YToEdgeOfRow( int y
)
2325 if ( y
> m_top
+ m_colLabelHeight
)
2327 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
2329 if ( m_rowHeights
[i
] > WXGRID_LABEL_EDGE_ZONE
)
2331 d
= abs( y
- m_rowBottoms
[i
] );
2333 if ( d
< WXGRID_LABEL_EDGE_ZONE
) return i
;
2344 // return the col number that that the x coord is near the edge of, or
2345 // -1 if not near an edge
2347 int wxGrid::XToEdgeOfCol( int x
)
2351 if ( x
> m_left
+ m_rowLabelWidth
)
2353 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
2355 if ( m_colWidths
[i
] > WXGRID_LABEL_EDGE_ZONE
)
2357 d
= abs( x
- m_colRights
[i
] );
2359 if ( d
< WXGRID_LABEL_EDGE_ZONE
) return i
;
2370 wxRect
wxGrid::CellToRect( int row
, int col
)
2372 wxRect
rect( -1, -1, -1, -1 );
2374 if ( row
>= m_scrollPosY
&& col
>= m_scrollPosX
)
2376 rect
.x
= m_colRights
[col
] - m_colWidths
[col
];
2377 rect
.y
= m_rowBottoms
[row
] - m_rowHeights
[row
];
2378 rect
.width
= m_colWidths
[col
];
2379 rect
.height
= m_rowHeights
[ row
];
2386 bool wxGrid::MoveCursorUp()
2388 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2389 m_currentCellCoords
.GetRow() > 0 )
2391 SelectCell( m_currentCellCoords
.GetRow() - 1,
2392 m_currentCellCoords
.GetCol() );
2394 if ( !IsVisible( m_currentCellCoords
) )
2395 MakeCellVisible( m_currentCellCoords
);
2403 bool wxGrid::MoveCursorDown()
2405 // TODO: allow for scrolling
2407 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2408 m_currentCellCoords
.GetRow() < m_numRows
-1 )
2410 SelectCell( m_currentCellCoords
.GetRow() + 1,
2411 m_currentCellCoords
.GetCol() );
2413 if ( !IsVisible( m_currentCellCoords
) )
2414 MakeCellVisible( m_currentCellCoords
);
2422 bool wxGrid::MoveCursorLeft()
2424 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2425 m_currentCellCoords
.GetCol() > 0 )
2427 SelectCell( m_currentCellCoords
.GetRow(),
2428 m_currentCellCoords
.GetCol() - 1 );
2430 if ( !IsVisible( m_currentCellCoords
) )
2431 MakeCellVisible( m_currentCellCoords
);
2439 bool wxGrid::MoveCursorRight()
2441 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2442 m_currentCellCoords
.GetCol() < m_numCols
- 1 )
2444 SelectCell( m_currentCellCoords
.GetRow(),
2445 m_currentCellCoords
.GetCol() + 1 );
2447 if ( !IsVisible( m_currentCellCoords
) )
2448 MakeCellVisible( m_currentCellCoords
);
2456 bool wxGrid::MovePageUp()
2458 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2461 int row
= m_currentCellCoords
.GetRow();
2462 int y
= m_rowBottoms
[ row
] - m_rowHeights
[ row
];
2465 if ( y
+ m_rowHeights
[row
-1] > m_bottom
) break;
2466 y
+= m_rowHeights
[ --row
];
2468 SetVerticalScrollPos( row
);
2470 SelectCell( row
, m_currentCellCoords
.GetCol() );
2477 bool wxGrid::MovePageDown()
2479 if ( m_currentCellCoords
!= wxGridNoCellCoords
&&
2480 m_scrollPosY
+ m_wholeRowsVisible
< m_numRows
)
2482 if ( m_wholeRowsVisible
> 0 )
2484 SetVerticalScrollPos( m_scrollPosY
+ m_wholeRowsVisible
);
2486 else if ( m_scrollPosY
< m_numRows
- 1 )
2488 SetVerticalScrollPos( m_scrollPosY
+ 1 );
2495 // m_scrollPosY will have been updated
2497 SelectCell( m_scrollPosY
, m_currentCellCoords
.GetCol() );
2504 bool wxGrid::MoveCursorUpBlock()
2507 m_currentCellCoords
!= wxGridNoCellCoords
&&
2508 m_currentCellCoords
.GetRow() > 0 )
2510 int row
= m_currentCellCoords
.GetRow();
2511 int col
= m_currentCellCoords
.GetCol();
2513 if ( m_table
->IsEmptyCell(row
, col
) )
2515 // starting in an empty cell: find the next block of
2521 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2524 else if ( m_table
->IsEmptyCell(row
-1, col
) )
2526 // starting at the top of a block: find the next block
2532 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2537 // starting within a block: find the top of the block
2542 if ( m_table
->IsEmptyCell(row
, col
) )
2550 SelectCell( row
, col
);
2552 if ( !IsVisible( m_currentCellCoords
) )
2553 MakeCellVisible( m_currentCellCoords
);
2561 bool wxGrid::MoveCursorDownBlock()
2564 m_currentCellCoords
!= wxGridNoCellCoords
&&
2565 m_currentCellCoords
.GetRow() < m_numRows
-1 )
2567 int row
= m_currentCellCoords
.GetRow();
2568 int col
= m_currentCellCoords
.GetCol();
2570 if ( m_table
->IsEmptyCell(row
, col
) )
2572 // starting in an empty cell: find the next block of
2575 while ( row
< m_numRows
-1 )
2578 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2581 else if ( m_table
->IsEmptyCell(row
+1, col
) )
2583 // starting at the bottom of a block: find the next block
2586 while ( row
< m_numRows
-1 )
2589 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2594 // starting within a block: find the bottom of the block
2596 while ( row
< m_numRows
-1 )
2599 if ( m_table
->IsEmptyCell(row
, col
) )
2607 SelectCell( row
, col
);
2609 if ( !IsVisible( m_currentCellCoords
) )
2610 MakeCellVisible( m_currentCellCoords
);
2618 bool wxGrid::MoveCursorLeftBlock()
2621 m_currentCellCoords
!= wxGridNoCellCoords
&&
2622 m_currentCellCoords
.GetCol() > 0 )
2624 int row
= m_currentCellCoords
.GetRow();
2625 int col
= m_currentCellCoords
.GetCol();
2627 if ( m_table
->IsEmptyCell(row
, col
) )
2629 // starting in an empty cell: find the next block of
2635 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2638 else if ( m_table
->IsEmptyCell(row
, col
-1) )
2640 // starting at the left of a block: find the next block
2646 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2651 // starting within a block: find the left of the block
2656 if ( m_table
->IsEmptyCell(row
, col
) )
2664 SelectCell( row
, col
);
2666 if ( !IsVisible( m_currentCellCoords
) )
2667 MakeCellVisible( m_currentCellCoords
);
2675 bool wxGrid::MoveCursorRightBlock()
2678 m_currentCellCoords
!= wxGridNoCellCoords
&&
2679 m_currentCellCoords
.GetCol() < m_numCols
-1 )
2681 int row
= m_currentCellCoords
.GetRow();
2682 int col
= m_currentCellCoords
.GetCol();
2684 if ( m_table
->IsEmptyCell(row
, col
) )
2686 // starting in an empty cell: find the next block of
2689 while ( col
< m_numCols
-1 )
2692 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2695 else if ( m_table
->IsEmptyCell(row
, col
+1) )
2697 // starting at the right of a block: find the next block
2700 while ( col
< m_numCols
-1 )
2703 if ( !(m_table
->IsEmptyCell(row
, col
)) ) break;
2708 // starting within a block: find the right of the block
2710 while ( col
< m_numCols
-1 )
2713 if ( m_table
->IsEmptyCell(row
, col
) )
2721 SelectCell( row
, col
);
2723 if ( !IsVisible( m_currentCellCoords
) )
2724 MakeCellVisible( m_currentCellCoords
);
2735 // ----- grid drawing functions
2738 void wxGrid::DrawLabelAreas( wxDC
& dc
)
2741 GetClientSize(&cw
, &ch
);
2743 dc
.SetPen(*wxTRANSPARENT_PEN
);
2744 dc
.SetBrush( wxBrush(GetLabelBackgroundColour(), wxSOLID
) );
2746 dc
.DrawRectangle( m_left
, m_top
,
2747 cw
- m_left
, m_colLabelHeight
);
2749 dc
.DrawRectangle( m_left
, m_top
,
2750 m_rowLabelWidth
, ch
- m_top
);
2754 void wxGrid::DrawColLabels( wxDC
& dc
)
2757 GetClientSize(&cw
, &ch
);
2759 if (m_colLabelHeight
== 0) return;
2761 DrawColLabelBorders( dc
);
2765 rect
.height
= m_colLabelHeight
- 1;
2767 int labelLeft
= m_left
+ m_rowLabelWidth
;
2770 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
2772 if ( labelLeft
> cw
) break;
2774 rect
.x
= 1 + labelLeft
;
2775 rect
.width
= m_colWidths
[i
];
2776 DrawColLabel( dc
, rect
, i
);
2778 labelLeft
+= m_colWidths
[i
];
2783 void wxGrid::DrawColLabelBorders( wxDC
& dc
)
2785 if ( m_colLabelHeight
<= 0 ) return;
2789 GetClientSize( &cw
, &ch
);
2791 dc
.SetPen( *wxBLACK_PEN
);
2795 dc
.DrawLine( m_left
, m_top
, cw
, m_top
);
2797 dc
.DrawLine( m_left
, m_top
+ m_colLabelHeight
,
2798 cw
, m_top
+ m_colLabelHeight
);
2802 int colLeft
= m_left
+ m_rowLabelWidth
;
2803 for ( i
= m_scrollPosX
; i
<= m_numCols
; i
++ )
2805 if (colLeft
> cw
) break;
2807 dc
.DrawLine( colLeft
, m_top
,
2808 colLeft
, m_top
+ m_colLabelHeight
);
2810 if ( i
< m_numCols
) colLeft
+= m_colWidths
[i
];
2813 // Draw white highlights for a 3d effect
2815 dc
.SetPen( *wxWHITE_PEN
);
2817 colLeft
= m_left
+ m_rowLabelWidth
;
2818 for ( i
= m_scrollPosX
; i
< m_numCols
; i
++ )
2820 if (colLeft
> cw
) break;
2822 dc
.DrawLine(colLeft
+ 1, m_top
+ 1,
2823 colLeft
+ m_colWidths
[i
], m_top
+ 1);
2825 dc
.DrawLine(colLeft
+ 1, m_top
+ 1,
2826 colLeft
+ 1, m_top
+ m_colLabelHeight
);
2828 colLeft
+= m_colWidths
[i
];
2833 void wxGrid::DrawColLabel( wxDC
& dc
, const wxRect
& rect
, int col
)
2842 dc
.SetBackgroundMode( wxTRANSPARENT
);
2843 dc
.SetTextBackground( GetLabelBackgroundColour() );
2844 dc
.SetTextForeground( GetLabelTextColour() );
2845 dc
.SetFont( GetLabelFont() );
2848 GetColLabelAlignment( &hAlign
, &vAlign
);
2849 DrawTextRectangle( dc
, GetColLabelValue( col
), rect2
, hAlign
, vAlign
);
2853 void wxGrid::DrawRowLabels( wxDC
& dc
)
2856 GetClientSize(&cw
, &ch
);
2858 if (m_rowLabelWidth
== 0) return;
2860 DrawRowLabelBorders( dc
);
2863 rect
.x
= m_left
+ 1;
2864 rect
.width
= m_rowLabelWidth
- 1;
2866 int labelTop
= m_top
+ m_colLabelHeight
;
2869 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
2871 if ( labelTop
> ch
) break;
2873 rect
.y
= 1 + labelTop
;
2874 rect
.height
= m_rowHeights
[i
];
2875 DrawRowLabel( dc
, rect
, i
);
2877 labelTop
+= m_rowHeights
[i
];
2882 void wxGrid::DrawRowLabelBorders( wxDC
& dc
)
2884 if ( m_rowLabelWidth
<= 0 ) return;
2888 GetClientSize( &cw
, &ch
);
2890 dc
.SetPen( *wxBLACK_PEN
);
2894 dc
.DrawLine( m_left
, m_top
, m_left
, ch
);
2896 dc
.DrawLine( m_left
+ m_rowLabelWidth
, m_top
,
2897 m_left
+ m_rowLabelWidth
, ch
);
2901 int rowTop
= m_top
+ m_colLabelHeight
;
2902 for ( i
= m_scrollPosY
; i
<= m_numRows
; i
++ )
2904 if ( rowTop
> ch
) break;
2906 dc
.DrawLine( m_left
, rowTop
,
2907 m_left
+ m_rowLabelWidth
, rowTop
);
2909 if ( i
< m_numRows
) rowTop
+= m_rowHeights
[i
];
2912 // Draw white highlights for a 3d effect
2914 dc
.SetPen( *wxWHITE_PEN
);
2916 rowTop
= m_top
+ m_colLabelHeight
;
2917 for ( i
= m_scrollPosY
; i
< m_numRows
; i
++ )
2919 if ( rowTop
> ch
) break;
2921 dc
.DrawLine( m_left
+ 1, rowTop
+ 1,
2922 m_left
+ m_rowLabelWidth
, rowTop
+ 1 );
2924 dc
.DrawLine( m_left
+ 1, rowTop
+ 1,
2925 m_left
+ 1, rowTop
+ m_rowHeights
[i
] );
2927 rowTop
+= m_rowHeights
[i
];
2932 void wxGrid::DrawRowLabel( wxDC
& dc
, const wxRect
& rect
, int row
)
2941 dc
.SetBackgroundMode( wxTRANSPARENT
);
2942 dc
.SetTextBackground( GetLabelBackgroundColour() );
2943 dc
.SetTextForeground( GetLabelTextColour() );
2944 dc
.SetFont( GetLabelFont() );
2947 GetRowLabelAlignment( &hAlign
, &vAlign
);
2948 DrawTextRectangle( dc
, GetRowLabelValue( row
), rect2
, hAlign
, vAlign
);
2952 void wxGrid::DrawCellArea( wxDC
& dc
)
2955 GetClientSize(&cw
, &ch
);
2957 dc
.SetPen( *wxTRANSPARENT_PEN
);
2958 dc
.SetBrush( wxBrush(GetDefaultCellBackgroundColour(), wxSOLID
) );
2960 int left
= m_left
+ m_rowLabelWidth
+ 1;
2961 int top
= m_top
+ m_colLabelHeight
+ 1;
2963 dc
.DrawRectangle( left
, top
, cw
- left
, ch
- top
);
2967 void wxGrid::DrawGridLines( wxDC
& dc
)
2969 if ( !m_gridLinesEnabled
|| !m_numRows
|| !m_numCols
) return;
2973 GetClientSize(&cw
, &ch
);
2975 dc
.SetPen( wxPen(GetGridLineColour(), 1, wxSOLID
) );
2977 // horizontal grid lines
2979 int rowTop
= m_top
+ m_colLabelHeight
+ m_rowHeights
[m_scrollPosY
];
2980 for ( i
= m_scrollPosY
+ 1; i
<= m_numRows
; i
++ )
2982 if ( rowTop
> ch
) break;
2984 dc
.DrawLine( m_left
+ m_rowLabelWidth
+ 1, rowTop
,
2987 if ( i
< m_numRows
) rowTop
+= m_rowHeights
[i
];
2991 // vertical grid lines
2993 int colLeft
= m_left
+ m_rowLabelWidth
+ m_colWidths
[m_scrollPosX
];
2994 for ( i
= m_scrollPosX
+ 1; i
<= m_numCols
; i
++ )
2996 if ( colLeft
> cw
) break;
2998 dc
.DrawLine( colLeft
, m_top
+ m_colLabelHeight
+ 1,
2999 colLeft
, m_bottom
);
3001 if ( i
< m_numCols
) colLeft
+= m_colWidths
[i
];
3006 void wxGrid::DrawCells( wxDC
& dc
)
3008 if ( !m_numRows
|| !m_numCols
) return;
3013 GetClientSize( &cw
, &ch
);
3019 rect
.y
= m_top
+ m_colLabelHeight
;
3020 for ( row
= m_scrollPosY
; row
< m_numRows
; row
++ )
3022 if ( rect
.y
> ch
) break;
3024 rect
.height
= m_rowHeights
[ row
];
3025 rect
.x
= m_left
+ m_rowLabelWidth
;
3027 for ( col
= m_scrollPosX
; col
< m_numCols
; col
++ )
3029 if ( rect
.x
> cw
) break;
3031 rect
.width
= m_colWidths
[col
];
3032 DrawCellBackground( dc
, rect
, row
, col
);
3033 DrawCellValue( dc
, rect
, row
, col
);
3034 rect
.x
+= rect
.width
;
3036 rect
.y
+= rect
.height
;
3042 void wxGrid::DrawCellBackground( wxDC
& dc
, const wxRect
& rect
, int row
, int col
)
3051 dc
.SetBackgroundMode( wxSOLID
);
3053 if ( IsInSelection( row
, col
) )
3055 // TODO: improve this
3057 dc
.SetBrush( *wxBLACK_BRUSH
);
3061 dc
.SetBrush( wxBrush(GetCellBackgroundColour(row
, col
), wxSOLID
) );
3063 dc
.SetPen( *wxTRANSPARENT_PEN
);
3064 dc
.DrawRectangle( rect2
);
3068 // This draws a text value in the given cell. If useValueArg is FALSE
3069 // (the default) then the grid table value will be used
3071 void wxGrid::DrawCellValue( wxDC
& dc
, const wxRect
& rect
, int row
, int col
,
3072 const wxString
& value
, bool useValueArg
)
3081 dc
.SetBackgroundMode( wxTRANSPARENT
);
3083 if ( IsInSelection( row
, col
) )
3085 // TODO: improve this
3087 dc
.SetTextBackground( wxColour(0, 0, 0) );
3088 dc
.SetTextForeground( wxColour(255, 255, 255) );
3092 dc
.SetTextBackground( GetCellBackgroundColour(row
, col
) );
3093 dc
.SetTextForeground( GetCellTextColour(row
, col
) );
3095 dc
.SetFont( GetCellFont(row
, col
) );
3098 GetCellAlignment( row
, col
, &hAlign
, &vAlign
);
3102 DrawTextRectangle( dc
, value
, rect2
, hAlign
, vAlign
);
3106 DrawTextRectangle( dc
, GetCellValue( row
, col
), rect2
, hAlign
, vAlign
);
3111 // this is used to echo text being entered into the top edit control when
3112 // in-place editing is turned off
3114 void wxGrid::DrawCellValue( const wxGridCellCoords
& coords
, const wxString
& value
)
3116 if ( IsVisible( coords
) )
3118 int row
= coords
.GetRow();
3119 int col
= coords
.GetCol();
3121 rect
.x
= m_colRights
[ col
] - m_colWidths
[ col
];
3122 rect
.y
= m_rowBottoms
[ row
] - m_rowHeights
[ row
];
3123 rect
.width
= m_colWidths
[ col
];
3124 rect
.height
= m_rowHeights
[ row
];
3126 wxClientDC
dc( this );
3127 DrawCellBackground( dc
, rect
, row
, col
);
3128 DrawCellValue( dc
, rect
, row
, col
, value
, TRUE
);
3133 void wxGrid::DrawCellHighlight( wxDC
& dc
, int row
, int col
)
3135 // TODO: bounds checking on row, col ?
3138 if ( row
>= m_scrollPosY
&& col
>= m_scrollPosX
)
3143 GetClientSize( &cw
, &ch
);
3145 x
= m_colRights
[col
] - m_colWidths
[col
];
3146 if ( x
>= cw
) return;
3148 y
= m_rowBottoms
[row
] - m_rowHeights
[row
];
3149 if ( y
>= ch
) return;
3151 dc
.SetLogicalFunction( wxINVERT
);
3152 dc
.SetPen( wxPen(GetCellHighlightColour(), 2, wxSOLID
) );
3153 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
3155 dc
.DrawRectangle( x
-2, y
-2,
3156 m_colWidths
[col
] + 6,
3157 m_rowHeights
[row
] + 6 );
3159 dc
.SetLogicalFunction( wxCOPY
);
3164 // This function is handy when you just want to update one or a few
3165 // cells. For example, it is used by SetCellValue()
3167 void wxGrid::DrawCell( int row
, int col
)
3169 if ( !GetBatchCount() )
3171 if ( !IsVisible( wxGridCellCoords(row
, col
) ) ) return;
3174 GetClientSize( &cw
, &ch
);
3176 wxRect
rect( CellToRect( row
, col
) );
3180 wxClientDC
dc( this );
3181 DrawCellBackground( dc
, rect
, row
, col
);
3182 DrawCellValue( dc
, rect
, row
, col
);
3188 // this is just to make other code more obvious
3190 void wxGrid::HideCurrentCellHighlight( wxDC
& dc
)
3192 if ( m_currentCellHighlighted
&&
3193 m_currentCellCoords
!= wxGridNoCellCoords
)
3195 DrawCellHighlight( dc
, m_currentCellCoords
);
3196 m_currentCellHighlighted
= FALSE
;
3201 // this is just to make other code more obvious
3203 void wxGrid::ShowCurrentCellHighlight( wxDC
& dc
)
3205 if ( !m_currentCellHighlighted
&&
3206 m_currentCellCoords
!= wxGridNoCellCoords
)
3208 DrawCellHighlight( dc
, m_currentCellCoords
);
3209 m_currentCellHighlighted
= TRUE
;
3214 void wxGrid::DrawTextRectangle( wxDC
& dc
,
3215 const wxString
& value
,
3220 long textWidth
, textHeight
;
3221 long lineWidth
, lineHeight
;
3222 wxArrayString lines
;
3224 // see if we are already clipping
3227 dc
.GetClippingBox( clipRect
);
3229 bool alreadyClipping
= TRUE
;
3230 wxRect intersectRect
;
3232 if ( clipRect
.x
== 0 && clipRect
.y
== 0 &&
3233 clipRect
.width
== 0 && clipRect
.height
== 0)
3235 alreadyClipping
= FALSE
;
3236 intersectRect
= rect
;
3240 // Find the intersection of the clipping rectangle and our
3243 wxRegion
region( rect
);
3244 region
.Intersect( clipRect
);
3245 if ( region
.IsEmpty() )
3251 intersectRect
= region
.GetBox();
3254 if ( alreadyClipping
) dc
.DestroyClippingRegion();
3256 dc
.SetClippingRegion( intersectRect
);
3258 StringToLines( value
, lines
);
3259 if ( lines
.GetCount() )
3261 GetTextBoxSize( dc
, lines
, &textWidth
, &textHeight
);
3262 dc
.GetTextExtent( lines
[0], &lineWidth
, &lineHeight
);
3265 switch ( horizAlign
)
3268 x
= rect
.x
+ (rect
.width
- textWidth
- 1);
3272 x
= rect
.x
+ ((rect
.width
- textWidth
)/2);
3281 switch ( vertAlign
)
3284 y
= rect
.y
+ (rect
.height
- textHeight
- 1);
3288 y
= rect
.y
+ ((rect
.height
- textHeight
)/2);
3297 for ( size_t i
= 0; i
< lines
.GetCount(); i
++ )
3299 dc
.DrawText( lines
[i
], (long)x
, (long)y
);
3304 dc
.DestroyClippingRegion();
3305 if (alreadyClipping
) dc
.SetClippingRegion( clipRect
);
3309 // Split multi line text up into an array of strings. Any existing
3310 // contents of the string array are preserved.
3312 void wxGrid::StringToLines( const wxString
& value
, wxArrayString
& lines
)
3314 // TODO: this won't work for WXMAC ? (lines end with '\r')
3315 // => use wxTextFile functions then (VZ)
3318 while ( startPos
< (int)value
.Length() )
3320 pos
= value
.Mid(startPos
).Find( '\n' );
3325 else if ( pos
== 0 )
3327 lines
.Add( wxEmptyString
);
3331 if ( value
[startPos
+pos
-1] == '\r' )
3333 lines
.Add( value
.Mid(startPos
, pos
-1) );
3337 lines
.Add( value
.Mid(startPos
, pos
) );
3342 if ( startPos
< (int)value
.Length() )
3344 lines
.Add( value
.Mid( startPos
) );
3349 void wxGrid::GetTextBoxSize( wxDC
& dc
,
3350 wxArrayString
& lines
,
3351 long *width
, long *height
)
3358 for ( i
= 0; i
< lines
.GetCount(); i
++ )
3360 dc
.GetTextExtent( lines
[i
], &lineW
, &lineH
);
3361 w
= wxMax( w
, lineW
);
3371 // ------ functions to get/send data (see also public functions)
3374 bool wxGrid::GetModelValues()
3378 // all we need to do is repaint the grid
3388 bool wxGrid::SetModelValues()
3394 for ( row
= m_scrollPosY
; row
< m_numRows
; row
++ )
3396 for ( col
= m_scrollPosX
; col
< m_numCols
; col
++ )
3398 m_table
->SetValue( row
, col
, GetCellValue(row
, col
) );
3410 // ------ public functions
3413 bool wxGrid::CreateGrid( int numRows
, int numCols
)
3417 wxLogError( wxT("wxGrid::CreateGrid(numRows, numCols) called more than once") );
3422 m_numRows
= numRows
;
3423 m_numCols
= numCols
;
3425 m_table
= new wxGridStringTable( m_numRows
, m_numCols
);
3426 m_table
->SetView( this );
3435 // The behaviour of this function depends on the grid table class
3436 // Clear() function. For the default wxGridStringTable class the
3437 // behavious is to replace all cell contents with wxEmptyString but
3438 // not to change the number of rows or cols.
3440 void wxGrid::ClearGrid()
3445 SetEditControlValue();
3446 if ( !GetBatchCount() ) Refresh();
3451 bool wxGrid::InsertRows( int pos
, int numRows
, bool WXUNUSED(updateLabels
) )
3453 // TODO: something with updateLabels flag
3457 wxLogError( wxT("Called wxGrid::InsertRows() before calling CreateGrid()") );
3463 bool ok
= m_table
->InsertRows( pos
, numRows
);
3465 // the table will have sent the results of the insert row
3466 // operation to this view object as a grid table message
3470 if ( m_numCols
== 0 )
3472 m_table
->AppendCols( WXGRID_DEFAULT_NUMBER_COLS
);
3474 // TODO: perhaps instead of appending the default number of cols
3475 // we should remember what the last non-zero number of cols was ?
3479 if ( m_currentCellCoords
== wxGridNoCellCoords
)
3481 // if we have just inserted cols into an empty grid the current
3482 // cell will be undefined...
3487 if ( !GetBatchCount() ) Refresh();
3490 SetEditControlValue();
3499 bool wxGrid::AppendRows( int numRows
, bool WXUNUSED(updateLabels
) )
3501 // TODO: something with updateLabels flag
3505 wxLogError( wxT("Called wxGrid::AppendRows() before calling CreateGrid()") );
3509 if ( m_table
&& m_table
->AppendRows( numRows
) )
3511 if ( m_currentCellCoords
== wxGridNoCellCoords
)
3513 // if we have just inserted cols into an empty grid the current
3514 // cell will be undefined...
3519 // the table will have sent the results of the append row
3520 // operation to this view object as a grid table message
3522 if ( !GetBatchCount() ) Refresh();
3531 bool wxGrid::DeleteRows( int pos
, int numRows
, bool WXUNUSED(updateLabels
) )
3533 // TODO: something with updateLabels flag
3537 wxLogError( wxT("Called wxGrid::DeleteRows() before calling CreateGrid()") );
3541 if ( m_table
&& m_table
->DeleteRows( pos
, numRows
) )
3543 // the table will have sent the results of the delete row
3544 // operation to this view object as a grid table message
3546 if ( m_numRows
> 0 )
3547 SetEditControlValue();
3549 HideCellEditControl();
3551 if ( !GetBatchCount() ) Refresh();
3560 bool wxGrid::InsertCols( int pos
, int numCols
, bool WXUNUSED(updateLabels
) )
3562 // TODO: something with updateLabels flag
3566 wxLogError( wxT("Called wxGrid::InsertCols() before calling CreateGrid()") );
3572 HideCellEditControl();
3573 bool ok
= m_table
->InsertCols( pos
, numCols
);
3575 // the table will have sent the results of the insert col
3576 // operation to this view object as a grid table message
3580 if ( m_currentCellCoords
== wxGridNoCellCoords
)
3582 // if we have just inserted cols into an empty grid the current
3583 // cell will be undefined...
3588 if ( !GetBatchCount() ) Refresh();
3591 SetEditControlValue();
3600 bool wxGrid::AppendCols( int numCols
, bool WXUNUSED(updateLabels
) )
3602 // TODO: something with updateLabels flag
3606 wxLogError( wxT("Called wxGrid::AppendCols() before calling CreateGrid()") );
3610 if ( m_table
&& m_table
->AppendCols( numCols
) )
3612 // the table will have sent the results of the append col
3613 // operation to this view object as a grid table message
3615 if ( m_currentCellCoords
== wxGridNoCellCoords
)
3617 // if we have just inserted cols into an empty grid the current
3618 // cell will be undefined...
3622 if ( !GetBatchCount() ) Refresh();
3631 bool wxGrid::DeleteCols( int pos
, int numCols
, bool WXUNUSED(updateLabels
) )
3633 // TODO: something with updateLabels flag
3637 wxLogError( wxT("Called wxGrid::DeleteCols() before calling CreateGrid()") );
3641 if ( m_table
&& m_table
->DeleteCols( pos
, numCols
) )
3643 // the table will have sent the results of the delete col
3644 // operation to this view object as a grid table message
3646 if ( m_numCols
> 0 )
3647 SetEditControlValue();
3649 HideCellEditControl();
3651 if ( !GetBatchCount() ) Refresh();
3663 // ------ control panel and cell edit control
3666 void wxGrid::EnableEditing( bool edit
)
3668 // TODO: improve this ?
3670 if ( edit
!= m_editable
)
3673 if ( !m_editable
) HideCellEditControl();
3674 m_topEditCtrlEnabled
= m_editable
;
3675 m_cellEditCtrlEnabled
= m_editable
;
3676 if ( !m_editable
) ShowCellEditControl();
3681 void wxGrid::EnableTopEditControl( bool enable
)
3683 if ( enable
!= m_topEditCtrlEnabled
)
3685 HideCellEditControl();
3686 m_topEditCtrlEnabled
= enable
;
3688 m_topEditCtrl
->Show( enable
);
3690 if ( m_currentCellCoords
!= wxGridNoCellCoords
)
3691 SetEditControlValue();
3693 ShowCellEditControl();
3694 if ( !GetBatchCount() ) Refresh();
3698 void wxGrid::EnableCellEditControl( bool enable
)
3700 if ( m_cellEditCtrl
&&
3701 enable
!= m_cellEditCtrlEnabled
)
3703 wxClientDC
dc( this );
3705 HideCurrentCellHighlight( dc
);
3706 HideCellEditControl();
3707 SaveEditControlValue();
3709 m_cellEditCtrlEnabled
= enable
;
3711 SetEditControlValue();
3712 ShowCellEditControl();
3713 ShowCurrentCellHighlight( dc
);
3719 // ------ grid formatting functions
3722 void wxGrid::GetRowLabelAlignment( int *horiz
, int *vert
)
3724 *horiz
= m_rowLabelHorizAlign
;
3725 *vert
= m_rowLabelVertAlign
;
3728 void wxGrid::GetColLabelAlignment( int *horiz
, int *vert
)
3730 *horiz
= m_colLabelHorizAlign
;
3731 *vert
= m_colLabelVertAlign
;
3734 wxString
wxGrid::GetRowLabelValue( int row
)
3738 return m_table
->GetRowLabelValue( row
);
3748 wxString
wxGrid::GetColLabelValue( int col
)
3752 return m_table
->GetColLabelValue( col
);
3762 void wxGrid::SetRowLabelSize( int width
)
3764 m_rowLabelWidth
= wxMax( 0, width
);
3766 ShowCellEditControl();
3767 if ( !GetBatchCount() ) Refresh();
3770 void wxGrid::SetColLabelSize( int height
)
3772 m_colLabelHeight
= wxMax( 0, height
);
3774 ShowCellEditControl();
3775 if ( !GetBatchCount() ) Refresh();
3778 void wxGrid::SetLabelBackgroundColour( const wxColour
& colour
)
3780 m_labelBackgroundColour
= colour
;
3781 if ( !GetBatchCount() ) Refresh();
3784 void wxGrid::SetLabelTextColour( const wxColour
& colour
)
3786 m_labelTextColour
= colour
;
3787 if ( !GetBatchCount() ) Refresh();
3790 void wxGrid::SetLabelFont( const wxFont
& font
)
3793 if ( !GetBatchCount() ) Refresh();
3796 void wxGrid::SetRowLabelAlignment( int horiz
, int vert
)
3798 if ( horiz
== wxLEFT
|| horiz
== wxCENTRE
|| horiz
== wxRIGHT
)
3800 m_rowLabelHorizAlign
= horiz
;
3803 if ( vert
== wxTOP
|| vert
== wxCENTRE
|| vert
== wxBOTTOM
)
3805 m_rowLabelVertAlign
= vert
;
3808 if ( !GetBatchCount() ) Refresh();
3811 void wxGrid::SetColLabelAlignment( int horiz
, int vert
)
3813 if ( horiz
== wxLEFT
|| horiz
== wxCENTRE
|| horiz
== wxRIGHT
)
3815 m_colLabelHorizAlign
= horiz
;
3818 if ( vert
== wxTOP
|| vert
== wxCENTRE
|| vert
== wxBOTTOM
)
3820 m_colLabelVertAlign
= vert
;
3823 if ( !GetBatchCount() ) Refresh();
3826 void wxGrid::SetRowLabelValue( int row
, const wxString
& s
)
3830 m_table
->SetRowLabelValue( row
, s
);
3831 if ( !GetBatchCount() ) Refresh();
3835 void wxGrid::SetColLabelValue( int col
, const wxString
& s
)
3839 m_table
->SetColLabelValue( col
, s
);
3840 if ( !GetBatchCount() ) Refresh();
3844 void wxGrid::SetGridLineColour( const wxColour
& colour
)
3846 m_gridLineColour
= colour
;
3848 wxClientDC
dc( this );
3849 DrawGridLines( dc
);
3852 void wxGrid::EnableGridLines( bool enable
)
3854 if ( enable
!= m_gridLinesEnabled
)
3856 m_gridLinesEnabled
= enable
;
3857 if ( !GetBatchCount() ) Refresh();
3862 int wxGrid::GetDefaultRowSize()
3864 return m_defaultRowHeight
;
3867 int wxGrid::GetRowSize( int row
)
3869 if ( row
>= 0 && row
< m_numRows
)
3870 return m_rowHeights
[row
];
3872 return 0; // TODO: log an error here
3875 int wxGrid::GetDefaultColSize()
3877 return m_defaultColWidth
;
3880 int wxGrid::GetColSize( int col
)
3882 if ( col
>= 0 && col
< m_numCols
)
3883 return m_colWidths
[col
];
3885 return 0; // TODO: log an error here
3888 wxColour
wxGrid::GetDefaultCellBackgroundColour()
3890 // TODO: replace this temp test code
3892 return wxColour( 255, 255, 255 );
3895 wxColour
wxGrid::GetCellBackgroundColour( int WXUNUSED(row
), int WXUNUSED(col
) )
3897 // TODO: replace this temp test code
3899 return wxColour( 255, 255, 255 );
3902 wxColour
wxGrid::GetDefaultCellTextColour()
3904 // TODO: replace this temp test code
3906 return wxColour( 0, 0, 0 );
3909 wxColour
wxGrid::GetCellTextColour( int WXUNUSED(row
), int WXUNUSED(col
) )
3911 // TODO: replace this temp test code
3913 return wxColour( 0, 0, 0 );
3917 wxColour
wxGrid::GetCellHighlightColour()
3919 // TODO: replace this temp test code
3921 return wxColour( 0, 0, 0 );
3925 wxFont
wxGrid::GetDefaultCellFont()
3927 return m_defaultCellFont
;
3930 wxFont
wxGrid::GetCellFont( int WXUNUSED(row
), int WXUNUSED(col
) )
3932 // TODO: replace this temp test code
3934 return m_defaultCellFont
;
3937 void wxGrid::GetDefaultCellAlignment( int *horiz
, int *vert
)
3939 // TODO: replace this temp test code
3945 void wxGrid::GetCellAlignment( int WXUNUSED(row
), int WXUNUSED(col
), int *horiz
, int *vert
)
3947 // TODO: replace this temp test code
3953 void wxGrid::SetDefaultRowSize( int height
, bool resizeExistingRows
)
3955 m_defaultRowHeight
= wxMax( height
, WXGRID_MIN_ROW_HEIGHT
);
3957 if ( resizeExistingRows
)
3959 // TODO: what do we do about events here ?
3960 // Generate an event for each resize ?
3963 for ( row
= 0; row
< m_numRows
; row
++ )
3965 m_rowHeights
[row
] = m_defaultRowHeight
;
3967 m_sumRowHeights
= m_defaultRowHeight
* m_numRows
;
3969 if ( !GetBatchCount() ) Refresh();
3973 void wxGrid::SetRowSize( int row
, int height
)
3975 if ( row
>= 0 && row
< m_numRows
)
3977 m_sumRowHeights
-= m_rowHeights
[row
];
3978 m_rowHeights
[row
] = wxMax( 0, height
);
3979 m_sumRowHeights
+= m_rowHeights
[row
];
3981 if ( !GetBatchCount() ) Refresh();
3983 // Note: we are ending the event *after* doing
3984 // default processing in this case
3986 SendEvent( EVT_GRID_ROW_SIZE
,
3991 // TODO: log an error here
3995 void wxGrid::SetDefaultColSize( int width
, bool resizeExistingCols
)
3997 m_defaultColWidth
= wxMax( width
, WXGRID_MIN_COL_WIDTH
);
3999 if ( resizeExistingCols
)
4001 // TODO: what do we do about events here ?
4002 // Generate an event for each resize ?
4005 for ( col
= 0; col
< m_numCols
; col
++ )
4007 m_colWidths
[col
] = m_defaultColWidth
;
4009 m_sumColWidths
= m_defaultColWidth
* m_numCols
;
4011 if ( !GetBatchCount() ) Refresh();
4015 void wxGrid::SetColSize( int col
, int width
)
4017 if ( col
>= 0 && col
< m_numCols
)
4019 m_sumColWidths
-= m_colWidths
[col
];
4020 m_colWidths
[col
] = wxMax( 0, width
);
4021 m_sumColWidths
+= m_colWidths
[col
];
4023 if ( !GetBatchCount() ) Refresh();
4025 // Note: we are ending the event *after* doing
4026 // default processing in this case
4028 SendEvent( EVT_GRID_COL_SIZE
,
4033 // TODO: log an error here
4037 void wxGrid::SetDefaultCellBackgroundColour( const wxColour
& )
4039 // TODO: everything !!!
4043 void wxGrid::SetCellBackgroundColour( int WXUNUSED(row
), int WXUNUSED(col
), const wxColour
& )
4045 // TODO: everything !!!
4049 void wxGrid::SetDefaultCellTextColour( const wxColour
& )
4051 // TODO: everything !!!
4055 void wxGrid::SetCellTextColour( int WXUNUSED(row
), int WXUNUSED(col
), const wxColour
& )
4057 // TODO: everything !!!
4061 void wxGrid::SetCellHighlightColour( const wxColour
& )
4063 // TODO: everything !!!
4067 void wxGrid::SetDefaultCellFont( const wxFont
& )
4069 // TODO: everything !!!
4073 void wxGrid::SetCellFont( int WXUNUSED(row
), int WXUNUSED(col
), const wxFont
& )
4075 // TODO: everything !!!
4079 void wxGrid::SetDefaultCellAlignment( int WXUNUSED(horiz
), int WXUNUSED(vert
) )
4081 // TODO: everything !!!
4085 void wxGrid::SetCellAlignment( int WXUNUSED(row
), int WXUNUSED(col
), int WXUNUSED(horiz
), int WXUNUSED(vert
) )
4087 // TODO: everything !!!
4093 // ------ cell value accessor functions
4096 void wxGrid::SetCellValue( int row
, int col
, const wxString
& s
)
4100 m_table
->SetValue( row
, col
, s
.c_str() );
4101 DrawCell( row
, col
);
4102 if ( m_currentCellCoords
.GetRow() == row
&&
4103 m_currentCellCoords
.GetCol() == col
)
4105 SetEditControlValue( s
);
4113 // ------ interaction with data model
4115 bool wxGrid::ProcessTableMessage( wxGridTableMessage
& msg
)
4117 switch ( msg
.GetId() )
4119 case wxGRIDTABLE_REQUEST_VIEW_GET_VALUES
:
4120 return GetModelValues();
4122 case wxGRIDTABLE_REQUEST_VIEW_SEND_VALUES
:
4123 return SetModelValues();
4125 case wxGRIDTABLE_NOTIFY_ROWS_INSERTED
:
4126 case wxGRIDTABLE_NOTIFY_ROWS_APPENDED
:
4127 case wxGRIDTABLE_NOTIFY_ROWS_DELETED
:
4128 case wxGRIDTABLE_NOTIFY_COLS_INSERTED
:
4129 case wxGRIDTABLE_NOTIFY_COLS_APPENDED
:
4130 case wxGRIDTABLE_NOTIFY_COLS_DELETED
:
4131 return Redimension( msg
);
4140 // ------ Grid location functions
4142 // (see also inline functions in grid.h)
4145 // check to see if a cell location is wholly visible
4147 bool wxGrid::IsVisible( const wxGridCellCoords
& coords
)
4149 return ( coords
.GetRow() >= m_scrollPosY
&&
4150 coords
.GetRow() < m_scrollPosY
+ m_wholeRowsVisible
&&
4151 coords
.GetCol() >= m_scrollPosX
&&
4152 coords
.GetCol() < m_scrollPosX
+ m_wholeColsVisible
);
4156 // make the specified cell location visible by doing a minimal amount
4159 void wxGrid::MakeCellVisible( int row
, int col
)
4161 int lastX
= m_scrollPosX
;
4162 int lastY
= m_scrollPosY
;
4164 if ( row
>= 0 && row
< m_numRows
&&
4165 col
>= 0 && col
< m_numCols
)
4167 if ( row
< m_scrollPosY
)
4169 SetVerticalScrollPos( row
);
4171 else if ( row
>= m_scrollPosY
+ m_wholeRowsVisible
)
4174 int h
= m_rowBottoms
[row
];
4175 for ( i
= m_scrollPosY
; i
< m_numRows
&& h
> m_bottom
; i
++ )
4177 h
-= m_rowHeights
[i
];
4179 SetVerticalScrollPos( i
);
4182 if ( col
< m_scrollPosX
)
4184 SetHorizontalScrollPos( col
);
4186 else if ( col
>= m_scrollPosX
+ m_wholeColsVisible
)
4189 int w
= m_colRights
[col
];
4190 for ( i
= m_scrollPosX
; i
< m_numCols
&& w
> m_right
; i
++ )
4192 w
-= m_colWidths
[i
];
4194 SetHorizontalScrollPos( i
);
4197 if ( m_scrollPosX
!= lastX
|| m_scrollPosY
!= lastY
)
4199 // The cell was not visible before but not it is
4201 ShowCellEditControl();
4206 // TODO: log an error
4211 void wxGrid::SetVerticalScrollPos( int topMostRow
)
4213 if ( m_vertScrollBar
&& topMostRow
!= m_scrollPosY
)
4215 m_scrollPosY
= topMostRow
;
4223 void wxGrid::SetHorizontalScrollPos( int leftMostCol
)
4225 if ( m_horizScrollBar
&& leftMostCol
!= m_scrollPosX
)
4227 m_scrollPosX
= leftMostCol
;
4236 // ------ block, row and col selection
4239 void wxGrid::SelectRow( int row
, bool addToSelected
)
4241 if ( IsSelection() && addToSelected
)
4243 if ( m_selectedTopLeft
.GetRow() > row
)
4244 m_selectedTopLeft
.SetRow( row
);
4246 m_selectedTopLeft
.SetCol( 0 );
4248 if ( m_selectedBottomRight
.GetRow() < row
)
4249 m_selectedBottomRight
.SetRow( row
);
4251 m_selectedBottomRight
.SetCol( m_numCols
- 1 );
4256 m_selectedTopLeft
.Set( row
, 0 );
4257 m_selectedBottomRight
.Set( row
, m_numCols
-1 );
4260 if ( !GetBatchCount() )
4262 wxRect
rect( SelectionToRect() );
4263 if ( rect
!= wxGridNoCellRect
) Refresh( TRUE
, &rect
);
4266 wxGridRangeSelectEvent
gridEvt( GetId(),
4267 EVT_GRID_RANGE_SELECT
,
4270 m_selectedBottomRight
);
4272 GetEventHandler()->ProcessEvent(gridEvt
);
4276 void wxGrid::SelectCol( int col
, bool addToSelected
)
4278 if ( addToSelected
&& m_selectedTopLeft
!= wxGridNoCellCoords
)
4280 if ( m_selectedTopLeft
.GetCol() > col
)
4281 m_selectedTopLeft
.SetCol( col
);
4283 m_selectedTopLeft
.SetRow( 0 );
4285 if ( m_selectedBottomRight
.GetCol() < col
)
4286 m_selectedBottomRight
.SetCol( col
);
4288 m_selectedBottomRight
.SetRow( m_numRows
- 1 );
4293 m_selectedTopLeft
.Set( 0, col
);
4294 m_selectedBottomRight
.Set( m_numRows
-1, col
);
4297 if ( !GetBatchCount() )
4299 wxRect
rect( SelectionToRect() );
4300 if ( rect
!= wxGridNoCellRect
) Refresh( TRUE
, &rect
);
4303 wxGridRangeSelectEvent
gridEvt( GetId(),
4304 EVT_GRID_RANGE_SELECT
,
4307 m_selectedBottomRight
);
4309 GetEventHandler()->ProcessEvent(gridEvt
);
4313 void wxGrid::SelectBlock( int topRow
, int leftCol
, int bottomRow
, int rightCol
)
4317 if ( topRow
> bottomRow
)
4324 if ( leftCol
> rightCol
)
4331 m_selectedTopLeft
.Set( topRow
, leftCol
);
4332 m_selectedBottomRight
.Set( bottomRow
, rightCol
);
4334 if ( !GetBatchCount() )
4336 wxRect
rect( SelectionToRect() );
4337 if ( rect
!= wxGridNoCellRect
) Refresh( TRUE
, &rect
);
4340 // only generate an event if the block is not being selected by
4341 // dragging the mouse (in which case the event will be generated in
4343 if ( !m_isDragging
)
4345 wxGridRangeSelectEvent
gridEvt( GetId(),
4346 EVT_GRID_RANGE_SELECT
,
4349 m_selectedBottomRight
);
4351 GetEventHandler()->ProcessEvent(gridEvt
);
4355 void wxGrid::SelectAll()
4357 m_selectedTopLeft
.Set( 0, 0 );
4358 m_selectedBottomRight
.Set( m_numRows
-1, m_numCols
-1 );
4360 if ( !GetBatchCount() ) Refresh();
4364 void wxGrid::ClearSelection()
4366 if ( IsSelection() )
4368 wxRect
rect( SelectionToRect() );
4369 if ( rect
!= wxGridNoCellRect
)
4371 Refresh( TRUE
, &rect
);
4374 m_selectedTopLeft
= wxGridNoCellCoords
;
4375 m_selectedBottomRight
= wxGridNoCellCoords
;
4380 wxRect
wxGrid::SelectionToRect()
4385 if ( IsSelection() )
4387 cellRect
= CellToRect( m_selectedTopLeft
);
4388 if ( cellRect
!= wxGridNoCellRect
)
4394 rect
= wxRect( m_left
, m_top
, 0, 0 );
4397 cellRect
= CellToRect( m_selectedBottomRight
);
4398 if ( cellRect
!= wxGridNoCellRect
)
4404 return wxGridNoCellRect
;
4415 // ------ Grid event classes
4418 IMPLEMENT_DYNAMIC_CLASS( wxGridEvent
, wxEvent
)
4420 wxGridEvent::wxGridEvent( int id
, wxEventType type
, wxObject
* obj
,
4421 int row
, int col
, int x
, int y
,
4422 bool control
, bool shift
, bool alt
, bool meta
)
4423 : wxNotifyEvent( type
, id
)
4429 m_control
= control
;
4434 SetEventObject(obj
);
4438 IMPLEMENT_DYNAMIC_CLASS( wxGridSizeEvent
, wxEvent
)
4440 wxGridSizeEvent::wxGridSizeEvent( int id
, wxEventType type
, wxObject
* obj
,
4441 int rowOrCol
, int x
, int y
,
4442 bool control
, bool shift
, bool alt
, bool meta
)
4443 : wxNotifyEvent( type
, id
)
4445 m_rowOrCol
= rowOrCol
;
4448 m_control
= control
;
4453 SetEventObject(obj
);
4457 IMPLEMENT_DYNAMIC_CLASS( wxGridRangeSelectEvent
, wxEvent
)
4459 wxGridRangeSelectEvent::wxGridRangeSelectEvent(int id
, wxEventType type
, wxObject
* obj
,
4460 const wxGridCellCoords
& topLeft
,
4461 const wxGridCellCoords
& bottomRight
,
4462 bool control
, bool shift
, bool alt
, bool meta
)
4463 : wxNotifyEvent( type
, id
)
4465 m_topLeft
= topLeft
;
4466 m_bottomRight
= bottomRight
;
4467 m_control
= control
;
4472 SetEventObject(obj
);
4476 #endif // ifndef wxUSE_NEW_GRID