added possibility to reorder columns by dragging them (patch 1409677)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39498 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-06-01 00:13:19 +00:00
parent ec376c8fd9
commit d417574519
6 changed files with 558 additions and 101 deletions

View File

@@ -91,6 +91,7 @@ All (GUI):
- Added wxDC::GradientFillLinear/Concentric() - Added wxDC::GradientFillLinear/Concentric()
- Added wxHyperlinkCtrl (Francesco Montorsi) - Added wxHyperlinkCtrl (Francesco Montorsi)
- Added clipboard events (wxEVT_COMMAND_TEXT_COPY/CUT/PASTE) - Added clipboard events (wxEVT_COMMAND_TEXT_COPY/CUT/PASTE)
- Allow to reorder wxGrid columns by drag-and-drop (Santiago Palacios)
- Added wxRadioBox::SetItemToolTip() - Added wxRadioBox::SetItemToolTip()
- Added support for CMYK JPEG images loading (Robert Wruck) - Added support for CMYK JPEG images loading (Robert Wruck)
- Added wxListCtrl::GetSubItemRect() and subitem hit testing (Agron Selimaj) - Added wxListCtrl::GetSubItemRect() and subitem hit testing (Agron Selimaj)

View File

@@ -2,7 +2,7 @@
%% Name: grid.tex %% Name: grid.tex
%% Purpose: wxGrid %% Purpose: wxGrid
%% Author: %% Author:
%% Modified by: %% Modified by: Santiago Palacios
%% Created: %% Created:
%% RCS-ID: $Id$ %% RCS-ID: $Id$
%% Copyright: (c) wxWidgets %% Copyright: (c) wxWidgets
@@ -265,6 +265,15 @@ to the client size of the grid window.
\membersection{wxGrid::CanDragColMove}\label{wxgridcandragcolmove}
\func{bool}{CanDragColMove}{\void}
Returns true if columns can be moved by dragging with the mouse. Columns can be moved
by dragging on their labels.
\membersection{wxGrid::CanDragColSize}\label{wxgridcandragcolsize} \membersection{wxGrid::CanDragColSize}\label{wxgridcandragcolsize}
\func{bool}{CanDragColSize}{\void} \func{bool}{CanDragColSize}{\void}
@@ -391,6 +400,15 @@ Equivalent to calling EnableCellEditControl(false).
\membersection{wxGrid::DisableDragColMove}\label{wxgriddisabledragcolmove}
\func{void}{DisableDragColMove}{\void}
Disables column moving by dragging with the mouse. Equivalent to passing false to
\helpref{wxGrid::EnableDragColMove}{wxgridenabledragcolmove}.
\membersection{wxGrid::DisableDragColSize}\label{wxgriddisabledragcolsize} \membersection{wxGrid::DisableDragColSize}\label{wxgriddisabledragcolsize}
\func{void}{DisableDragColSize}{\void} \func{void}{DisableDragColSize}{\void}
@@ -435,6 +453,14 @@ Enables or disables column sizing by dragging with the mouse.
\membersection{wxGrid::EnableDragColMove}\label{wxgridenabledragcolmove}
\func{void}{EnableDragColMove}{\param{bool }{enable = true}}
Enables or disables column moving by dragging with the mouse.
\membersection{wxGrid::EnableDragGridSize}\label{wxgridenabledraggridsize} \membersection{wxGrid::EnableDragGridSize}\label{wxgridenabledraggridsize}
\func{void}{EnableDragGridSize}{\param{bool }{enable = true}} \func{void}{EnableDragGridSize}{\param{bool }{enable = true}}
@@ -596,6 +622,13 @@ and the \helpref{wxGrid overview}{gridoverview} for more information.
\membersection{wxGrid::GetColAt}\label{wxgridgetcolat}
\constfunc{int}{GetColAt}{\param{int }{colPos}}
Returns the column ID of the specified column position.
\membersection{wxGrid::GetColLeft}\label{wxgridgetcolleft} \membersection{wxGrid::GetColLeft}\label{wxgridgetcolleft}
\constfunc{int}{GetColLeft}{\param{int }{col}} \constfunc{int}{GetColLeft}{\param{int }{col}}
@@ -652,6 +685,14 @@ Get the minimal width of the given column/row.
\membersection{wxGrid::GetColPos}\label{wxgridgetcolpos}
\constfunc{int}{GetColPos}{\param{int }{colID}}
Returns the position of the specified column.
\membersection{wxGrid::GetColRight}\label{wxgridgetcolright} \membersection{wxGrid::GetColRight}\label{wxgridgetcolright}
\constfunc{int}{GetColRight}{\param{int }{col}} \constfunc{int}{GetColRight}{\param{int }{col}}
@@ -1062,10 +1103,10 @@ used at present.
The sequence of actions begins with the grid object requesting the underlying grid The sequence of actions begins with the grid object requesting the underlying grid
table to insert new columns. If this is successful the table notifies the grid and the table to insert new columns. If this is successful the table notifies the grid and the
grid updates the display. For a default grid (one where you have called grid updates the display. For a default grid (one where you have called
\helpref{wxGrid::CreateGrid}{wxgridcreategrid}) this process is automatic. If you are \helpref{wxGrid::CreateGrid}{wxgridcreategrid}) this process is automatic. If you are
using a custom grid table (specified with \helpref{wxGrid::SetTable}{wxgridsettable}) using a custom grid table (specified with \helpref{wxGrid::SetTable}{wxgridsettable})
then you must override then you must override
\helpref{wxGridTableBase::InsertCols}{wxgridtablebaseinsertcols} in your derived \helpref{wxGridTableBase::InsertCols}{wxgridtablebaseinsertcols} in your derived
table class. table class.
@@ -1081,10 +1122,10 @@ present.
The sequence of actions begins with the grid object requesting the underlying grid The sequence of actions begins with the grid object requesting the underlying grid
table to insert new rows. If this is successful the table notifies the grid and the table to insert new rows. If this is successful the table notifies the grid and the
grid updates the display. For a default grid (one where you have called grid updates the display. For a default grid (one where you have called
\helpref{wxGrid::CreateGrid}{wxgridcreategrid}) this process is automatic. If you are \helpref{wxGrid::CreateGrid}{wxgridcreategrid}) this process is automatic. If you are
using a custom grid table (specified with \helpref{wxGrid::SetTable}{wxgridsettable}) using a custom grid table (specified with \helpref{wxGrid::SetTable}{wxgridsettable})
then you must override then you must override
\helpref{wxGridTableBase::InsertRows}{wxgridtablebaseinsertrows} in your derived \helpref{wxGridTableBase::InsertRows}{wxgridtablebaseinsertrows} in your derived
table class. table class.
@@ -1438,7 +1479,7 @@ function for those cells that contain string values.
The last form is for backward compatibility only. The last form is for backward compatibility only.
See \helpref{wxGridTableBase::CanSetValueAs}{wxgridtablebasecangetvalueas} See \helpref{wxGridTableBase::CanSetValueAs}{wxgridtablebasecangetvalueas}
and the \helpref{wxGrid overview}{gridoverview} for more information. and the \helpref{wxGrid overview}{gridoverview} for more information.
@@ -1449,8 +1490,8 @@ and the \helpref{wxGrid overview}{gridoverview} for more information.
Sets the cell attributes for all cells in the specified column. Sets the cell attributes for all cells in the specified column.
For more information about controlling grid cell attributes see the For more information about controlling grid cell attributes see the
\helpref{wxGridCellAttr}{wxgridcellattr} cell attribute class and the \helpref{wxGridCellAttr}{wxgridcellattr} cell attribute class and the
\helpref{wxGrid classes overview}{gridoverview}. \helpref{wxGrid classes overview}{gridoverview}.
@@ -1543,6 +1584,14 @@ with sizes smaller than the value specified here.
\membersection{wxGrid::SetColPos}\label{wxgridsetcolpos}
\func{void}{SetColPos}{\param{int }{colID}, \param{int }{newPos}}
Sets the position of the specified column.
\membersection{wxGrid::SetColSize}\label{wxgridsetcolsize} \membersection{wxGrid::SetColSize}\label{wxgridsetcolsize}
\func{void}{SetColSize}{\param{int }{col}, \param{int }{width}} \func{void}{SetColSize}{\param{int }{col}, \param{int }{width}}
@@ -1877,9 +1926,14 @@ Displays the in-place cell edit control for the current cell.
\membersection{wxGrid::XToCol}\label{wxgridxtocol} \membersection{wxGrid::XToCol}\label{wxgridxtocol}
\func{int}{XToCol}{\param{int }{x}} \func{int}{XToCol}{\param{int }{x}, \param{bool }{clipToMinMax = false}}
Returns the grid column that corresponds to the logical x coordinate. Returns \wxheading{Parameters}
\docparam{x}{The x position to evaluate.}
\docparam{clipToMinMax}{If true, rather than returning wxNOT\_FOUND, it returns either the first or last column depending on whether x is too far to the left or right respectively.}
\wxheading{Return value}
The grid column that corresponds to the logical x coordinate. Returns
{\tt wxNOT\_FOUND} if there is no column at the x position. {\tt wxNOT\_FOUND} if there is no column at the x position.
@@ -1906,6 +1960,6 @@ If no row edge is near to this position {\tt wxNOT\_FOUND} is returned.
\func{int}{YToRow}{\param{int }{y}} \func{int}{YToRow}{\param{int }{y}}
Returns the grid row that corresponds to the logical y coordinate. Returns Returns the grid row that corresponds to the logical y coordinate. Returns
{\tt wxNOT\_FOUND} if there is no row at the y position. {\tt wxNOT\_FOUND} if there is no row at the y position.

View File

@@ -2,7 +2,7 @@
// Name: wx/generic/grid.h // Name: wx/generic/grid.h
// Purpose: wxGrid and related classes // Purpose: wxGrid and related classes
// Author: Michael Bedward (based on code by Julian Smart, Robin Dunn) // Author: Michael Bedward (based on code by Julian Smart, Robin Dunn)
// Modified by: // Modified by: Santiago Palacios
// Created: 1/08/1999 // Created: 1/08/1999
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Michael Bedward // Copyright: (c) Michael Bedward
@@ -1123,6 +1123,7 @@ public:
void DoEndDragResizeRow(); void DoEndDragResizeRow();
void DoEndDragResizeCol(); void DoEndDragResizeCol();
void DoEndDragMoveCol();
wxGridTableBase * GetTable() const { return m_table; } wxGridTableBase * GetTable() const { return m_table; }
bool SetTable( wxGridTableBase *table, bool takeOwnership = false, bool SetTable( wxGridTableBase *table, bool takeOwnership = false,
@@ -1226,7 +1227,7 @@ public:
// //
void XYToCell( int x, int y, wxGridCellCoords& ); void XYToCell( int x, int y, wxGridCellCoords& );
int YToRow( int y ); int YToRow( int y );
int XToCol( int x ); int XToCol( int x, bool clipToMinMax = false );
int YToEdgeOfRow( int y ); int YToEdgeOfRow( int y );
int XToEdgeOfCol( int x ); int XToEdgeOfCol( int x );
@@ -1306,6 +1307,9 @@ public:
void EnableDragColSize( bool enable = true ); void EnableDragColSize( bool enable = true );
void DisableDragColSize() { EnableDragColSize( false ); } void DisableDragColSize() { EnableDragColSize( false ); }
bool CanDragColSize() { return m_canDragColSize; } bool CanDragColSize() { return m_canDragColSize; }
void EnableDragColMove( bool enable = true );
void DisableDragColMove() { EnableDragColMove( false ); }
bool CanDragColMove() { return m_canDragColMove; }
void EnableDragGridSize(bool enable = true); void EnableDragGridSize(bool enable = true);
void DisableDragGridSize() { EnableDragGridSize(false); } void DisableDragGridSize() { EnableDragGridSize(false); }
bool CanDragGridSize() { return m_canDragGridSize; } bool CanDragGridSize() { return m_canDragGridSize; }
@@ -1361,6 +1365,33 @@ public:
void SetColSize( int col, int width ); void SetColSize( int col, int width );
//Column positions
int GetColAt( int colPos ) const
{
if ( m_colAt.IsEmpty() )
return colPos;
else
return m_colAt[colPos];
}
void SetColPos( int colID, int newPos );
int GetColPos( int colID ) const
{
if ( m_colAt.IsEmpty() )
return colID;
else
{
for ( int i = 0; i < m_numCols; i++ )
{
if ( m_colAt[i] == colID )
return i;
}
}
return -1;
}
// automatically size the column or row to fit to its contents, if // automatically size the column or row to fit to its contents, if
// setAsMin is true, this optimal width will also be set as minimal width // setAsMin is true, this optimal width will also be set as minimal width
// for this column // for this column
@@ -1869,7 +1900,8 @@ protected:
WXGRID_CURSOR_RESIZE_ROW, WXGRID_CURSOR_RESIZE_ROW,
WXGRID_CURSOR_RESIZE_COL, WXGRID_CURSOR_RESIZE_COL,
WXGRID_CURSOR_SELECT_ROW, WXGRID_CURSOR_SELECT_ROW,
WXGRID_CURSOR_SELECT_COL WXGRID_CURSOR_SELECT_COL,
WXGRID_CURSOR_MOVE_COL
}; };
// this method not only sets m_cursorMode but also sets the correct cursor // this method not only sets m_cursorMode but also sets the correct cursor
@@ -1885,8 +1917,13 @@ protected:
wxWindow *m_winCapture; // the window which captured the mouse wxWindow *m_winCapture; // the window which captured the mouse
CursorMode m_cursorMode; CursorMode m_cursorMode;
//Column positions
wxArrayInt m_colAt;
int m_moveToCol;
bool m_canDragRowSize; bool m_canDragRowSize;
bool m_canDragColSize; bool m_canDragColSize;
bool m_canDragColMove;
bool m_canDragGridSize; bool m_canDragGridSize;
bool m_canDragCell; bool m_canDragCell;
int m_dragLastPos; int m_dragLastPos;
@@ -1980,7 +2017,7 @@ public:
bool MetaDown() { return m_meta; } bool MetaDown() { return m_meta; }
bool ShiftDown() { return m_shift; } bool ShiftDown() { return m_shift; }
bool AltDown() { return m_alt; } bool AltDown() { return m_alt; }
bool CmdDown() bool CmdDown()
{ {
#if defined(__WXMAC__) || defined(__WXCOCOA__) #if defined(__WXMAC__) || defined(__WXCOCOA__)
return MetaDown(); return MetaDown();
@@ -2022,7 +2059,7 @@ public:
bool MetaDown() { return m_meta; } bool MetaDown() { return m_meta; }
bool ShiftDown() { return m_shift; } bool ShiftDown() { return m_shift; }
bool AltDown() { return m_alt; } bool AltDown() { return m_alt; }
bool CmdDown() bool CmdDown()
{ {
#if defined(__WXMAC__) || defined(__WXCOCOA__) #if defined(__WXMAC__) || defined(__WXCOCOA__)
return MetaDown(); return MetaDown();
@@ -2077,7 +2114,7 @@ public:
bool MetaDown() { return m_meta; } bool MetaDown() { return m_meta; }
bool ShiftDown() { return m_shift; } bool ShiftDown() { return m_shift; }
bool AltDown() { return m_alt; } bool AltDown() { return m_alt; }
bool CmdDown() bool CmdDown()
{ {
#if defined(__WXMAC__) || defined(__WXCOCOA__) #if defined(__WXMAC__) || defined(__WXCOCOA__)
return MetaDown(); return MetaDown();

View File

@@ -2,7 +2,7 @@
// Name: griddemo.cpp // Name: griddemo.cpp
// Purpose: Grid control wxWidgets sample // Purpose: Grid control wxWidgets sample
// Author: Michael Bedward // Author: Michael Bedward
// Modified by: // Modified by: Santiago Palacios
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Michael Bedward, Julian Smart, Vadim Zeitlin // Copyright: (c) Michael Bedward, Julian Smart, Vadim Zeitlin
// Licence: wxWindows license // Licence: wxWindows license
@@ -68,6 +68,7 @@ BEGIN_EVENT_TABLE( GridFrame, wxFrame )
EVT_MENU( ID_TOGGLEEDIT, GridFrame::ToggleEditing ) EVT_MENU( ID_TOGGLEEDIT, GridFrame::ToggleEditing )
EVT_MENU( ID_TOGGLEROWSIZING, GridFrame::ToggleRowSizing ) EVT_MENU( ID_TOGGLEROWSIZING, GridFrame::ToggleRowSizing )
EVT_MENU( ID_TOGGLECOLSIZING, GridFrame::ToggleColSizing ) EVT_MENU( ID_TOGGLECOLSIZING, GridFrame::ToggleColSizing )
EVT_MENU( ID_TOGGLECOLMOVING, GridFrame::ToggleColMoving )
EVT_MENU( ID_TOGGLEGRIDSIZING, GridFrame::ToggleGridSizing ) EVT_MENU( ID_TOGGLEGRIDSIZING, GridFrame::ToggleGridSizing )
EVT_MENU( ID_TOGGLEGRIDDRAGCELL, GridFrame::ToggleGridDragCell ) EVT_MENU( ID_TOGGLEGRIDDRAGCELL, GridFrame::ToggleGridDragCell )
EVT_MENU( ID_TOGGLEGRIDLINES, GridFrame::ToggleGridLines ) EVT_MENU( ID_TOGGLEGRIDLINES, GridFrame::ToggleGridLines )
@@ -146,6 +147,7 @@ GridFrame::GridFrame()
viewMenu->Append( ID_TOGGLEEDIT, _T("&Editable"), wxEmptyString, wxITEM_CHECK ); viewMenu->Append( ID_TOGGLEEDIT, _T("&Editable"), wxEmptyString, wxITEM_CHECK );
viewMenu->Append( ID_TOGGLEROWSIZING, _T("Ro&w drag-resize"), wxEmptyString, wxITEM_CHECK ); viewMenu->Append( ID_TOGGLEROWSIZING, _T("Ro&w drag-resize"), wxEmptyString, wxITEM_CHECK );
viewMenu->Append( ID_TOGGLECOLSIZING, _T("C&ol drag-resize"), wxEmptyString, wxITEM_CHECK ); viewMenu->Append( ID_TOGGLECOLSIZING, _T("C&ol drag-resize"), wxEmptyString, wxITEM_CHECK );
viewMenu->Append( ID_TOGGLECOLMOVING, _T("Col drag-&move"), wxEmptyString, wxITEM_CHECK );
viewMenu->Append( ID_TOGGLEGRIDSIZING, _T("&Grid drag-resize"), wxEmptyString, wxITEM_CHECK ); viewMenu->Append( ID_TOGGLEGRIDSIZING, _T("&Grid drag-resize"), wxEmptyString, wxITEM_CHECK );
viewMenu->Append( ID_TOGGLEGRIDDRAGCELL, _T("&Grid drag-cell"), wxEmptyString, wxITEM_CHECK ); viewMenu->Append( ID_TOGGLEGRIDDRAGCELL, _T("&Grid drag-cell"), wxEmptyString, wxITEM_CHECK );
viewMenu->Append( ID_TOGGLEGRIDLINES, _T("&Grid Lines"), wxEmptyString, wxITEM_CHECK ); viewMenu->Append( ID_TOGGLEGRIDLINES, _T("&Grid Lines"), wxEmptyString, wxITEM_CHECK );
@@ -376,6 +378,7 @@ void GridFrame::SetDefaults()
GetMenuBar()->Check( ID_TOGGLEEDIT, true ); GetMenuBar()->Check( ID_TOGGLEEDIT, true );
GetMenuBar()->Check( ID_TOGGLEROWSIZING, true ); GetMenuBar()->Check( ID_TOGGLEROWSIZING, true );
GetMenuBar()->Check( ID_TOGGLECOLSIZING, true ); GetMenuBar()->Check( ID_TOGGLECOLSIZING, true );
GetMenuBar()->Check( ID_TOGGLECOLMOVING, false );
GetMenuBar()->Check( ID_TOGGLEGRIDSIZING, true ); GetMenuBar()->Check( ID_TOGGLEGRIDSIZING, true );
GetMenuBar()->Check( ID_TOGGLEGRIDDRAGCELL, false ); GetMenuBar()->Check( ID_TOGGLEGRIDDRAGCELL, false );
GetMenuBar()->Check( ID_TOGGLEGRIDLINES, true ); GetMenuBar()->Check( ID_TOGGLEGRIDLINES, true );
@@ -429,6 +432,12 @@ void GridFrame::ToggleColSizing( wxCommandEvent& WXUNUSED(ev) )
GetMenuBar()->IsChecked( ID_TOGGLECOLSIZING ) ); GetMenuBar()->IsChecked( ID_TOGGLECOLSIZING ) );
} }
void GridFrame::ToggleColMoving( wxCommandEvent& WXUNUSED(ev) )
{
grid->EnableDragColMove(
GetMenuBar()->IsChecked( ID_TOGGLECOLMOVING ) );
}
void GridFrame::ToggleGridSizing( wxCommandEvent& WXUNUSED(ev) ) void GridFrame::ToggleGridSizing( wxCommandEvent& WXUNUSED(ev) )
{ {
grid->EnableDragGridSize( grid->EnableDragGridSize(
@@ -927,6 +936,11 @@ void GridFrame::OnSelectCell( wxGridEvent& ev )
<< _T(", ShiftDown: ")<< (ev.ShiftDown() ? 'T':'F') << _T(", ShiftDown: ")<< (ev.ShiftDown() ? 'T':'F')
<< _T(", AltDown: ")<< (ev.AltDown() ? 'T':'F') << _T(", AltDown: ")<< (ev.AltDown() ? 'T':'F')
<< _T(", MetaDown: ")<< (ev.MetaDown() ? 'T':'F') << _T(" )"); << _T(", MetaDown: ")<< (ev.MetaDown() ? 'T':'F') << _T(" )");
//Indicate whether this column was moved
if ( ((wxGrid *)ev.GetEventObject())->GetColPos( ev.GetCol() ) != ev.GetCol() )
logBuf << _T(" *** Column moved, current position: ") << ((wxGrid *)ev.GetEventObject())->GetColPos( ev.GetCol() );
wxLogMessage( wxT("%s"), logBuf.c_str() ); wxLogMessage( wxT("%s"), logBuf.c_str() );
// you must call Skip() if you want the default processing // you must call Skip() if you want the default processing

View File

@@ -37,6 +37,7 @@ class GridFrame : public wxFrame
void ToggleEditing( wxCommandEvent& ); void ToggleEditing( wxCommandEvent& );
void ToggleRowSizing( wxCommandEvent& ); void ToggleRowSizing( wxCommandEvent& );
void ToggleColSizing( wxCommandEvent& ); void ToggleColSizing( wxCommandEvent& );
void ToggleColMoving( wxCommandEvent& );
void ToggleGridSizing( wxCommandEvent& ); void ToggleGridSizing( wxCommandEvent& );
void ToggleGridDragCell ( wxCommandEvent& ); void ToggleGridDragCell ( wxCommandEvent& );
void ToggleGridLines( wxCommandEvent& ); void ToggleGridLines( wxCommandEvent& );
@@ -107,6 +108,7 @@ public:
ID_TOGGLEEDIT, ID_TOGGLEEDIT,
ID_TOGGLEROWSIZING, ID_TOGGLEROWSIZING,
ID_TOGGLECOLSIZING, ID_TOGGLECOLSIZING,
ID_TOGGLECOLMOVING,
ID_TOGGLEGRIDSIZING, ID_TOGGLEGRIDSIZING,
ID_TOGGLEGRIDDRAGCELL, ID_TOGGLEGRIDDRAGCELL,
ID_TOGGLEGRIDLINES, ID_TOGGLEGRIDLINES,

View File

@@ -2,7 +2,7 @@
// Name: src/generic/grid.cpp // Name: src/generic/grid.cpp
// Purpose: wxGrid and related classes // Purpose: wxGrid and related classes
// Author: Michael Bedward (based on code by Julian Smart, Robin Dunn) // Author: Michael Bedward (based on code by Julian Smart, Robin Dunn)
// Modified by: Robin Dunn, Vadim Zeitlin // Modified by: Robin Dunn, Vadim Zeitlin, Santiago Palacios
// Created: 1/08/1999 // Created: 1/08/1999
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Michael Bedward (mbedward@ozemail.com.au) // Copyright: (c) Michael Bedward (mbedward@ozemail.com.au)
@@ -104,6 +104,7 @@ DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_DCLICK) DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_ROW_SIZE) DEFINE_EVENT_TYPE(wxEVT_GRID_ROW_SIZE)
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE) DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE)
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_MOVE)
DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT) DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT)
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGE) DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGE)
DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL) DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL)
@@ -622,7 +623,7 @@ void wxGridCellTextEditor::Create(wxWindow* parent,
m_control = new wxTextCtrl(parent, id, wxEmptyString, m_control = new wxTextCtrl(parent, id, wxEmptyString,
wxDefaultPosition, wxDefaultSize wxDefaultPosition, wxDefaultSize
#if defined(__WXMSW__) #if defined(__WXMSW__)
, wxTE_PROCESS_TAB | wxTE_AUTO_SCROLL , wxTE_PROCESS_TAB | wxTE_AUTO_SCROLL | wxNO_BORDER
#endif #endif
); );
@@ -658,27 +659,33 @@ void wxGridCellTextEditor::SetSize(const wxRect& rectOrig)
rect.width -= 1; rect.width -= 1;
rect.height -= 1; rect.height -= 1;
} }
#else // !GTK #elif defined(__WXMSW__)
int extra_x = ( rect.x > 2 ) ? 2 : 1; if ( rect.x == 0 )
rect.x += 2;
else
rect.x += 3;
// MB: treat MSW separately here otherwise the caret doesn't show if ( rect.y == 0 )
// when the editor is in the first row. rect.y += 2;
#if defined(__WXMSW__) else
int extra_y = 2; rect.y += 3;
rect.width -= 2;
rect.height -= 2;
#else #else
int extra_x = ( rect.x > 2 ) ? 2 : 1;
int extra_y = ( rect.y > 2 ) ? 2 : 1; int extra_y = ( rect.y > 2 ) ? 2 : 1;
#endif
#if defined(__WXMOTIF__) #if defined(__WXMOTIF__)
extra_x *= 2; extra_x *= 2;
extra_y *= 2; extra_y *= 2;
#endif #endif
rect.SetLeft( wxMax(0, rect.x - extra_x) ); rect.SetLeft( wxMax(0, rect.x - extra_x) );
rect.SetTop( wxMax(0, rect.y - extra_y) ); rect.SetTop( wxMax(0, rect.y - extra_y) );
rect.SetRight( rect.GetRight() + 2 * extra_x ); rect.SetRight( rect.GetRight() + 2 * extra_x );
rect.SetBottom( rect.GetBottom() + 2 * extra_y ); rect.SetBottom( rect.GetBottom() + 2 * extra_y );
#endif // GTK/!GTK #endif
wxGridCellEditor::SetSize(rect); wxGridCellEditor::SetSize(rect);
} }
@@ -3506,6 +3513,15 @@ bool wxGridStringTable::InsertCols( size_t pos, size_t numCols )
return AppendCols( numCols ); return AppendCols( numCols );
} }
if ( !m_colLabels.IsEmpty() )
{
m_colLabels.Insert( wxEmptyString, pos, numCols );
size_t i;
for ( i = pos; i < pos + numCols; i++ )
m_colLabels[i] = wxGridTableBase::GetColLabelValue( i );
}
for ( row = 0; row < curNumRows; row++ ) for ( row = 0; row < curNumRows; row++ )
{ {
for ( col = pos; col < pos + numCols; col++ ) for ( col = pos; col < pos + numCols; col++ )
@@ -3580,9 +3596,20 @@ bool wxGridStringTable::DeleteCols( size_t pos, size_t numCols )
return false; return false;
} }
if ( numCols > curNumCols - pos ) int colID;
if ( GetView() )
colID = GetView()->GetColAt( pos );
else
colID = pos;
if ( numCols > curNumCols - colID )
{ {
numCols = curNumCols - pos; numCols = curNumCols - colID;
}
if ( !m_colLabels.IsEmpty() )
{
m_colLabels.RemoveAt( colID, numCols );
} }
for ( row = 0; row < curNumRows; row++ ) for ( row = 0; row < curNumRows; row++ )
@@ -3593,7 +3620,7 @@ bool wxGridStringTable::DeleteCols( size_t pos, size_t numCols )
} }
else else
{ {
m_data[row].RemoveAt( pos, numCols ); m_data[row].RemoveAt( colID, numCols );
} }
} }
@@ -3851,7 +3878,7 @@ void wxGridCornerLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
wxRendererNative::Get().DrawHeaderButton( this, dc, rect, 0 ); wxRendererNative::Get().DrawHeaderButton( this, dc, rect, 0 );
#else // !__WXGTK__ #else // !__WXGTK__
dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW), 1, wxSOLID) ); dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) );
dc.DrawLine( client_width - 1, client_height - 1, client_width - 1, 0 ); dc.DrawLine( client_width - 1, client_height - 1, client_width - 1, 0 );
dc.DrawLine( client_width - 1, client_height - 1, 0, client_height - 1 ); dc.DrawLine( client_width - 1, client_height - 1, 0, client_height - 1 );
dc.DrawLine( 0, 0, client_width, 0 ); dc.DrawLine( 0, 0, client_width, 0 );
@@ -4006,9 +4033,7 @@ static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
const wxArrayInt& BorderArray, int nMax, const wxArrayInt& BorderArray, int nMax,
bool clipToMinMax); bool clipToMinMax);
#define internalXToCol(x) CoordToRowOrCol(x, m_defaultColWidth, \ #define internalXToCol(x) XToCol(x, true)
m_minAcceptableColWidth, \
m_colRights, m_numCols, true)
#define internalYToRow(y) CoordToRowOrCol(y, m_defaultRowHeight, \ #define internalYToRow(y) CoordToRowOrCol(y, m_defaultRowHeight, \
m_minAcceptableRowHeight, \ m_minAcceptableRowHeight, \
m_rowBottoms, m_numRows, true) m_rowBottoms, m_numRows, true)
@@ -4376,6 +4401,8 @@ void wxGrid::Init()
m_cellHighlightPenWidth = 2; m_cellHighlightPenWidth = 2;
m_cellHighlightROPenWidth = 1; m_cellHighlightROPenWidth = 1;
m_canDragColMove = false;
m_cursorMode = WXGRID_CURSOR_SELECT_CELL; m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
m_winCapture = (wxWindow *)NULL; m_winCapture = (wxWindow *)NULL;
m_canDragRowSize = true; m_canDragRowSize = true;
@@ -4453,7 +4480,7 @@ void wxGrid::InitColWidths()
for ( int i = 0; i < m_numCols; i++ ) for ( int i = 0; i < m_numCols; i++ )
{ {
colRight += m_defaultColWidth; colRight = ( GetColPos( i ) + 1 ) * m_defaultColWidth;
m_colRights.Add( colRight ); m_colRights.Add( colRight );
} }
} }
@@ -4465,13 +4492,13 @@ int wxGrid::GetColWidth(int col) const
int wxGrid::GetColLeft(int col) const int wxGrid::GetColLeft(int col) const
{ {
return m_colRights.IsEmpty() ? col * m_defaultColWidth return m_colRights.IsEmpty() ? GetColPos( col ) * m_defaultColWidth
: m_colRights[col] - m_colWidths[col]; : m_colRights[col] - m_colWidths[col];
} }
int wxGrid::GetColRight(int col) const int wxGrid::GetColRight(int col) const
{ {
return m_colRights.IsEmpty() ? (col + 1) * m_defaultColWidth return m_colRights.IsEmpty() ? (GetColPos( col ) + 1) * m_defaultColWidth
: m_colRights[col]; : m_colRights[col];
} }
@@ -4503,7 +4530,7 @@ void wxGrid::CalcDimensions()
ch -= m_colLabelHeight; ch -= m_colLabelHeight;
// grid total size // grid total size
int w = m_numCols > 0 ? GetColRight(m_numCols - 1) + m_extraWidth + 1 : 0; int w = m_numCols > 0 ? GetColRight(GetColAt( m_numCols - 1 )) + m_extraWidth + 1 : 0;
int h = m_numRows > 0 ? GetRowBottom(m_numRows - 1) + m_extraHeight + 1 : 0; int h = m_numRows > 0 ? GetRowBottom(m_numRows - 1) + m_extraHeight + 1 : 0;
// take into account editor if shown // take into account editor if shown
@@ -4755,6 +4782,25 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
int numCols = msg.GetCommandInt2(); int numCols = msg.GetCommandInt2();
m_numCols += numCols; m_numCols += numCols;
if ( !m_colAt.IsEmpty() )
{
//Shift the column IDs
int i;
for ( i = 0; i < m_numCols - numCols; i++ )
{
if ( m_colAt[i] >= (int)pos )
m_colAt[i] += numCols;
}
m_colAt.Insert( pos, pos, numCols );
//Set the new columns' positions
for ( i = pos + 1; i < (int)pos + numCols; i++ )
{
m_colAt[i] = i;
}
}
if ( !m_colWidths.IsEmpty() ) if ( !m_colWidths.IsEmpty() )
{ {
m_colWidths.Insert( m_defaultColWidth, pos, numCols ); m_colWidths.Insert( m_defaultColWidth, pos, numCols );
@@ -4762,10 +4808,13 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
int right = 0; int right = 0;
if ( pos > 0 ) if ( pos > 0 )
right = m_colRights[pos - 1]; right = m_colRights[GetColAt( pos - 1 )];
for ( i = pos; i < m_numCols; i++ ) int colPos;
for ( colPos = pos; colPos < m_numCols; colPos++ )
{ {
i = GetColAt( colPos );
right += m_colWidths[i]; right += m_colWidths[i];
m_colRights[i] = right; m_colRights[i] = right;
} }
@@ -4798,6 +4847,19 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
int numCols = msg.GetCommandInt(); int numCols = msg.GetCommandInt();
int oldNumCols = m_numCols; int oldNumCols = m_numCols;
m_numCols += numCols; m_numCols += numCols;
if ( !m_colAt.IsEmpty() )
{
m_colAt.Add( 0, numCols );
//Set the new columns' positions
int i;
for ( i = oldNumCols; i < m_numCols; i++ )
{
m_colAt[i] = i;
}
}
if ( !m_colWidths.IsEmpty() ) if ( !m_colWidths.IsEmpty() )
{ {
m_colWidths.Add( m_defaultColWidth, numCols ); m_colWidths.Add( m_defaultColWidth, numCols );
@@ -4805,10 +4867,13 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
int right = 0; int right = 0;
if ( oldNumCols > 0 ) if ( oldNumCols > 0 )
right = m_colRights[oldNumCols - 1]; right = m_colRights[GetColAt( oldNumCols - 1 )];
for ( i = oldNumCols; i < m_numCols; i++ ) int colPos;
for ( colPos = oldNumCols; colPos < m_numCols; colPos++ )
{ {
i = GetColAt( colPos );
right += m_colWidths[i]; right += m_colWidths[i];
m_colRights[i] = right; m_colRights[i] = right;
} }
@@ -4836,14 +4901,32 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
int numCols = msg.GetCommandInt2(); int numCols = msg.GetCommandInt2();
m_numCols -= numCols; m_numCols -= numCols;
if ( !m_colAt.IsEmpty() )
{
int colID = GetColAt( pos );
m_colAt.RemoveAt( pos, numCols );
//Shift the column IDs
int colPos;
for ( colPos = 0; colPos < m_numCols; colPos++ )
{
if ( m_colAt[colPos] > colID )
m_colAt[colPos] -= numCols;
}
}
if ( !m_colWidths.IsEmpty() ) if ( !m_colWidths.IsEmpty() )
{ {
m_colWidths.RemoveAt( pos, numCols ); m_colWidths.RemoveAt( pos, numCols );
m_colRights.RemoveAt( pos, numCols ); m_colRights.RemoveAt( pos, numCols );
int w = 0; int w = 0;
for ( i = 0; i < m_numCols; i++ ) int colPos;
for ( colPos = 0; colPos < m_numCols; colPos++ )
{ {
i = GetColAt( colPos );
w += m_colWidths[i]; w += m_colWidths[i];
m_colRights[i] = w; m_colRights[i] = w;
} }
@@ -4979,8 +5062,11 @@ wxArrayInt wxGrid::CalcColLabelsExposed( const wxRegion& reg )
// find the cells within these bounds // find the cells within these bounds
// //
int col; int col;
for ( col = internalXToCol(left); col < m_numCols; col++ ) int colPos;
for ( colPos = GetColPos( internalXToCol(left) ); colPos < m_numCols; colPos++ )
{ {
col = GetColAt( colPos );
if ( GetColRight(col) < left ) if ( GetColRight(col) < left )
continue; continue;
@@ -5038,8 +5124,11 @@ wxGridCellCoordsArray wxGrid::CalcCellsExposed( const wxRegion& reg )
if ( GetRowTop(row) > bottom ) if ( GetRowTop(row) > bottom )
break; break;
for ( col = internalXToCol(left); col < m_numCols; col++ ) int colPos;
for ( colPos = GetColPos( internalXToCol(left) ); colPos < m_numCols; colPos++ )
{ {
col = GetColAt( colPos );
if ( GetColRight(col) <= left ) if ( GetColRight(col) <= left )
continue; continue;
@@ -5287,6 +5376,9 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
{ {
m_isDragging = true; m_isDragging = true;
m_colLabelWin->CaptureMouse(); m_colLabelWin->CaptureMouse();
if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL )
m_dragRowOrCol = XToCol( x );
} }
if ( event.LeftIsDown() ) if ( event.LeftIsDown() )
@@ -5330,6 +5422,63 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
} }
break; break;
case WXGRID_CURSOR_MOVE_COL:
{
if ( x < 0 )
m_moveToCol = GetColAt( 0 );
else
m_moveToCol = XToCol( x );
int markerX;
if ( m_moveToCol < 0 )
markerX = GetColRight( GetColAt( m_numCols - 1 ) );
else
markerX = GetColLeft( m_moveToCol );
if ( markerX != m_dragLastPos )
{
wxClientDC dc( m_colLabelWin );
int cw, ch;
m_colLabelWin->GetClientSize( &cw, &ch );
markerX++;
//Clean up the last indicator
if ( m_dragLastPos >= 0 )
{
wxPen pen( m_colLabelWin->GetBackgroundColour(), 2 );
dc.SetPen(pen);
dc.DrawLine( m_dragLastPos + 1, 0, m_dragLastPos + 1, ch );
dc.SetPen(wxNullPen);
if ( XToCol( m_dragLastPos ) != -1 )
DrawColLabel( dc, XToCol( m_dragLastPos ) );
}
//Moving to the same place? Don't draw a marker
if ( (m_moveToCol == m_dragRowOrCol)
|| (GetColPos( m_moveToCol ) == GetColPos( m_dragRowOrCol ) + 1)
|| (m_moveToCol < 0 && m_dragRowOrCol == GetColAt( m_numCols - 1 )))
{
m_dragLastPos = -1;
return;
}
//Draw the marker
wxPen pen( *wxBLUE, 2 );
dc.SetPen(pen);
dc.DrawLine( markerX, 0, markerX, ch );
dc.SetPen(wxNullPen);
m_dragLastPos = markerX - 1;
}
}
break;
// default label to suppress warnings about "enumeration value // default label to suppress warnings about "enumeration value
// 'xxx' not handled in switch // 'xxx' not handled in switch
default: default:
@@ -5370,31 +5519,46 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
if ( col >= 0 && if ( col >= 0 &&
!SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) ) !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
{ {
if ( !event.ShiftDown() && !event.CmdDown() ) if ( m_canDragColMove )
ClearSelection();
if ( m_selection )
{ {
if ( event.ShiftDown() ) //Show button as pressed
{ wxClientDC dc( m_colLabelWin );
m_selection->SelectBlock( 0, int colLeft = GetColLeft( col );
m_currentCellCoords.GetCol(), int colRight = GetColRight( col ) - 1;
GetNumberRows() - 1, col, dc.SetPen( wxPen( m_colLabelWin->GetBackgroundColour(), 1 ) );
event.ControlDown(), dc.DrawLine( colLeft, 1, colLeft, m_colLabelHeight-1 );
event.ShiftDown(), dc.DrawLine( colLeft, 1, colRight, 1 );
event.AltDown(),
event.MetaDown() );
}
else
{
m_selection->SelectCol( col,
event.ControlDown(),
event.ShiftDown(),
event.AltDown(),
event.MetaDown() );
}
}
ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, m_colLabelWin); ChangeCursorMode(WXGRID_CURSOR_MOVE_COL, m_colLabelWin);
}
else
{
if ( !event.ShiftDown() && !event.CmdDown() )
ClearSelection();
if ( m_selection )
{
if ( event.ShiftDown() )
{
m_selection->SelectBlock( 0,
m_currentCellCoords.GetCol(),
GetNumberRows() - 1, col,
event.ControlDown(),
event.ShiftDown(),
event.AltDown(),
event.MetaDown() );
}
else
{
m_selection->SelectCol( col,
event.ControlDown(),
event.ShiftDown(),
event.AltDown(),
event.MetaDown() );
}
}
ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, m_colLabelWin);
}
} }
} }
else else
@@ -5434,14 +5598,26 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
// //
else if ( event.LeftUp() ) else if ( event.LeftUp() )
{ {
if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL ) switch ( m_cursorMode )
{ {
DoEndDragResizeCol(); case WXGRID_CURSOR_RESIZE_COL:
{
DoEndDragResizeCol();
// Note: we are ending the event *after* doing // Note: we are ending the event *after* doing
// default processing in this case // default processing in this case
// //
SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event ); SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event );
}
break;
case WXGRID_CURSOR_MOVE_COL:
{
DoEndDragMoveCol();
SendEvent( wxEVT_GRID_COL_MOVE, -1, m_dragRowOrCol, event );
}
break;
} }
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_colLabelWin); ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_colLabelWin);
@@ -5536,7 +5712,8 @@ void wxGrid::ChangeCursorMode(CursorMode mode,
_T("RESIZE_ROW"), _T("RESIZE_ROW"),
_T("RESIZE_COL"), _T("RESIZE_COL"),
_T("SELECT_ROW"), _T("SELECT_ROW"),
_T("SELECT_COL") _T("SELECT_COL"),
_T("MOVE_COL"),
}; };
wxLogTrace(_T("grid"), wxLogTrace(_T("grid"),
@@ -5577,6 +5754,10 @@ void wxGrid::ChangeCursorMode(CursorMode mode,
win->SetCursor( m_colResizeCursor ); win->SetCursor( m_colResizeCursor );
break; break;
case WXGRID_CURSOR_MOVE_COL:
win->SetCursor( wxCursor(wxCURSOR_HAND) );
break;
default: default:
win->SetCursor( *wxSTANDARD_CURSOR ); win->SetCursor( *wxSTANDARD_CURSOR );
break; break;
@@ -6099,6 +6280,112 @@ void wxGrid::DoEndDragResizeCol()
} }
} }
void wxGrid::DoEndDragMoveCol()
{
//The user clicked on the column but didn't actually drag
if ( m_dragLastPos < 0 )
{
m_colLabelWin->Refresh(); //Do this to "unpress" the column
return;
}
int newPos;
if ( m_moveToCol == -1 )
newPos = m_numCols - 1;
else
{
newPos = GetColPos( m_moveToCol );
if ( newPos > GetColPos( m_dragRowOrCol ) )
newPos--;
}
SetColPos( m_dragRowOrCol, newPos );
}
void wxGrid::SetColPos( int colID, int newPos )
{
if ( m_colAt.IsEmpty() )
{
m_colAt.Alloc( m_numCols );
int i;
for ( i = 0; i < m_numCols; i++ )
{
m_colAt.Add( i );
}
}
int oldPos = GetColPos( colID );
//Reshuffle the m_colAt array
if ( newPos > oldPos )
{
int i;
for ( i = oldPos; i < newPos; i++ )
{
m_colAt[i] = m_colAt[i+1];
}
}
else
{
int i;
for ( i = oldPos; i > newPos; i-- )
{
m_colAt[i] = m_colAt[i-1];
}
}
m_colAt[newPos] = colID;
//Recalculate the column rights
if ( !m_colWidths.IsEmpty() )
{
int colRight = 0;
int colPos;
for ( colPos = 0; colPos < m_numCols; colPos++ )
{
int colID = GetColAt( colPos );
colRight += m_colWidths[colID];
m_colRights[colID] = colRight;
}
}
m_colLabelWin->Refresh();
m_gridWin->Refresh();
}
void wxGrid::EnableDragColMove( bool enable )
{
if ( m_canDragColMove == enable )
return;
m_canDragColMove = enable;
if ( !m_canDragColMove )
{
m_colAt.Clear();
//Recalculate the column rights
if ( !m_colWidths.IsEmpty() )
{
int colRight = 0;
int colPos;
for ( colPos = 0; colPos < m_numCols; colPos++ )
{
colRight += m_colWidths[colPos];
m_colRights[colPos] = colRight;
}
}
m_colLabelWin->Refresh();
m_gridWin->Refresh();
}
}
// //
// ------ interaction with data model // ------ interaction with data model
// //
@@ -7094,7 +7381,7 @@ void wxGrid::DrawGridSpace( wxDC& dc )
int right, bottom; int right, bottom;
CalcUnscrolledPosition( cw, ch, &right, &bottom ); CalcUnscrolledPosition( cw, ch, &right, &bottom );
int rightCol = m_numCols > 0 ? GetColRight(m_numCols - 1) : 0; int rightCol = m_numCols > 0 ? GetColRight(GetColAt( m_numCols - 1 )) : 0;
int bottomRow = m_numRows > 0 ? GetRowBottom(m_numRows - 1) : 0; int bottomRow = m_numRows > 0 ? GetRowBottom(m_numRows - 1) : 0;
if ( right > rightCol || bottom > bottomRow ) if ( right > rightCol || bottom > bottomRow )
@@ -7315,13 +7602,13 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
// avoid drawing grid lines past the last row and col // avoid drawing grid lines past the last row and col
// //
right = wxMin( right, GetColRight(m_numCols - 1) ); right = wxMin( right, GetColRight(GetColAt( m_numCols - 1 )) );
bottom = wxMin( bottom, GetRowBottom(m_numRows - 1) ); bottom = wxMin( bottom, GetRowBottom(m_numRows - 1) );
// no gridlines inside multicells, clip them out // no gridlines inside multicells, clip them out
int leftCol = internalXToCol(left); int leftCol = GetColPos( internalXToCol(left) );
int topRow = internalYToRow(top); int topRow = internalYToRow(top);
int rightCol = internalXToCol(right); int rightCol = GetColPos( internalXToCol(right) );
int bottomRow = internalYToRow(bottom); int bottomRow = internalYToRow(bottom);
#ifndef __WXMAC__ #ifndef __WXMAC__
@@ -7333,8 +7620,11 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
for (j=topRow; j<bottomRow; j++) for (j=topRow; j<bottomRow; j++)
{ {
for (i=leftCol; i<rightCol; i++) int colPos;
for (colPos=leftCol; colPos<rightCol; colPos++)
{ {
i = GetColAt( colPos );
GetCellSize( j, i, &cell_rows, &cell_cols ); GetCellSize( j, i, &cell_rows, &cell_cols );
if ((cell_rows > 1) || (cell_cols > 1)) if ((cell_rows > 1) || (cell_cols > 1))
{ {
@@ -7399,8 +7689,11 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & WXUNUSED(reg) )
// vertical grid lines // vertical grid lines
// //
for ( i = internalXToCol(left); i < m_numCols; i++ ) int colPos;
for ( colPos = leftCol; colPos < m_numCols; colPos++ )
{ {
i = GetColAt( colPos );
int colRight = GetColRight(i) - 1; int colRight = GetColRight(i) - 1;
if ( colRight > right ) if ( colRight > right )
{ {
@@ -7452,7 +7745,7 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row )
int rowTop = GetRowTop(row), int rowTop = GetRowTop(row),
rowBottom = GetRowBottom(row) - 1; rowBottom = GetRowBottom(row) - 1;
dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW), 1, wxSOLID) ); dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) );
dc.DrawLine( m_rowLabelWidth - 1, rowTop, m_rowLabelWidth - 1, rowBottom ); dc.DrawLine( m_rowLabelWidth - 1, rowTop, m_rowLabelWidth - 1, rowBottom );
dc.DrawLine( 0, rowTop, 0, rowBottom ); dc.DrawLine( 0, rowTop, 0, rowBottom );
dc.DrawLine( 0, rowBottom, m_rowLabelWidth, rowBottom ); dc.DrawLine( 0, rowBottom, m_rowLabelWidth, rowBottom );
@@ -7511,7 +7804,7 @@ void wxGrid::DrawColLabel( wxDC& dc, int col )
#else #else
int colRight = GetColRight(col) - 1; int colRight = GetColRight(col) - 1;
dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW), 1, wxSOLID) ); dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) );
dc.DrawLine( colRight, 0, colRight, m_colLabelHeight - 1 ); dc.DrawLine( colRight, 0, colRight, m_colLabelHeight - 1 );
dc.DrawLine( colLeft, 0, colRight, 0 ); dc.DrawLine( colLeft, 0, colRight, 0 );
dc.DrawLine( colLeft, m_colLabelHeight - 1, dc.DrawLine( colLeft, m_colLabelHeight - 1,
@@ -7887,16 +8180,13 @@ void wxGrid::ShowCellEditControl()
if (rect.x < 0) if (rect.x < 0)
nXMove = rect.x; nXMove = rect.x;
// performed in PaintBackground()
#if 0
// erase the highlight and the cell contents because the editor // erase the highlight and the cell contents because the editor
// might not cover the entire cell // might not cover the entire cell
wxClientDC dc( m_gridWin ); wxClientDC dc( m_gridWin );
PrepareDC( dc ); PrepareDC( dc );
dc.SetBrush(*wxLIGHT_GREY_BRUSH); //wxBrush(attr->GetBackgroundColour(), wxSOLID)); dc.SetBrush(wxBrush(GetCellAttr(row, col)->GetBackgroundColour(), wxSOLID));
dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(rect); dc.DrawRectangle(rect);
#endif
// cell is shifted by one pixel // cell is shifted by one pixel
// However, don't allow x or y to become negative // However, don't allow x or y to become negative
@@ -8135,10 +8425,65 @@ int wxGrid::YToRow( int y )
m_minAcceptableRowHeight, m_rowBottoms, m_numRows, false); m_minAcceptableRowHeight, m_rowBottoms, m_numRows, false);
} }
int wxGrid::XToCol( int x ) int wxGrid::XToCol( int x, bool clipToMinMax )
{ {
return CoordToRowOrCol(x, m_defaultColWidth, if (x < 0)
m_minAcceptableColWidth, m_colRights, m_numCols, false); return clipToMinMax && (m_numCols > 0) ? GetColAt( 0 ) : -1;
if (!m_defaultColWidth)
m_defaultColWidth = 1;
int maxPos = x / m_defaultColWidth;
int minPos = 0;
if (m_colRights.IsEmpty())
{
if(maxPos < m_numCols)
return GetColAt( maxPos );
return clipToMinMax ? GetColAt( m_numCols - 1 ) : -1;
}
if ( maxPos >= m_numCols)
maxPos = m_numCols - 1;
else
{
if ( x >= m_colRights[GetColAt( maxPos )])
{
minPos = maxPos;
if (m_minAcceptableColWidth)
maxPos = x / m_minAcceptableColWidth;
else
maxPos = m_numCols - 1;
}
if ( maxPos >= m_numCols)
maxPos = m_numCols - 1;
}
//X is beyond the last column
if ( x >= m_colRights[GetColAt( maxPos )])
return clipToMinMax ? GetColAt( maxPos ) : -1;
//X is before the first column
if ( x < m_colRights[GetColAt( 0 )] )
return GetColAt( 0 );
//Perform a binary search
while ( maxPos - minPos > 0 )
{
wxCHECK_MSG(m_colRights[GetColAt( minPos )] <= x && x < m_colRights[GetColAt( maxPos )],
0, _T("wxGrid: internal error in XToCol"));
if (x >= m_colRights[GetColAt( maxPos - 1 )])
return GetColAt( maxPos );
else
maxPos--;
int median = minPos + (maxPos - minPos + 1) / 2;
if (x < m_colRights[GetColAt( median )])
maxPos = median;
else
minPos = median;
}
return GetColAt( maxPos );
} }
// return the row number that that the y coord is near the edge of, or // return the row number that that the y coord is near the edge of, or
@@ -8418,11 +8763,12 @@ bool wxGrid::MoveCursorLeft( bool expandSelection )
HighlightBlock( m_currentCellCoords, m_selectingKeyboard ); HighlightBlock( m_currentCellCoords, m_selectingKeyboard );
} }
} }
else if ( m_currentCellCoords.GetCol() > 0 ) else if ( GetColPos( m_currentCellCoords.GetCol() ) > 0 )
{ {
int row = m_currentCellCoords.GetRow(); int row = m_currentCellCoords.GetRow();
int col = m_currentCellCoords.GetCol() - 1; int col = GetColAt( GetColPos( m_currentCellCoords.GetCol() ) - 1 );
ClearSelection(); ClearSelection();
MakeCellVisible( row, col ); MakeCellVisible( row, col );
SetCurrentCell( row, col ); SetCurrentCell( row, col );
} }
@@ -8452,11 +8798,12 @@ bool wxGrid::MoveCursorRight( bool expandSelection )
HighlightBlock( m_currentCellCoords, m_selectingKeyboard ); HighlightBlock( m_currentCellCoords, m_selectingKeyboard );
} }
} }
else if ( m_currentCellCoords.GetCol() < m_numCols - 1 ) else if ( GetColPos( m_currentCellCoords.GetCol() ) < m_numCols - 1 )
{ {
int row = m_currentCellCoords.GetRow(); int row = m_currentCellCoords.GetRow();
int col = m_currentCellCoords.GetCol() + 1; int col = GetColAt( GetColPos( m_currentCellCoords.GetCol() ) + 1 );
ClearSelection(); ClearSelection();
MakeCellVisible( row, col ); MakeCellVisible( row, col );
SetCurrentCell( row, col ); SetCurrentCell( row, col );
} }
@@ -9812,7 +10159,7 @@ void wxGrid::SetColSize( int col, int width )
// should we check that it's bigger than GetColMinimalWidth(col) here? // should we check that it's bigger than GetColMinimalWidth(col) here?
// (VZ) // (VZ)
// No, because it is reasonable to assume the library user know's // No, because it is reasonable to assume the library user know's
// what he is doing. However whe should test against the weaker // what he is doing. However we should test against the weaker
// constraint of minimalAcceptableWidth, as this breaks rendering // constraint of minimalAcceptableWidth, as this breaks rendering
// //
// This test then fixes sf.net bug #645734 // This test then fixes sf.net bug #645734
@@ -9843,8 +10190,10 @@ void wxGrid::SetColSize( int col, int width )
m_colWidths[col] = w; m_colWidths[col] = w;
int i; int i;
for ( i = col; i < m_numCols; i++ ) int colPos;
for ( colPos = GetColPos( col ); colPos < m_numCols; colPos++ )
{ {
i = GetColAt( colPos );
m_colRights[i] += diff; m_colRights[i] += diff;
} }