From b62f94ff4834ab607a888826ec7bf4404837f400 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 15 Mar 2007 17:25:15 +0000 Subject: [PATCH] added wxGridUpdateLocker helper class wrapping Begin/EndBatch() calls in a more convenient and safe way git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44833 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + docs/latex/wx/classes.tex | 1 + docs/latex/wx/grid.tex | 8 ++++ docs/latex/wx/gupdlock.tex | 81 ++++++++++++++++++++++++++++++++++++++ include/wx/generic/grid.h | 41 +++++++++++++++++++ samples/grid/griddemo.cpp | 6 +-- src/common/dbgrid.cpp | 4 +- src/generic/grid.cpp | 20 ++++------ 8 files changed, 143 insertions(+), 19 deletions(-) create mode 100644 docs/latex/wx/gupdlock.tex diff --git a/docs/changes.txt b/docs/changes.txt index 0dc9025a39..0ea04eb93f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -39,6 +39,7 @@ All: - Fixed crashes in helpview when opening a file. - Added wxMutex::LockTimeout() (Aleksandr Napylov) - Set locale to the default in all ports, not just wxGTK +- Added wxGridUpdateLocker helper class (Evgeniy Tarassov) wxGTK: diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex index 50f5926823..5046e4ceaa 100644 --- a/docs/latex/wx/classes.tex +++ b/docs/latex/wx/classes.tex @@ -188,6 +188,7 @@ \input gridrend.tex \input gridtbl.tex \input gridsizr.tex +\input gupdlock.tex \input hashmap.tex \input hashset.tex \input hash.tex diff --git a/docs/latex/wx/grid.tex b/docs/latex/wx/grid.tex index 0231c365d0..62b640cda8 100644 --- a/docs/latex/wx/grid.tex +++ b/docs/latex/wx/grid.tex @@ -253,6 +253,10 @@ the grid is suppressed. Each call to BeginBatch must be matched by a later call modification can be enclosed between BeginBatch and EndBatch calls to avoid screen flicker. The final EndBatch will cause the grid to be repainted. +\wxheading{See also} + +\helpref{wxGridUpdateLocker}{wxgridupdatelocker} + \membersection{wxGrid::BlockToDeviceRect}\label{wxgridblocktodevicerect} @@ -514,6 +518,10 @@ EndBatch. Code that does a lot of grid modification can be enclosed between BeginBatch and EndBatch calls to avoid screen flicker. The final EndBatch will cause the grid to be repainted. +\wxheading{See also} + +\helpref{wxGridUpdateLocker}{wxgridupdatelocker} + \membersection{wxGrid::Fit}\label{wxgridfit} diff --git a/docs/latex/wx/gupdlock.tex b/docs/latex/wx/gupdlock.tex new file mode 100644 index 0000000000..f0c6a3ce2e --- /dev/null +++ b/docs/latex/wx/gupdlock.tex @@ -0,0 +1,81 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: gupdlock.tex +%% Purpose: wxGridUpdateLocker documentation +%% Author: Evgeniy Tarassov +%% Created: 2007-03-15 +%% RCS-ID: $Id$ +%% Copyright: (c) 2007 TT-Solutions SARL +%% License: wxWindows license +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxGridUpdateLocker}}\label{wxgridupdatelocker} + +This small class can be used to prevent \helpref{wxGrid}{wxgrid} from redrawing +during its lifetime by calling \helpref{wxGrid::BeginBatch}{wxgridbeginbatch} +in its constructor and \helpref{wxGrid::EndBatch}{wxgridendbatch} in its +destructor. It is typically used in a function performing several operations +with a grid which would otherwise result in flicker. For example: + +{\small +\begin{verbatim} + void MyFrame::Foo() + { + m_grid = new wxGrid(this, ...); + + wxGridUpdateLocker noUpdates(m_grid); + m_grid->AppendColumn(); + ... many other operations with m_grid... + m_grid->AppendRow(); + + // destructor called, grid refreshed + } +\end{verbatim} +} + +Using this class is easier and safer than calling +\helpref{BeginBatch}{wxgridbeginbatch} and \helpref{EndBatch}{wxgridendbatch} +because you don't risk not to call the latter (due to an exception for example). + +\wxheading{Derived from} + +None. + +\wxheading{Include files} + + + + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxGridUpdateLocker::wxGridUpdateLocker}\label{wxgridupdatelockerctor} + +\func{}{wxGridUpdateLocker}{\param{wxGrid *}{grid = \NULL}} + +Creates an object preventing the updates of the specified \arg{grid}. The +parameter could be \NULL in which case nothing is done. If \arg{grid} is +non-\NULL then the grid must exist for longer than wxGridUpdateLocker object +itself. + +The default constructor could be followed by a call to +\helpref{wxGridUpdateLocker::Create}{wxgridupdatelockercreate} to set the +grid object later. + + + +\membersection{wxGridUpdateLocker::\destruct{wxGridUpdateLocker}}\label{wxgridupdatelockerdtor} + +\func{}{\destruct{wxGridUpdateLocker}}{\void} + +Destructor reenables updates for the grid this object is associated with. + + + +\membersection{wxGridUpdateLocker::Create}\label{wxgridupdatelockercreate} + +\func{void}{Create}{\param{wxGrid* }{grid}} + +This method can be called if the object had been constructed using the default +constructor. It must not be called more than once. + + diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index 4229751aa1..2d04e59b6c 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -2007,6 +2007,47 @@ protected: }; +// ---------------------------------------------------------------------------- +// wxGridUpdateLocker prevents updates to a grid during its lifetime +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_ADV wxGridUpdateLocker +{ +public: + // if the pointer is NULL, Create() can be called later + wxGridUpdateLocker(wxGrid *grid = NULL) + { + Init(grid); + } + + // can be called if ctor was used with a NULL pointer, must not be called + // more than once + void Create(wxGrid *grid) + { + wxASSERT_MSG( !m_grid, _T("shouldn't be called more than once") ); + + Init(grid); + } + + ~wxGridUpdateLocker() + { + if ( m_grid ) + m_grid->EndBatch(); + } + +private: + void Init(wxGrid *grid) + { + m_grid = grid; + if ( m_grid ) + m_grid->BeginBatch(); + } + + wxGrid *m_grid; + + DECLARE_NO_COPY_CLASS(wxGridUpdateLocker) +}; + // ---------------------------------------------------------------------------- // Grid event class and event types // ---------------------------------------------------------------------------- diff --git a/samples/grid/griddemo.cpp b/samples/grid/griddemo.cpp index 387fb57614..85867844af 100644 --- a/samples/grid/griddemo.cpp +++ b/samples/grid/griddemo.cpp @@ -668,7 +668,7 @@ void GridFrame::DeleteSelectedRows( wxCommandEvent& WXUNUSED(ev) ) { if ( grid->IsSelection() ) { - grid->BeginBatch(); + wxGridUpdateLocker locker(grid); for ( int n = 0; n < grid->GetNumberRows(); ) { if ( grid->IsInSelection( n , 0 ) ) @@ -676,7 +676,6 @@ void GridFrame::DeleteSelectedRows( wxCommandEvent& WXUNUSED(ev) ) else n++; } - grid->EndBatch(); } } @@ -685,7 +684,7 @@ void GridFrame::DeleteSelectedCols( wxCommandEvent& WXUNUSED(ev) ) { if ( grid->IsSelection() ) { - grid->BeginBatch(); + wxGridUpdateLocker locker(grid); for ( int n = 0; n < grid->GetNumberCols(); ) { if ( grid->IsInSelection( 0 , n ) ) @@ -693,7 +692,6 @@ void GridFrame::DeleteSelectedCols( wxCommandEvent& WXUNUSED(ev) ) else n++; } - grid->EndBatch(); } } diff --git a/src/common/dbgrid.cpp b/src/common/dbgrid.cpp index d8b13172a3..634be020d8 100644 --- a/src/common/dbgrid.cpp +++ b/src/common/dbgrid.cpp @@ -203,11 +203,12 @@ bool wxDbGridTableBase::AssignDbTable(wxDbTable *tab, int count, bool takeOwners { wxDbGridCellAttrProvider *provider; + wxGridUpdateLocker locker(GetView()); + //Remove Information from grid about old data if (GetView()) { wxGrid *grid = GetView(); - grid->BeginBatch(); grid->ClearSelection(); if (grid->IsCellEditControlEnabled()) { @@ -250,7 +251,6 @@ bool wxDbGridTableBase::AssignDbTable(wxDbTable *tab, int count, bool takeOwners wxGrid * grid = GetView(); wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_rowtotal); grid->ProcessTableMessage(msg); - grid->EndBatch(); } m_dbowner = takeOwnership; m_rowmodified = false; diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 20121718e0..e8ef3ce6dd 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -10595,8 +10595,9 @@ int wxGrid::SetOrCalcColumnSizes(bool calcOnly, bool setAsMin) { int width = m_rowLabelWidth; - if ( !calcOnly ) - BeginBatch(); + wxGridUpdateLocker locker; + if(!calcOnly) + locker.Create(this); for ( int col = 0; col < m_numCols; col++ ) { @@ -10606,9 +10607,6 @@ int wxGrid::SetOrCalcColumnSizes(bool calcOnly, bool setAsMin) width += GetColWidth(col); } - if ( !calcOnly ) - EndBatch(); - return width; } @@ -10616,8 +10614,9 @@ int wxGrid::SetOrCalcRowSizes(bool calcOnly, bool setAsMin) { int height = m_colLabelHeight; - if ( !calcOnly ) - BeginBatch(); + wxGridUpdateLocker locker; + if(!calcOnly) + locker.Create(this); for ( int row = 0; row < m_numRows; row++ ) { @@ -10627,15 +10626,12 @@ int wxGrid::SetOrCalcRowSizes(bool calcOnly, bool setAsMin) height += GetRowHeight(row); } - if ( !calcOnly ) - EndBatch(); - return height; } void wxGrid::AutoSize() { - BeginBatch(); + wxGridUpdateLocker locker(this); // we need to round up the size of the scrollable area to a multiple of // scroll step to ensure that we don't get the scrollbars when we're sized @@ -10701,8 +10697,6 @@ void wxGrid::AutoSize() // client size but also leave space for (not needed any more) scrollbars SetScrollbars(0, 0, 0, 0, 0, 0, true); SetClientSize(sizeFit.x + m_rowLabelWidth, sizeFit.y + m_colLabelHeight); - - EndBatch(); } void wxGrid::AutoSizeRowLabelSize( int row ) -- 2.45.2