#include "wx/dcclient.h"
#include "wx/settings.h"
#include "wx/log.h"
- #include "wx/sizer.h"
- #include "wx/layout.h"
#endif
+// this include needs to be outside precomp for BCC
+#include "wx/textfile.h"
+
#include "wx/generic/grid.h"
// ----------------------------------------------------------------------------
m_gridLinesEnabled = TRUE;
m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
+ m_winCapture = (wxWindow *)NULL;
m_dragLastPos = -1;
m_dragRowOrCol = -1;
m_isDragging = FALSE;
break;
case WXGRID_CURSOR_SELECT_ROW:
- {
if ( (row = YToRow( y )) >= 0 &&
!IsInSelection( row, 0 ) )
{
SelectRow( row, TRUE );
}
- }
- break;
+
+ // default label to suppress warnings about "enumeration value
+ // 'xxx' not handled in switch
+ default:
+ break;
}
}
return;
m_isDragging = FALSE;
+ // ------------ Entering or leaving the window
+ //
+ if ( event.Entering() || event.Leaving() )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_rowLabelWin);
+ }
+
+
// ------------ Left button pressed
//
- if ( event.LeftDown() )
+ else if ( event.LeftDown() )
{
// don't send a label click event for a hit on the
// edge of the row label - this is probably the user
!SendEvent( EVT_GRID_LABEL_LEFT_CLICK, row, -1, event ) )
{
SelectRow( row, event.ShiftDown() );
- m_cursorMode = WXGRID_CURSOR_SELECT_ROW;
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_ROW, m_rowLabelWin);
}
}
else
{
// starting to drag-resize a row
//
- m_rowLabelWin->CaptureMouse();
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin);
}
}
{
if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
{
- m_rowLabelWin->ReleaseMouse();
-
- if ( m_dragLastPos >= 0 )
- {
- // erase the last line and resize the row
- //
- int cw, ch, left, dummy;
- m_gridWin->GetClientSize( &cw, &ch );
- CalcUnscrolledPosition( 0, 0, &left, &dummy );
+ DoEndDragResizeRow();
- wxClientDC dc( m_gridWin );
- PrepareDC( dc );
- dc.SetLogicalFunction( wxINVERT );
- dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos );
- HideCellEditControl();
-
- int rowTop = m_rowBottoms[m_dragRowOrCol] - m_rowHeights[m_dragRowOrCol];
- SetRowSize( m_dragRowOrCol, wxMax( y - rowTop, WXGRID_MIN_ROW_HEIGHT ) );
- if ( !GetBatchCount() )
- {
- // Only needed to get the correct rect.y:
- wxRect rect ( CellToRect( m_dragRowOrCol, 0 ) );
- rect.x = 0;
- CalcScrolledPosition(0, rect.y, &dummy, &rect.y);
- rect.width = m_rowLabelWidth;
- rect.height = ch - rect.y;
- m_rowLabelWin->Refresh( TRUE, &rect );
- rect.width = cw;
- m_gridWin->Refresh( FALSE, &rect );
- }
-
- ShowCellEditControl();
-
- // Note: we are ending the event *after* doing
- // default processing in this case
- //
- SendEvent( EVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event );
- }
+ // Note: we are ending the event *after* doing
+ // default processing in this case
+ //
+ SendEvent( EVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event );
}
- m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
- m_dragLastPos = -1;
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_rowLabelWin);
+ m_dragLastPos = -1;
}
{
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
- m_cursorMode = WXGRID_CURSOR_RESIZE_ROW;
- m_rowLabelWin->SetCursor( m_rowResizeCursor );
+ // don't capture the mouse yet
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin, FALSE);
}
}
- else
+ else if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
{
- m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
- if ( m_rowLabelWin->GetCursor() == m_rowResizeCursor )
- m_rowLabelWin->SetCursor( *wxSTANDARD_CURSOR );
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_rowLabelWin, FALSE);
}
}
}
break;
case WXGRID_CURSOR_SELECT_COL:
- {
if ( (col = XToCol( x )) >= 0 &&
!IsInSelection( 0, col ) )
{
SelectCol( col, TRUE );
}
- }
- break;
+
+ // default label to suppress warnings about "enumeration value
+ // 'xxx' not handled in switch
+ default:
+ break;
}
}
return;
m_isDragging = FALSE;
+ // ------------ Entering or leaving the window
+ //
+ if ( event.Entering() || event.Leaving() )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_colLabelWin);
+ }
+
+
// ------------ Left button pressed
//
- if ( event.LeftDown() )
+ else if ( event.LeftDown() )
{
// don't send a label click event for a hit on the
// edge of the col label - this is probably the user
!SendEvent( EVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
{
SelectCol( col, event.ShiftDown() );
- m_cursorMode = WXGRID_CURSOR_SELECT_COL;
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, m_colLabelWin);
}
}
else
{
// starting to drag-resize a col
//
- m_colLabelWin->CaptureMouse();
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, m_colLabelWin);
}
}
{
if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
{
- m_colLabelWin->ReleaseMouse();
+ DoEndDragResizeCol();
- if ( m_dragLastPos >= 0 )
- {
- // erase the last line and resize the col
- //
- int cw, ch, dummy, top;
- m_gridWin->GetClientSize( &cw, &ch );
- CalcUnscrolledPosition( 0, 0, &dummy, &top );
-
- wxClientDC dc( m_gridWin );
- PrepareDC( dc );
- dc.SetLogicalFunction( wxINVERT );
- dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top+ch );
- HideCellEditControl();
-
- int colLeft = m_colRights[m_dragRowOrCol] - m_colWidths[m_dragRowOrCol];
- SetColSize( m_dragRowOrCol, wxMax( x - colLeft, WXGRID_MIN_COL_WIDTH ) );
-
- if ( !GetBatchCount() )
- {
- // Only needed to get the correct rect.x:
- wxRect rect ( CellToRect( 0, m_dragRowOrCol ) );
- rect.y = 0;
- CalcScrolledPosition(rect.x, 0, &rect.x, &dummy);
- rect.width = cw - rect.x;
- rect.height = m_colLabelHeight;
- m_colLabelWin->Refresh( TRUE, &rect );
- rect.height = ch;
- m_gridWin->Refresh( FALSE, &rect );
- }
-
- ShowCellEditControl();
-
- // Note: we are ending the event *after* doing
- // default processing in this case
- //
- SendEvent( EVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event );
- }
+ // Note: we are ending the event *after* doing
+ // default processing in this case
+ //
+ SendEvent( EVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event );
}
- m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_colLabelWin);
m_dragLastPos = -1;
}
{
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
- m_cursorMode = WXGRID_CURSOR_RESIZE_COL;
- m_colLabelWin->SetCursor( m_colResizeCursor );
+ // don't capture the cursor yet
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, m_colLabelWin, FALSE);
}
}
- else
+ else if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
{
- m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
- if ( m_colLabelWin->GetCursor() == m_colResizeCursor )
- m_colLabelWin->SetCursor( *wxSTANDARD_CURSOR );
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_colLabelWin, FALSE);
}
}
}
}
}
+void wxGrid::ChangeCursorMode(CursorMode mode,
+ wxWindow *win,
+ bool captureMouse)
+{
+#ifdef __WXDEBUG__
+ static const wxChar *cursorModes[] =
+ {
+ _T("SELECT_CELL"),
+ _T("RESIZE_ROW"),
+ _T("RESIZE_COL"),
+ _T("SELECT_ROW"),
+ _T("SELECT_COL")
+ };
+
+ wxLogTrace(_T("grid"),
+ _T("wxGrid cursor mode (mouse capture for %s): %s -> %s"),
+ win == m_colLabelWin ? _T("colLabelWin")
+ : win ? _T("rowLabelWin")
+ : _T("gridWin"),
+ cursorModes[m_cursorMode], cursorModes[mode]);
+#endif // __WXDEBUG__
+
+ if ( mode == m_cursorMode )
+ return;
+
+ if ( !win )
+ {
+ // by default use the grid itself
+ win = m_gridWin;
+ }
+
+ if ( m_winCapture )
+ {
+ m_winCapture->ReleaseMouse();
+ m_winCapture = (wxWindow *)NULL;
+ }
+
+ m_cursorMode = mode;
+
+ switch ( m_cursorMode )
+ {
+ case WXGRID_CURSOR_RESIZE_ROW:
+ win->SetCursor( m_rowResizeCursor );
+ break;
+
+ case WXGRID_CURSOR_RESIZE_COL:
+ win->SetCursor( m_colResizeCursor );
+ break;
+
+ default:
+ win->SetCursor( *wxSTANDARD_CURSOR );
+ }
+
+ // we need to capture mouse when resizing
+ bool resize = m_cursorMode == WXGRID_CURSOR_RESIZE_ROW ||
+ m_cursorMode == WXGRID_CURSOR_RESIZE_COL;
+
+ if ( captureMouse && resize )
+ {
+ win->CaptureMouse();
+ m_winCapture = win;
+ }
+}
void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
{
}
}
}
+ else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
+ {
+ int cw, ch, left, dummy;
+ m_gridWin->GetClientSize( &cw, &ch );
+ CalcUnscrolledPosition( 0, 0, &left, &dummy );
+
+ wxClientDC dc( m_gridWin );
+ PrepareDC( dc );
+ dc.SetLogicalFunction(wxINVERT);
+ if ( m_dragLastPos >= 0 )
+ {
+ dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos );
+ }
+ dc.DrawLine( left, y, left+cw, y );
+ m_dragLastPos = y;
+ }
+ else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
+ {
+ int cw, ch, dummy, top;
+ m_gridWin->GetClientSize( &cw, &ch );
+ CalcUnscrolledPosition( 0, 0, &dummy, &top );
+
+ wxClientDC dc( m_gridWin );
+ PrepareDC( dc );
+ dc.SetLogicalFunction(wxINVERT);
+ if ( m_dragLastPos >= 0 )
+ {
+ dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top+ch );
+ }
+ dc.DrawLine( x, top, x, top+ch );
+ m_dragLastPos = x;
+ }
return;
}
if ( coords != wxGridNoCellCoords )
{
+ // VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
+ // immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
+ // wxGTK
+#if 0
+ if ( event.Entering() || event.Leaving() )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
+ }
+ else
+#endif // 0
+
+ // ------------ Left button pressed
+ //
if ( event.LeftDown() )
{
if ( event.ShiftDown() )
{
SelectBlock( m_currentCellCoords, coords );
}
- else
+ else if ( XToEdgeOfCol(x) < 0 &&
+ YToEdgeOfRow(y) < 0 )
{
if ( !SendEvent( EVT_GRID_CELL_LEFT_CLICK,
coords.GetRow(),
//
else if ( event.LeftDClick() )
{
- SendEvent( EVT_GRID_CELL_LEFT_DCLICK,
- coords.GetRow(),
- coords.GetCol(),
- event );
+ if ( XToEdgeOfCol(x) < 0 && YToEdgeOfRow(y) < 0 )
+ {
+ SendEvent( EVT_GRID_CELL_LEFT_DCLICK,
+ coords.GetRow(),
+ coords.GetCol(),
+ event );
+ }
}
{
SendEvent( EVT_GRID_RANGE_SELECT, -1, -1, event );
}
+
+ // Show the edit control, if it has
+ // been hidden for drag-shrinking.
+ if ( IsCellEditControlEnabled() )
+ ShowCellEditControl();
}
+ else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ DoEndDragResizeRow();
- // Show the edit control, if it has
- // been hidden for drag-shrinking.
- if ( IsCellEditControlEnabled() )
- ShowCellEditControl();
+ // Note: we are ending the event *after* doing
+ // default processing in this case
+ //
+ SendEvent( EVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event );
+ }
+ else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ DoEndDragResizeCol();
+
+ // Note: we are ending the event *after* doing
+ // default processing in this case
+ //
+ SendEvent( EVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event );
+ }
m_dragLastPos = -1;
}
//
else if ( event.Moving() && !event.IsButton() )
{
- m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
+ int dragRow = YToEdgeOfRow( y );
+ int dragCol = XToEdgeOfCol( x );
+
+ // Dragging on the corner of a cell to resize in both
+ // directions is not implemented yet...
+ //
+ if ( dragRow >= 0 && dragCol >= 0 )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ return;
+ }
+
+ if ( dragRow >= 0 )
+ {
+ m_dragRowOrCol = dragRow;
+
+ if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW);
+ }
+
+ return;
+ }
+
+ if ( dragCol >= 0 )
+ {
+ m_dragRowOrCol = dragCol;
+
+ if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL);
+ }
+
+ return;
+ }
+
+ // Neither on a row or col edge
+ //
+ if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
+ {
+ ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+ }
+ }
+ }
+}
+
+
+void wxGrid::DoEndDragResizeRow()
+{
+ if ( m_dragLastPos >= 0 )
+ {
+ // erase the last line and resize the row
+ //
+ int cw, ch, left, dummy;
+ m_gridWin->GetClientSize( &cw, &ch );
+ CalcUnscrolledPosition( 0, 0, &left, &dummy );
+
+ wxClientDC dc( m_gridWin );
+ PrepareDC( dc );
+ dc.SetLogicalFunction( wxINVERT );
+ dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos );
+ HideCellEditControl();
+
+ int rowTop = m_rowBottoms[m_dragRowOrCol] - m_rowHeights[m_dragRowOrCol];
+ SetRowSize( m_dragRowOrCol,
+ wxMax( m_dragLastPos - rowTop, WXGRID_MIN_ROW_HEIGHT ) );
+
+ if ( !GetBatchCount() )
+ {
+ // Only needed to get the correct rect.y:
+ wxRect rect ( CellToRect( m_dragRowOrCol, 0 ) );
+ rect.x = 0;
+ CalcScrolledPosition(0, rect.y, &dummy, &rect.y);
+ rect.width = m_rowLabelWidth;
+ rect.height = ch - rect.y;
+ m_rowLabelWin->Refresh( TRUE, &rect );
+ rect.width = cw;
+ m_gridWin->Refresh( FALSE, &rect );
}
+
+ ShowCellEditControl();
}
}
+void wxGrid::DoEndDragResizeCol()
+{
+ if ( m_dragLastPos >= 0 )
+ {
+ // erase the last line and resize the col
+ //
+ int cw, ch, dummy, top;
+ m_gridWin->GetClientSize( &cw, &ch );
+ CalcUnscrolledPosition( 0, 0, &dummy, &top );
+
+ wxClientDC dc( m_gridWin );
+ PrepareDC( dc );
+ dc.SetLogicalFunction( wxINVERT );
+ dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top+ch );
+ HideCellEditControl();
+
+ int colLeft = m_colRights[m_dragRowOrCol] - m_colWidths[m_dragRowOrCol];
+ SetColSize( m_dragRowOrCol,
+ wxMax( m_dragLastPos - colLeft, WXGRID_MIN_COL_WIDTH ) );
+
+ if ( !GetBatchCount() )
+ {
+ // Only needed to get the correct rect.x:
+ wxRect rect ( CellToRect( 0, m_dragRowOrCol ) );
+ rect.y = 0;
+ CalcScrolledPosition(rect.x, 0, &rect.x, &dummy);
+ rect.width = cw - rect.x;
+ rect.height = m_colLabelHeight;
+ m_colLabelWin->Refresh( TRUE, &rect );
+ rect.height = ch;
+ m_gridWin->Refresh( FALSE, &rect );
+ }
+
+ ShowCellEditControl();
+ }
+}
+
+
+
//
// ------ interaction with data model
//
//
void wxGrid::StringToLines( const wxString& value, wxArrayString& lines )
{
- // TODO: this won't work for WXMAC ? (lines end with '\r')
- // => use wxTextFile functions then (VZ)
int startPos = 0;
int pos;
- while ( startPos < (int)value.Length() )
+ wxString eol = wxTextFile::GetEOL( wxTextFileType_Unix );
+ wxString tVal = wxTextFile::Translate( value, wxTextFileType_Unix );
+
+ while ( startPos < (int)tVal.Length() )
{
- pos = value.Mid(startPos).Find( '\n' );
+ pos = tVal.Mid(startPos).Find( eol );
if ( pos < 0 )
{
break;
}
else
{
- if ( value[startPos+pos-1] == '\r' )
- {
- lines.Add( value.Mid(startPos, pos-1) );
- }
- else
- {
- lines.Add( value.Mid(startPos, pos) );
- }
+ lines.Add( value.Mid(startPos, pos) );
}
startPos += pos+1;
}
wxColour wxGrid::GetDefaultCellBackgroundColour()
{
- return GetBackgroundColour();
+ return m_gridWin->GetBackgroundColour();
}
// TODO VZ: this must be optimized to allow only retrieveing attr once!
wxColour wxGrid::GetDefaultCellTextColour()
{
- return GetForegroundColour();
+ return m_gridWin->GetForegroundColour();
}
wxColour wxGrid::GetCellTextColour( int row, int col )
m_rowBottoms[i] += diff;
}
CalcDimensions();
-
- // Note: we are ending the event *after* doing
- // default processing in this case
- //
- SendEvent( EVT_GRID_ROW_SIZE,
- row, -1 );
}
void wxGrid::SetDefaultColSize( int width, bool resizeExistingCols )
m_colRights[i] += diff;
}
CalcDimensions();
-
- // Note: we are ending the event *after* doing
- // default processing in this case
- //
- SendEvent( EVT_GRID_COL_SIZE,
- -1, col );
}
void wxGrid::SetDefaultCellBackgroundColour( const wxColour& col )
{
- SetBackgroundColour(col);
+ m_gridWin->SetBackgroundColour(col);
}
void wxGrid::SetDefaultCellTextColour( const wxColour& col )
{
- SetForegroundColour(col);
+ m_gridWin->SetForegroundColour(col);
}
void wxGrid::SetDefaultCellAlignment( int horiz, int vert )