1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/generic/private/grid.h
3 // Purpose:     Private wxGrid structures
4 // Author:      Michael Bedward (based on code by Julian Smart, Robin Dunn)
5 // Modified by: Santiago Palacios
6 // Created:     1/08/1999
7 // Copyright:   (c) Michael Bedward
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef _WX_GENERIC_GRID_PRIVATE_H_
12 #define _WX_GENERIC_GRID_PRIVATE_H_
13 
14 #include "wx/defs.h"
15 
16 #if wxUSE_GRID
17 
18 #include "wx/headerctrl.h"
19 
20 // ----------------------------------------------------------------------------
21 // array classes
22 // ----------------------------------------------------------------------------
23 
24 WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridCellAttr *, wxArrayAttrs,
25                                  class WXDLLIMPEXP_ADV);
26 
27 WX_DECLARE_HASH_MAP_WITH_DECL(wxLongLong_t, wxGridCellAttr*,
28                               wxIntegerHash, wxIntegerEqual,
29                               wxGridCoordsToAttrMap, class WXDLLIMPEXP_CORE);
30 
31 
32 // ----------------------------------------------------------------------------
33 // private classes
34 // ----------------------------------------------------------------------------
35 
36 // header column providing access to the column information stored in wxGrid
37 // via wxHeaderColumn interface
38 class wxGridHeaderColumn : public wxHeaderColumn
39 {
40 public:
wxGridHeaderColumn(wxGrid * grid,int col)41     wxGridHeaderColumn(wxGrid *grid, int col)
42         : m_grid(grid),
43           m_col(col)
44     {
45     }
46 
GetTitle()47     virtual wxString GetTitle() const wxOVERRIDE { return m_grid->GetColLabelValue(m_col); }
GetBitmap()48     virtual wxBitmap GetBitmap() const wxOVERRIDE { return wxNullBitmap; }
GetWidth()49     virtual int GetWidth() const wxOVERRIDE { return m_grid->GetColSize(m_col); }
GetMinWidth()50     virtual int GetMinWidth() const wxOVERRIDE { return m_grid->GetColMinimalWidth(m_col); }
GetAlignment()51     virtual wxAlignment GetAlignment() const wxOVERRIDE
52     {
53         int horz,
54             vert;
55         m_grid->GetColLabelAlignment(&horz, &vert);
56 
57         return static_cast<wxAlignment>(horz);
58     }
59 
GetFlags()60     virtual int GetFlags() const wxOVERRIDE
61     {
62         // we can't know in advance whether we can sort by this column or not
63         // with wxGrid API so suppose we can by default
64         int flags = wxCOL_SORTABLE;
65         if ( m_grid->CanDragColSize(m_col) )
66             flags |= wxCOL_RESIZABLE;
67         if ( m_grid->CanDragColMove() )
68             flags |= wxCOL_REORDERABLE;
69         if ( GetWidth() == 0 )
70             flags |= wxCOL_HIDDEN;
71 
72         return flags;
73     }
74 
IsSortKey()75     virtual bool IsSortKey() const wxOVERRIDE
76     {
77         return m_grid->IsSortingBy(m_col);
78     }
79 
IsSortOrderAscending()80     virtual bool IsSortOrderAscending() const wxOVERRIDE
81     {
82         return m_grid->IsSortOrderAscending();
83     }
84 
85 private:
86     // these really should be const but are not because the column needs to be
87     // assignable to be used in a wxVector (in STL build, in non-STL build we
88     // avoid the need for this)
89     wxGrid *m_grid;
90     int m_col;
91 };
92 
93 // header control retrieving column information from the grid
94 class wxGridHeaderCtrl : public wxHeaderCtrl
95 {
96 public:
wxGridHeaderCtrl(wxGrid * owner)97     wxGridHeaderCtrl(wxGrid *owner)
98         : wxHeaderCtrl(owner,
99                        wxID_ANY,
100                        wxDefaultPosition,
101                        wxDefaultSize,
102                        (owner->CanHideColumns() ? wxHD_ALLOW_HIDE : 0) |
103                        (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0))
104     {
105         m_inResizing = 0;
106     }
107 
108     // Special method to call from wxGrid::DoSetColSize(), see comments there.
UpdateIfNotResizing(unsigned int idx)109     void UpdateIfNotResizing(unsigned int idx)
110     {
111         if ( !m_inResizing )
112             UpdateColumn(idx);
113     }
114 
115 protected:
GetColumn(unsigned int idx)116     virtual const wxHeaderColumn& GetColumn(unsigned int idx) const wxOVERRIDE
117     {
118         return m_columns[idx];
119     }
120 
GetOwner()121     wxGrid *GetOwner() const { return static_cast<wxGrid *>(GetParent()); }
122 
123 private:
GetDummyMouseEvent()124     wxMouseEvent GetDummyMouseEvent() const
125     {
126         // make up a dummy event for the grid event to use -- unfortunately we
127         // can't do anything else here
128         wxMouseEvent e;
129         e.SetState(wxGetMouseState());
130         GetOwner()->ScreenToClient(&e.m_x, &e.m_y);
131         return e;
132     }
133 
134     // override the base class method to update our m_columns array
OnColumnCountChanging(unsigned int count)135     virtual void OnColumnCountChanging(unsigned int count) wxOVERRIDE
136     {
137         const unsigned countOld = m_columns.size();
138         if ( count < countOld )
139         {
140             // just discard the columns which don't exist any more (notice that
141             // we can't use resize() here as it would require the vector
142             // value_type, i.e. wxGridHeaderColumn to be default constructible,
143             // which it is not)
144             m_columns.erase(m_columns.begin() + count, m_columns.end());
145         }
146         else // new columns added
147         {
148             // add columns for the new elements
149             for ( unsigned n = countOld; n < count; n++ )
150                 m_columns.push_back(wxGridHeaderColumn(GetOwner(), n));
151         }
152     }
153 
154     // override to implement column auto sizing
UpdateColumnWidthToFit(unsigned int idx,int WXUNUSED (widthTitle))155     virtual bool UpdateColumnWidthToFit(unsigned int idx, int WXUNUSED(widthTitle)) wxOVERRIDE
156     {
157         GetOwner()->HandleColumnAutosize(idx, GetDummyMouseEvent());
158 
159         return true;
160     }
161 
162     // overridden to react to the actions using the columns popup menu
UpdateColumnVisibility(unsigned int idx,bool show)163     virtual void UpdateColumnVisibility(unsigned int idx, bool show) wxOVERRIDE
164     {
165         GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0);
166 
167         // as this is done by the user we should notify the main program about
168         // it
169         GetOwner()->SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, idx,
170                                       GetDummyMouseEvent());
171     }
172 
173     // overridden to react to the columns order changes in the customization
174     // dialog
UpdateColumnsOrder(const wxArrayInt & order)175     virtual void UpdateColumnsOrder(const wxArrayInt& order) wxOVERRIDE
176     {
177         GetOwner()->SetColumnsOrder(order);
178     }
179 
180 
181     // event handlers forwarding wxHeaderCtrl events to wxGrid
OnClick(wxHeaderCtrlEvent & event)182     void OnClick(wxHeaderCtrlEvent& event)
183     {
184         GetOwner()->SendEvent(wxEVT_GRID_LABEL_LEFT_CLICK,
185                               -1, event.GetColumn(),
186                               GetDummyMouseEvent());
187 
188         GetOwner()->DoColHeaderClick(event.GetColumn());
189     }
190 
OnDoubleClick(wxHeaderCtrlEvent & event)191     void OnDoubleClick(wxHeaderCtrlEvent& event)
192     {
193         if ( !GetOwner()->SendEvent(wxEVT_GRID_LABEL_LEFT_DCLICK,
194                                     -1, event.GetColumn(),
195                                     GetDummyMouseEvent()) )
196         {
197             event.Skip();
198         }
199     }
200 
OnRightClick(wxHeaderCtrlEvent & event)201     void OnRightClick(wxHeaderCtrlEvent& event)
202     {
203         if ( !GetOwner()->SendEvent(wxEVT_GRID_LABEL_RIGHT_CLICK,
204                                     -1, event.GetColumn(),
205                                     GetDummyMouseEvent()) )
206         {
207             event.Skip();
208         }
209     }
210 
OnBeginResize(wxHeaderCtrlEvent & event)211     void OnBeginResize(wxHeaderCtrlEvent& event)
212     {
213         GetOwner()->DoHeaderStartDragResizeCol(event.GetColumn());
214 
215         event.Skip();
216     }
217 
OnResizing(wxHeaderCtrlEvent & event)218     void OnResizing(wxHeaderCtrlEvent& event)
219     {
220         // Calling wxGrid method results in a call to our own UpdateColumn()
221         // because it ends up in wxGrid::SetColSize() which must indeed update
222         // the column when it's called by the program -- but in the case where
223         // the size change comes from the column itself, it is useless and, in
224         // fact, harmful, as it results in extra flicker due to the inefficient
225         // implementation of UpdateColumn() in wxMSW wxHeaderCtrl, so skip
226         // calling it from our overridden version by setting this flag for the
227         // duration of this function execution and checking it in our
228         // UpdateIfNotResizing().
229         m_inResizing++;
230 
231         GetOwner()->DoHeaderDragResizeCol(event.GetWidth());
232 
233         m_inResizing--;
234     }
235 
OnEndResize(wxHeaderCtrlEvent & event)236     void OnEndResize(wxHeaderCtrlEvent& event)
237     {
238         GetOwner()->DoHeaderEndDragResizeCol(event.GetWidth());
239 
240         event.Skip();
241     }
242 
OnBeginReorder(wxHeaderCtrlEvent & event)243     void OnBeginReorder(wxHeaderCtrlEvent& event)
244     {
245         GetOwner()->DoStartMoveCol(event.GetColumn());
246     }
247 
OnEndReorder(wxHeaderCtrlEvent & event)248     void OnEndReorder(wxHeaderCtrlEvent& event)
249     {
250         GetOwner()->DoEndMoveCol(event.GetNewOrder());
251     }
252 
253     wxVector<wxGridHeaderColumn> m_columns;
254 
255     // The count of OnResizing() call nesting, 0 if not inside it.
256     int m_inResizing;
257 
258     wxDECLARE_EVENT_TABLE();
259     wxDECLARE_NO_COPY_CLASS(wxGridHeaderCtrl);
260 };
261 
262 // common base class for various grid subwindows
263 class WXDLLIMPEXP_ADV wxGridSubwindow : public wxWindow
264 {
265 public:
266     wxGridSubwindow(wxGrid *owner,
267                     int additionalStyle = 0,
268                     const wxString& name = wxASCII_STR(wxPanelNameStr))
269         : wxWindow(owner, wxID_ANY,
270                    wxDefaultPosition, wxDefaultSize,
271                    wxBORDER_NONE | additionalStyle,
272                    name)
273     {
274         m_owner = owner;
275     }
276 
GetMainWindowOfCompositeControl()277     virtual wxWindow *GetMainWindowOfCompositeControl() wxOVERRIDE { return m_owner; }
278 
AcceptsFocus()279     virtual bool AcceptsFocus() const wxOVERRIDE { return false; }
280 
GetOwner()281     wxGrid *GetOwner() { return m_owner; }
282 
283 protected:
284     void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
285 
286     wxGrid *m_owner;
287 
288     wxDECLARE_EVENT_TABLE();
289     wxDECLARE_NO_COPY_CLASS(wxGridSubwindow);
290 };
291 
292 class WXDLLIMPEXP_ADV wxGridRowLabelWindow : public wxGridSubwindow
293 {
294 public:
wxGridRowLabelWindow(wxGrid * parent)295     wxGridRowLabelWindow(wxGrid *parent)
296       : wxGridSubwindow(parent)
297     {
298     }
299 
IsFrozen()300     virtual bool IsFrozen() const { return false; }
301 
302 private:
303     void OnPaint( wxPaintEvent& event );
304     void OnMouseEvent( wxMouseEvent& event );
305     void OnMouseWheel( wxMouseEvent& event );
306 
307     wxDECLARE_EVENT_TABLE();
308     wxDECLARE_NO_COPY_CLASS(wxGridRowLabelWindow);
309 };
310 
311 
312 class wxGridRowFrozenLabelWindow : public wxGridRowLabelWindow
313 {
314 public:
wxGridRowFrozenLabelWindow(wxGrid * parent)315     wxGridRowFrozenLabelWindow(wxGrid *parent)
316         : wxGridRowLabelWindow(parent)
317     {
318     }
319 
IsFrozen()320     virtual bool IsFrozen() const wxOVERRIDE { return true; }
321 };
322 
323 
324 class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxGridSubwindow
325 {
326 public:
wxGridColLabelWindow(wxGrid * parent)327     wxGridColLabelWindow(wxGrid *parent)
328         : wxGridSubwindow(parent)
329     {
330     }
331 
IsFrozen()332     virtual bool IsFrozen() const { return false; }
333 
334 private:
335     void OnPaint( wxPaintEvent& event );
336     void OnMouseEvent( wxMouseEvent& event );
337     void OnMouseWheel( wxMouseEvent& event );
338 
339     wxDECLARE_EVENT_TABLE();
340     wxDECLARE_NO_COPY_CLASS(wxGridColLabelWindow);
341 };
342 
343 
344 class wxGridColFrozenLabelWindow : public wxGridColLabelWindow
345 {
346 public:
wxGridColFrozenLabelWindow(wxGrid * parent)347     wxGridColFrozenLabelWindow(wxGrid *parent)
348         : wxGridColLabelWindow(parent)
349     {
350     }
351 
IsFrozen()352     virtual bool IsFrozen() const wxOVERRIDE { return true; }
353 };
354 
355 
356 class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxGridSubwindow
357 {
358 public:
wxGridCornerLabelWindow(wxGrid * parent)359     wxGridCornerLabelWindow(wxGrid *parent)
360         : wxGridSubwindow(parent)
361     {
362     }
363 
364 private:
365     void OnMouseEvent( wxMouseEvent& event );
366     void OnMouseWheel( wxMouseEvent& event );
367     void OnPaint( wxPaintEvent& event );
368 
369     wxDECLARE_EVENT_TABLE();
370     wxDECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow);
371 };
372 
373 class WXDLLIMPEXP_ADV wxGridWindow : public wxGridSubwindow
374 {
375 public:
376     // grid window variants for scrolling possibilities
377     enum wxGridWindowType
378     {
379         wxGridWindowNormal          = 0,
380         wxGridWindowFrozenCol       = 1,
381         wxGridWindowFrozenRow       = 2,
382         wxGridWindowFrozenCorner    = wxGridWindowFrozenCol |
383                                       wxGridWindowFrozenRow
384     };
385 
wxGridWindow(wxGrid * parent,wxGridWindowType type)386     wxGridWindow(wxGrid *parent, wxGridWindowType type)
387         : wxGridSubwindow(parent,
388                           wxWANTS_CHARS | wxCLIP_CHILDREN,
389                           "GridWindow"),
390           m_type(type)
391     {
392         SetBackgroundStyle(wxBG_STYLE_PAINT);
393     }
394 
395 
396     virtual void ScrollWindow( int dx, int dy, const wxRect *rect ) wxOVERRIDE;
397 
AcceptsFocus()398     virtual bool AcceptsFocus() const wxOVERRIDE { return true; }
399 
GetType()400     wxGridWindowType GetType() const { return m_type; }
401 
402 private:
403     const wxGridWindowType m_type;
404 
405     void OnPaint( wxPaintEvent &event );
406     void OnMouseWheel( wxMouseEvent& event );
407     void OnMouseEvent( wxMouseEvent& event );
408     void OnKeyDown( wxKeyEvent& );
409     void OnKeyUp( wxKeyEvent& );
410     void OnChar( wxKeyEvent& );
411     void OnFocus( wxFocusEvent& );
412 
413     wxDECLARE_EVENT_TABLE();
414     wxDECLARE_NO_COPY_CLASS(wxGridWindow);
415 };
416 
417 // ----------------------------------------------------------------------------
418 // the internal data representation used by wxGridCellAttrProvider
419 // ----------------------------------------------------------------------------
420 
421 // this class stores attributes set for cells
422 class WXDLLIMPEXP_ADV wxGridCellAttrData
423 {
424 public:
425     ~wxGridCellAttrData();
426 
427     void SetAttr(wxGridCellAttr *attr, int row, int col);
428     wxGridCellAttr *GetAttr(int row, int col) const;
429     void UpdateAttrRows( size_t pos, int numRows );
430     void UpdateAttrCols( size_t pos, int numCols );
431 
432 private:
433     // Tries to search for the attr for given cell.
434     wxGridCoordsToAttrMap::iterator FindIndex(int row, int col) const;
435 
436     mutable wxGridCoordsToAttrMap m_attrs;
437 };
438 
439 // this class stores attributes set for rows or columns
440 class WXDLLIMPEXP_ADV wxGridRowOrColAttrData
441 {
442 public:
443     // empty ctor to suppress warnings
wxGridRowOrColAttrData()444     wxGridRowOrColAttrData() {}
445     ~wxGridRowOrColAttrData();
446 
447     void SetAttr(wxGridCellAttr *attr, int rowOrCol);
448     wxGridCellAttr *GetAttr(int rowOrCol) const;
449     void UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols );
450 
451 private:
452     wxArrayInt m_rowsOrCols;
453     wxArrayAttrs m_attrs;
454 };
455 
456 // NB: this is just a wrapper around 3 objects: one which stores cell
457 //     attributes, and 2 others for row/col ones
458 class WXDLLIMPEXP_ADV wxGridCellAttrProviderData
459 {
460 public:
461     wxGridCellAttrData m_cellAttrs;
462     wxGridRowOrColAttrData m_rowAttrs,
463                            m_colAttrs;
464 };
465 
466 // ----------------------------------------------------------------------------
467 // operations classes abstracting the difference between operating on rows and
468 // columns
469 // ----------------------------------------------------------------------------
470 
471 // This class allows to write a function only once because by using its methods
472 // it will apply to both columns and rows.
473 //
474 // This is an abstract interface definition, the two concrete implementations
475 // below should be used when working with rows and columns respectively.
476 class wxGridOperations
477 {
478 public:
479     // Returns the operations in the other direction, i.e. wxGridRowOperations
480     // if this object is a wxGridColumnOperations and vice versa.
481     virtual wxGridOperations& Dual() const = 0;
482 
483     // Return the total number of rows or columns.
484     virtual int GetTotalNumberOfLines(const wxGrid *grid) const = 0;
485 
486     // Return the current number of rows or columns of a grid window.
487     virtual int GetNumberOfLines(const wxGrid *grid, wxGridWindow *gridWindow) const = 0;
488 
489     // Return the first line for this grid type.
490     virtual int GetFirstLine(const wxGrid *grid, wxGridWindow *gridWindow) const = 0;
491 
492     // Return the selection mode which allows selecting rows or columns.
493     virtual wxGrid::wxGridSelectionModes GetSelectionMode() const = 0;
494 
495     // Make a wxGridCellCoords from the given components: thisDir is row or
496     // column and otherDir is column or row
497     virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const = 0;
498 
499     // Calculate the scrolled position of the given abscissa or ordinate.
500     virtual int CalcScrolledPosition(wxGrid *grid, int pos) const = 0;
501 
502     // Selects the horizontal or vertical component from the given object.
503     virtual int Select(const wxGridCellCoords& coords) const = 0;
504     virtual int Select(const wxPoint& pt) const = 0;
505     virtual int Select(const wxSize& sz) const = 0;
506     virtual int Select(const wxRect& r) const = 0;
507     virtual int& Select(wxRect& r) const = 0;
508 
509     // Return or set left/top or right/bottom component of a block.
510     virtual int SelectFirst(const wxGridBlockCoords& block) const = 0;
511     virtual int SelectLast(const wxGridBlockCoords& block) const = 0;
512     virtual void SetFirst(wxGridBlockCoords& block, int line) const = 0;
513     virtual void SetLast(wxGridBlockCoords& block, int line) const = 0;
514 
515     // Returns width or height of the rectangle
516     virtual int& SelectSize(wxRect& r) const = 0;
517 
518     // Make a wxSize such that Select() applied to it returns first component
519     virtual wxSize MakeSize(int first, int second) const = 0;
520 
521     // Sets the row or column component of the given cell coordinates
522     virtual void Set(wxGridCellCoords& coords, int line) const = 0;
523 
524 
525     // Draws a line parallel to the row or column, i.e. horizontal or vertical:
526     // pos is the horizontal or vertical position of the line and start and end
527     // are the coordinates of the line extremities in the other direction
528     virtual void
529         DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0;
530 
531     // Draw a horizontal or vertical line across the given rectangle
532     // (this is implemented in terms of above and uses Select() to extract
533     // start and end from the given rectangle)
DrawParallelLineInRect(wxDC & dc,const wxRect & rect,int pos)534     void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const
535     {
536         const int posStart = Select(rect.GetPosition());
537         DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos);
538     }
539 
540 
541     // Return the index of the row or column at the given pixel coordinate.
542     virtual int
543         PosToLine(const wxGrid *grid, int pos, wxGridWindow *gridWindow, bool clip = false) const = 0;
544 
545     // Get the top/left position, in pixels, of the given row or column
546     virtual int GetLineStartPos(const wxGrid *grid, int line) const = 0;
547 
548     // Get the bottom/right position, in pixels, of the given row or column
549     virtual int GetLineEndPos(const wxGrid *grid, int line) const = 0;
550 
551     // Get the height/width of the given row/column
552     virtual int GetLineSize(const wxGrid *grid, int line) const = 0;
553 
554     // Get wxGrid::m_rowBottoms/m_colRights array
555     virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const = 0;
556 
557     // Get default height row height or column width
558     virtual int GetDefaultLineSize(const wxGrid *grid) const = 0;
559 
560     // Return the minimal acceptable row height or column width
561     virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const = 0;
562 
563     // Return the minimal row height or column width
564     virtual int GetMinimalLineSize(const wxGrid *grid, int line) const = 0;
565 
566     // Set the row height or column width
567     virtual void SetLineSize(wxGrid *grid, int line, int size) const = 0;
568 
569     // Set the row default height or column default width
570     virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const = 0;
571 
572 
573     // Return the index of the line at the given position
574     //
575     // NB: currently this is always identity for the rows as reordering is only
576     //     implemented for the lines
577     virtual int GetLineAt(const wxGrid *grid, int pos) const = 0;
578 
579     // Return the display position of the line with the given index.
580     //
581     // NB: As GetLineAt(), currently this is always identity for rows.
582     virtual int GetLinePos(const wxGrid *grid, int line) const = 0;
583 
584     // Return the index of the line just before the given one or wxNOT_FOUND.
585     virtual int GetLineBefore(const wxGrid* grid, int line) const = 0;
586 
587     // Get the row or column label window
588     virtual wxWindow *GetHeaderWindow(wxGrid *grid) const = 0;
589 
590     // Get the width or height of the row or column label window
591     virtual int GetHeaderWindowSize(wxGrid *grid) const = 0;
592 
593     // Get the row or column frozen grid window
594     virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const = 0;
595 
596     // This class is never used polymorphically but give it a virtual dtor
597     // anyhow to suppress g++ complaints about it
~wxGridOperations()598     virtual ~wxGridOperations() { }
599 };
600 
601 class wxGridRowOperations : public wxGridOperations
602 {
603 public:
604     virtual wxGridOperations& Dual() const wxOVERRIDE;
605 
GetTotalNumberOfLines(const wxGrid * grid)606     virtual int GetTotalNumberOfLines(const wxGrid *grid) const wxOVERRIDE
607         { return grid->GetNumberRows(); }
608 
609     virtual int GetNumberOfLines(const wxGrid *grid, wxGridWindow *gridWindow) const wxOVERRIDE;
610 
611     virtual int GetFirstLine(const wxGrid *grid, wxGridWindow *gridWindow) const wxOVERRIDE;
612 
GetSelectionMode()613     virtual wxGrid::wxGridSelectionModes GetSelectionMode() const wxOVERRIDE
614         { return wxGrid::wxGridSelectRows; }
615 
MakeCoords(int thisDir,int otherDir)616     virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const wxOVERRIDE
617         { return wxGridCellCoords(thisDir, otherDir); }
618 
CalcScrolledPosition(wxGrid * grid,int pos)619     virtual int CalcScrolledPosition(wxGrid *grid, int pos) const wxOVERRIDE
620         { return grid->CalcScrolledPosition(wxPoint(pos, 0)).x; }
621 
Select(const wxGridCellCoords & c)622     virtual int Select(const wxGridCellCoords& c) const wxOVERRIDE { return c.GetRow(); }
Select(const wxPoint & pt)623     virtual int Select(const wxPoint& pt) const wxOVERRIDE { return pt.x; }
Select(const wxSize & sz)624     virtual int Select(const wxSize& sz) const wxOVERRIDE { return sz.x; }
Select(const wxRect & r)625     virtual int Select(const wxRect& r) const wxOVERRIDE { return r.x; }
Select(wxRect & r)626     virtual int& Select(wxRect& r) const wxOVERRIDE { return r.x; }
SelectFirst(const wxGridBlockCoords & block)627     virtual int SelectFirst(const wxGridBlockCoords& block) const wxOVERRIDE
628         { return block.GetTopRow(); }
SelectLast(const wxGridBlockCoords & block)629     virtual int SelectLast(const wxGridBlockCoords& block) const wxOVERRIDE
630         { return block.GetBottomRow(); }
SetFirst(wxGridBlockCoords & block,int line)631     virtual void SetFirst(wxGridBlockCoords& block, int line) const wxOVERRIDE
632         { block.SetTopRow(line); }
SetLast(wxGridBlockCoords & block,int line)633     virtual void SetLast(wxGridBlockCoords& block, int line) const wxOVERRIDE
634         { block.SetBottomRow(line); }
SelectSize(wxRect & r)635     virtual int& SelectSize(wxRect& r) const wxOVERRIDE { return r.width; }
MakeSize(int first,int second)636     virtual wxSize MakeSize(int first, int second) const wxOVERRIDE
637         { return wxSize(first, second); }
Set(wxGridCellCoords & coords,int line)638     virtual void Set(wxGridCellCoords& coords, int line) const wxOVERRIDE
639         { coords.SetRow(line); }
640 
DrawParallelLine(wxDC & dc,int start,int end,int pos)641     virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const wxOVERRIDE
642         { dc.DrawLine(start, pos, end, pos); }
643 
644     virtual int PosToLine(const wxGrid *grid, int pos, wxGridWindow *gridWindow , bool clip = false) const wxOVERRIDE
645         { return grid->YToRow(pos, clip, gridWindow); }
GetLineStartPos(const wxGrid * grid,int line)646     virtual int GetLineStartPos(const wxGrid *grid, int line) const wxOVERRIDE
647         { return grid->GetRowTop(line); }
GetLineEndPos(const wxGrid * grid,int line)648     virtual int GetLineEndPos(const wxGrid *grid, int line) const wxOVERRIDE
649         { return grid->GetRowBottom(line); }
GetLineSize(const wxGrid * grid,int line)650     virtual int GetLineSize(const wxGrid *grid, int line) const wxOVERRIDE
651         { return grid->GetRowHeight(line); }
GetLineEnds(const wxGrid * grid)652     virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const wxOVERRIDE
653         { return grid->m_rowBottoms; }
GetDefaultLineSize(const wxGrid * grid)654     virtual int GetDefaultLineSize(const wxGrid *grid) const wxOVERRIDE
655         { return grid->GetDefaultRowSize(); }
GetMinimalAcceptableLineSize(const wxGrid * grid)656     virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const wxOVERRIDE
657         { return grid->GetRowMinimalAcceptableHeight(); }
GetMinimalLineSize(const wxGrid * grid,int line)658     virtual int GetMinimalLineSize(const wxGrid *grid, int line) const wxOVERRIDE
659         { return grid->GetRowMinimalHeight(line); }
SetLineSize(wxGrid * grid,int line,int size)660     virtual void SetLineSize(wxGrid *grid, int line, int size) const wxOVERRIDE
661         { grid->SetRowSize(line, size); }
SetDefaultLineSize(wxGrid * grid,int size,bool resizeExisting)662     virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const wxOVERRIDE
663         {  grid->SetDefaultRowSize(size, resizeExisting); }
664 
GetLineAt(const wxGrid * WXUNUSED (grid),int pos)665     virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int pos) const wxOVERRIDE
666         { return pos; } // TODO: implement row reordering
GetLinePos(const wxGrid * WXUNUSED (grid),int line)667     virtual int GetLinePos(const wxGrid * WXUNUSED(grid), int line) const wxOVERRIDE
668         { return line; } // TODO: implement row reordering
669 
GetLineBefore(const wxGrid * WXUNUSED (grid),int line)670     virtual int GetLineBefore(const wxGrid* WXUNUSED(grid), int line) const wxOVERRIDE
671         { return line - 1; }
672 
GetHeaderWindow(wxGrid * grid)673     virtual wxWindow *GetHeaderWindow(wxGrid *grid) const wxOVERRIDE
674         { return grid->GetGridRowLabelWindow(); }
GetHeaderWindowSize(wxGrid * grid)675     virtual int GetHeaderWindowSize(wxGrid *grid) const wxOVERRIDE
676         { return grid->GetRowLabelSize(); }
677 
GetFrozenGrid(wxGrid * grid)678     virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const wxOVERRIDE
679         { return (wxGridWindow*)grid->GetFrozenRowGridWindow(); }
680 };
681 
682 class wxGridColumnOperations : public wxGridOperations
683 {
684 public:
685     virtual wxGridOperations& Dual() const wxOVERRIDE;
686 
GetTotalNumberOfLines(const wxGrid * grid)687     virtual int GetTotalNumberOfLines(const wxGrid *grid) const wxOVERRIDE
688         { return grid->GetNumberCols(); }
689 
690     virtual int GetNumberOfLines(const wxGrid *grid, wxGridWindow *gridWindow) const wxOVERRIDE;
691 
692     virtual int GetFirstLine(const wxGrid *grid, wxGridWindow *gridWindow) const wxOVERRIDE;
693 
GetSelectionMode()694     virtual wxGrid::wxGridSelectionModes GetSelectionMode() const wxOVERRIDE
695         { return wxGrid::wxGridSelectColumns; }
696 
MakeCoords(int thisDir,int otherDir)697     virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const wxOVERRIDE
698         { return wxGridCellCoords(otherDir, thisDir); }
699 
CalcScrolledPosition(wxGrid * grid,int pos)700     virtual int CalcScrolledPosition(wxGrid *grid, int pos) const wxOVERRIDE
701         { return grid->CalcScrolledPosition(wxPoint(0, pos)).y; }
702 
Select(const wxGridCellCoords & c)703     virtual int Select(const wxGridCellCoords& c) const wxOVERRIDE { return c.GetCol(); }
Select(const wxPoint & pt)704     virtual int Select(const wxPoint& pt) const wxOVERRIDE { return pt.y; }
Select(const wxSize & sz)705     virtual int Select(const wxSize& sz) const wxOVERRIDE { return sz.y; }
Select(const wxRect & r)706     virtual int Select(const wxRect& r) const wxOVERRIDE { return r.y; }
Select(wxRect & r)707     virtual int& Select(wxRect& r) const wxOVERRIDE { return r.y; }
SelectFirst(const wxGridBlockCoords & block)708     virtual int SelectFirst(const wxGridBlockCoords& block) const wxOVERRIDE
709         { return block.GetLeftCol(); }
SelectLast(const wxGridBlockCoords & block)710     virtual int SelectLast(const wxGridBlockCoords& block) const wxOVERRIDE
711         { return block.GetRightCol(); }
SetFirst(wxGridBlockCoords & block,int line)712     virtual void SetFirst(wxGridBlockCoords& block, int line) const wxOVERRIDE
713         { block.SetLeftCol(line); }
SetLast(wxGridBlockCoords & block,int line)714     virtual void SetLast(wxGridBlockCoords& block, int line) const wxOVERRIDE
715         { block.SetRightCol(line); }
SelectSize(wxRect & r)716     virtual int& SelectSize(wxRect& r) const wxOVERRIDE { return r.height; }
MakeSize(int first,int second)717     virtual wxSize MakeSize(int first, int second) const wxOVERRIDE
718         { return wxSize(second, first); }
Set(wxGridCellCoords & coords,int line)719     virtual void Set(wxGridCellCoords& coords, int line) const wxOVERRIDE
720         { coords.SetCol(line); }
721 
DrawParallelLine(wxDC & dc,int start,int end,int pos)722     virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const wxOVERRIDE
723         { dc.DrawLine(pos, start, pos, end); }
724 
725     virtual int PosToLine(const wxGrid *grid, int pos, wxGridWindow *gridWindow, bool clip = false) const wxOVERRIDE
726         { return grid->XToCol(pos, clip, gridWindow); }
GetLineStartPos(const wxGrid * grid,int line)727     virtual int GetLineStartPos(const wxGrid *grid, int line) const wxOVERRIDE
728         { return grid->GetColLeft(line); }
GetLineEndPos(const wxGrid * grid,int line)729     virtual int GetLineEndPos(const wxGrid *grid, int line) const wxOVERRIDE
730         { return grid->GetColRight(line); }
GetLineSize(const wxGrid * grid,int line)731     virtual int GetLineSize(const wxGrid *grid, int line) const wxOVERRIDE
732         { return grid->GetColWidth(line); }
GetLineEnds(const wxGrid * grid)733     virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const wxOVERRIDE
734         { return grid->m_colRights; }
GetDefaultLineSize(const wxGrid * grid)735     virtual int GetDefaultLineSize(const wxGrid *grid) const wxOVERRIDE
736         { return grid->GetDefaultColSize(); }
GetMinimalAcceptableLineSize(const wxGrid * grid)737     virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const wxOVERRIDE
738         { return grid->GetColMinimalAcceptableWidth(); }
GetMinimalLineSize(const wxGrid * grid,int line)739     virtual int GetMinimalLineSize(const wxGrid *grid, int line) const wxOVERRIDE
740         { return grid->GetColMinimalWidth(line); }
SetLineSize(wxGrid * grid,int line,int size)741     virtual void SetLineSize(wxGrid *grid, int line, int size) const wxOVERRIDE
742         { grid->SetColSize(line, size); }
SetDefaultLineSize(wxGrid * grid,int size,bool resizeExisting)743     virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const wxOVERRIDE
744         {  grid->SetDefaultColSize(size, resizeExisting); }
745 
GetLineAt(const wxGrid * grid,int pos)746     virtual int GetLineAt(const wxGrid *grid, int pos) const wxOVERRIDE
747         { return grid->GetColAt(pos); }
GetLinePos(const wxGrid * grid,int line)748     virtual int GetLinePos(const wxGrid *grid, int line) const wxOVERRIDE
749         { return grid->GetColPos(line); }
750 
GetLineBefore(const wxGrid * grid,int line)751     virtual int GetLineBefore(const wxGrid* grid, int line) const wxOVERRIDE
752     {
753         int posBefore = grid->GetColPos(line) - 1;
754         return posBefore >= 0 ? grid->GetColAt(posBefore) : wxNOT_FOUND;
755     }
756 
GetHeaderWindow(wxGrid * grid)757     virtual wxWindow *GetHeaderWindow(wxGrid *grid) const wxOVERRIDE
758         { return grid->GetGridColLabelWindow(); }
GetHeaderWindowSize(wxGrid * grid)759     virtual int GetHeaderWindowSize(wxGrid *grid) const wxOVERRIDE
760         { return grid->GetColLabelSize(); }
761 
GetFrozenGrid(wxGrid * grid)762     virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const wxOVERRIDE
763         { return (wxGridWindow*)grid->GetFrozenColGridWindow(); }
764 };
765 
766 // This class abstracts the difference between operations going forward
767 // (down/right) and backward (up/left) and allows to use the same code for
768 // functions which differ only in the direction of grid traversal.
769 //
770 // Notice that all operations in this class work with display positions and not
771 // internal indices which can be different if the columns were reordered.
772 //
773 // Like wxGridOperations it's an ABC with two concrete subclasses below. Unlike
774 // it, this is a normal object and not just a function dispatch table and has a
775 // non-default ctor.
776 //
777 // Note: the explanation of this discrepancy is the existence of (very useful)
778 // Dual() method in wxGridOperations which forces us to make wxGridOperations a
779 // function dispatcher only.
780 class wxGridDirectionOperations
781 {
782 public:
783     // The oper parameter to ctor selects whether we work with rows or columns
wxGridDirectionOperations(wxGrid * grid,const wxGridOperations & oper)784     wxGridDirectionOperations(wxGrid *grid, const wxGridOperations& oper)
785         : m_grid(grid),
786           m_oper(oper)
787     {
788     }
789 
790     // Check if the component of this point in our direction is at the
791     // boundary, i.e. is the first/last row/column
792     virtual bool IsAtBoundary(const wxGridCellCoords& coords) const = 0;
793 
794     // Check if the component of this point in our direction is
795     // valid, i.e. not -1
IsValid(const wxGridCellCoords & coords)796     bool IsValid(const wxGridCellCoords& coords) const
797     {
798         return m_oper.Select(coords) != -1;
799     }
800 
801     // Make the coordinates with the other component value of -1.
MakeWholeLineCoords(const wxGridCellCoords & coords)802     wxGridCellCoords MakeWholeLineCoords(const wxGridCellCoords& coords) const
803     {
804         return m_oper.MakeCoords(m_oper.Select(coords), -1);
805     }
806 
807     // Increment the component of this point in our direction
808     //
809     // Note that this can't be called if IsAtBoundary() is true, use
810     // TryToAdvance() if this might be the case.
811     virtual void Advance(wxGridCellCoords& coords) const = 0;
812 
813     // Try to advance in our direction, return true if succeeded or false
814     // otherwise, i.e. if the coordinates are already at the grid boundary.
TryToAdvance(wxGridCellCoords & coords)815     bool TryToAdvance(wxGridCellCoords& coords) const
816     {
817         if ( IsAtBoundary(coords) )
818             return false;
819 
820         Advance(coords);
821 
822         return true;
823     }
824 
825     // Find the line at the given distance, in pixels, away from this one
826     // (this uses clipping, i.e. anything after the last line is counted as the
827     // last one and anything before the first one as 0)
828     //
829     // TODO: Implementation of this method currently doesn't support column
830     //       reordering as it mixes up indices and positions. But this doesn't
831     //       really matter as it's only called for rows (Page Up/Down only work
832     //       vertically) and row reordering is not currently supported. We'd
833     //       need to fix it if this ever changes however.
834     virtual int MoveByPixelDistance(int line, int distance) const = 0;
835 
836     // This class is never used polymorphically but give it a virtual dtor
837     // anyhow to suppress g++ complaints about it
~wxGridDirectionOperations()838     virtual ~wxGridDirectionOperations() { }
839 
840 protected:
841     // Get the position of the row or column from the given coordinates pair.
842     //
843     // This is just a shortcut to avoid repeating m_oper and m_grid multiple
844     // times in the derived classes code.
GetLinePos(const wxGridCellCoords & coords)845     int GetLinePos(const wxGridCellCoords& coords) const
846     {
847         return m_oper.GetLinePos(m_grid, m_oper.Select(coords));
848     }
849 
850     // Get the index of the row or column from the position.
GetLineAt(int pos)851     int GetLineAt(int pos) const
852     {
853         return m_oper.GetLineAt(m_grid, pos);
854     }
855 
856     // Check if the given line is visible, i.e. has non 0 size.
IsLineVisible(int line)857     bool IsLineVisible(int line) const
858     {
859         return m_oper.GetLineSize(m_grid, line) != 0;
860     }
861 
862 
863     wxGrid * const m_grid;
864     const wxGridOperations& m_oper;
865 };
866 
867 class wxGridBackwardOperations : public wxGridDirectionOperations
868 {
869 public:
wxGridBackwardOperations(wxGrid * grid,const wxGridOperations & oper)870     wxGridBackwardOperations(wxGrid *grid, const wxGridOperations& oper)
871         : wxGridDirectionOperations(grid, oper)
872     {
873     }
874 
IsAtBoundary(const wxGridCellCoords & coords)875     virtual bool IsAtBoundary(const wxGridCellCoords& coords) const wxOVERRIDE
876     {
877         wxASSERT_MSG( m_oper.Select(coords) >= 0, "invalid row/column" );
878 
879         int pos = GetLinePos(coords);
880         while ( pos )
881         {
882             // Check the previous line.
883             int line = GetLineAt(--pos);
884             if ( IsLineVisible(line) )
885             {
886                 // There is another visible line before this one, hence it's
887                 // not at boundary.
888                 return false;
889             }
890         }
891 
892         // We reached the boundary without finding any visible lines.
893         return true;
894     }
895 
Advance(wxGridCellCoords & coords)896     virtual void Advance(wxGridCellCoords& coords) const wxOVERRIDE
897     {
898         int pos = GetLinePos(coords);
899         for ( ;; )
900         {
901             // This is not supposed to happen if IsAtBoundary() returned false.
902             wxCHECK_RET( pos, "can't advance when already at boundary" );
903 
904             int line = GetLineAt(--pos);
905             if ( IsLineVisible(line) )
906             {
907                 m_oper.Set(coords, line);
908                 break;
909             }
910         }
911     }
912 
MoveByPixelDistance(int line,int distance)913     virtual int MoveByPixelDistance(int line, int distance) const wxOVERRIDE
914     {
915         int pos = m_oper.GetLineStartPos(m_grid, line);
916         return m_oper.PosToLine(m_grid, pos - distance + 1, NULL, true);
917     }
918 };
919 
920 // Please refer to the comments above when reading this class code, it's
921 // absolutely symmetrical to wxGridBackwardOperations.
922 class wxGridForwardOperations : public wxGridDirectionOperations
923 {
924 public:
wxGridForwardOperations(wxGrid * grid,const wxGridOperations & oper)925     wxGridForwardOperations(wxGrid *grid, const wxGridOperations& oper)
926         : wxGridDirectionOperations(grid, oper),
927           m_numLines(oper.GetTotalNumberOfLines(grid))
928     {
929     }
930 
IsAtBoundary(const wxGridCellCoords & coords)931     virtual bool IsAtBoundary(const wxGridCellCoords& coords) const wxOVERRIDE
932     {
933         wxASSERT_MSG( m_oper.Select(coords) < m_numLines, "invalid row/column" );
934 
935         int pos = GetLinePos(coords);
936         while ( pos < m_numLines - 1 )
937         {
938             int line = GetLineAt(++pos);
939             if ( IsLineVisible(line) )
940                 return false;
941         }
942 
943         return true;
944     }
945 
Advance(wxGridCellCoords & coords)946     virtual void Advance(wxGridCellCoords& coords) const wxOVERRIDE
947     {
948         int pos = GetLinePos(coords);
949         for ( ;; )
950         {
951             wxCHECK_RET( pos < m_numLines - 1,
952                          "can't advance when already at boundary" );
953 
954             int line = GetLineAt(++pos);
955             if ( IsLineVisible(line) )
956             {
957                 m_oper.Set(coords, line);
958                 break;
959             }
960         }
961     }
962 
MoveByPixelDistance(int line,int distance)963     virtual int MoveByPixelDistance(int line, int distance) const wxOVERRIDE
964     {
965         int pos = m_oper.GetLineStartPos(m_grid, line);
966         return m_oper.PosToLine(m_grid, pos + distance, NULL, true);
967     }
968 
969 private:
970     const int m_numLines;
971 };
972 
973 // ----------------------------------------------------------------------------
974 // data structures used for the data type registry
975 // ----------------------------------------------------------------------------
976 
977 struct wxGridDataTypeInfo
978 {
wxGridDataTypeInfowxGridDataTypeInfo979     wxGridDataTypeInfo(const wxString& typeName,
980                        wxGridCellRenderer* renderer,
981                        wxGridCellEditor* editor)
982         : m_typeName(typeName), m_renderer(renderer), m_editor(editor)
983         {}
984 
~wxGridDataTypeInfowxGridDataTypeInfo985     ~wxGridDataTypeInfo()
986     {
987         wxSafeDecRef(m_renderer);
988         wxSafeDecRef(m_editor);
989     }
990 
991     wxString            m_typeName;
992     wxGridCellRenderer* m_renderer;
993     wxGridCellEditor*   m_editor;
994 
995     wxDECLARE_NO_COPY_CLASS(wxGridDataTypeInfo);
996 };
997 
998 
999 WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridDataTypeInfo*, wxGridDataTypeInfoArray,
1000                                  class WXDLLIMPEXP_ADV);
1001 
1002 
1003 class WXDLLIMPEXP_ADV wxGridTypeRegistry
1004 {
1005 public:
wxGridTypeRegistry()1006     wxGridTypeRegistry() {}
1007     ~wxGridTypeRegistry();
1008 
1009     void RegisterDataType(const wxString& typeName,
1010                      wxGridCellRenderer* renderer,
1011                      wxGridCellEditor* editor);
1012 
1013     // find one of already registered data types
1014     int FindRegisteredDataType(const wxString& typeName);
1015 
1016     // try to FindRegisteredDataType(), if this fails and typeName is one of
1017     // standard typenames, register it and return its index
1018     int FindDataType(const wxString& typeName);
1019 
1020     // try to FindDataType(), if it fails see if it is not one of already
1021     // registered data types with some params in which case clone the
1022     // registered data type and set params for it
1023     int FindOrCloneDataType(const wxString& typeName);
1024 
1025     wxGridCellRenderer* GetRenderer(int index);
1026     wxGridCellEditor*   GetEditor(int index);
1027 
1028 private:
1029     wxGridDataTypeInfoArray m_typeinfo;
1030 };
1031 
1032 // Returns the rectangle for showing something of the given size in a cell with
1033 // the given alignment.
1034 //
1035 // The function is used by wxGridCellBoolEditor and wxGridCellBoolRenderer to
1036 // draw a check mark and position wxCheckBox respectively.
1037 wxRect
1038 wxGetContentRect(wxSize contentSize,
1039                  const wxRect& cellRect,
1040                  int hAlign,
1041                  int vAlign);
1042 
1043 namespace wxGridPrivate
1044 {
1045 
1046 #if wxUSE_DATETIME
1047 
1048 // This is used as TryGetValueAsDate() parameter.
1049 class DateParseParams
1050 {
1051 public:
1052     // Unfortunately we have to provide the default ctor (and also make the
1053     // members non-const) because we use these objects as out-parameters as
1054     // they are not fully declared in the public headers. The factory functions
1055     // below must be used to create a really usable object.
DateParseParams()1056     DateParseParams() : fallbackParseDate(false) { }
1057 
1058     // Use these functions to really initialize the object.
WithFallback(const wxString & format)1059     static DateParseParams WithFallback(const wxString& format)
1060     {
1061         return DateParseParams(format, true);
1062     }
1063 
WithoutFallback(const wxString & format)1064     static DateParseParams WithoutFallback(const wxString& format)
1065     {
1066         return DateParseParams(format, false);
1067     }
1068 
1069     // The usual format, e.g. "%x" or "%Y-%m-%d".
1070     wxString format;
1071 
1072     // Whether fall back to ParseDate() is allowed.
1073     bool fallbackParseDate;
1074 
1075 private:
DateParseParams(const wxString & format_,bool fallbackParseDate_)1076     DateParseParams(const wxString& format_, bool fallbackParseDate_)
1077         : format(format_),
1078           fallbackParseDate(fallbackParseDate_)
1079     {
1080     }
1081 };
1082 
1083 // Helper function trying to get a date from the given cell: if possible, get
1084 // the date value from the table directly, otherwise get the string value for
1085 // this cell and try to parse it using the specified date format and, if this
1086 // doesn't work and fallbackParseDate is true, try using ParseDate() as a
1087 // fallback. If this still fails, returns false.
1088 bool
1089 TryGetValueAsDate(wxDateTime& result,
1090                   const DateParseParams& params,
1091                   const wxGrid& grid,
1092                   int row, int col);
1093 
1094 #endif // wxUSE_DATETIME
1095 
1096 } // namespace wxGridPrivate
1097 
1098 #endif // wxUSE_GRID
1099 #endif // _WX_GENERIC_GRID_PRIVATE_H_
1100