Remove all lines containing cvs/svn "$Id$" keyword.
[wxWidgets.git] / include / wx / generic / private / grid.h
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 // Internally used (and hence intentionally not exported) event telling wxGrid
19 // to hide the currently shown editor.
20 wxDECLARE_EVENT( wxEVT_GRID_HIDE_EDITOR, wxCommandEvent );
21
22 // ----------------------------------------------------------------------------
23 // array classes
24 // ----------------------------------------------------------------------------
25
26 WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridCellAttr *, wxArrayAttrs,
27 class WXDLLIMPEXP_ADV);
28
29 struct wxGridCellWithAttr
30 {
31 wxGridCellWithAttr(int row, int col, wxGridCellAttr *attr_)
32 : coords(row, col), attr(attr_)
33 {
34 wxASSERT( attr );
35 }
36
37 wxGridCellWithAttr(const wxGridCellWithAttr& other)
38 : coords(other.coords),
39 attr(other.attr)
40 {
41 attr->IncRef();
42 }
43
44 wxGridCellWithAttr& operator=(const wxGridCellWithAttr& other)
45 {
46 coords = other.coords;
47 if (attr != other.attr)
48 {
49 attr->DecRef();
50 attr = other.attr;
51 attr->IncRef();
52 }
53 return *this;
54 }
55
56 void ChangeAttr(wxGridCellAttr* new_attr)
57 {
58 if (attr != new_attr)
59 {
60 // "Delete" (i.e. DecRef) the old attribute.
61 attr->DecRef();
62 attr = new_attr;
63 // Take ownership of the new attribute, i.e. no IncRef.
64 }
65 }
66
67 ~wxGridCellWithAttr()
68 {
69 attr->DecRef();
70 }
71
72 wxGridCellCoords coords;
73 wxGridCellAttr *attr;
74 };
75
76 WX_DECLARE_OBJARRAY_WITH_DECL(wxGridCellWithAttr, wxGridCellWithAttrArray,
77 class WXDLLIMPEXP_ADV);
78
79
80 // ----------------------------------------------------------------------------
81 // private classes
82 // ----------------------------------------------------------------------------
83
84 // header column providing access to the column information stored in wxGrid
85 // via wxHeaderColumn interface
86 class wxGridHeaderColumn : public wxHeaderColumn
87 {
88 public:
89 wxGridHeaderColumn(wxGrid *grid, int col)
90 : m_grid(grid),
91 m_col(col)
92 {
93 }
94
95 virtual wxString GetTitle() const { return m_grid->GetColLabelValue(m_col); }
96 virtual wxBitmap GetBitmap() const { return wxNullBitmap; }
97 virtual int GetWidth() const { return m_grid->GetColSize(m_col); }
98 virtual int GetMinWidth() const { return 0; }
99 virtual wxAlignment GetAlignment() const
100 {
101 int horz,
102 vert;
103 m_grid->GetColLabelAlignment(&horz, &vert);
104
105 return static_cast<wxAlignment>(horz);
106 }
107
108 virtual int GetFlags() const
109 {
110 // we can't know in advance whether we can sort by this column or not
111 // with wxGrid API so suppose we can by default
112 int flags = wxCOL_SORTABLE;
113 if ( m_grid->CanDragColSize(m_col) )
114 flags |= wxCOL_RESIZABLE;
115 if ( m_grid->CanDragColMove() )
116 flags |= wxCOL_REORDERABLE;
117 if ( GetWidth() == 0 )
118 flags |= wxCOL_HIDDEN;
119
120 return flags;
121 }
122
123 virtual bool IsSortKey() const
124 {
125 return m_grid->IsSortingBy(m_col);
126 }
127
128 virtual bool IsSortOrderAscending() const
129 {
130 return m_grid->IsSortOrderAscending();
131 }
132
133 private:
134 // these really should be const but are not because the column needs to be
135 // assignable to be used in a wxVector (in STL build, in non-STL build we
136 // avoid the need for this)
137 wxGrid *m_grid;
138 int m_col;
139 };
140
141 // header control retreiving column information from the grid
142 class wxGridHeaderCtrl : public wxHeaderCtrl
143 {
144 public:
145 wxGridHeaderCtrl(wxGrid *owner)
146 : wxHeaderCtrl(owner,
147 wxID_ANY,
148 wxDefaultPosition,
149 wxDefaultSize,
150 wxHD_ALLOW_HIDE |
151 (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0))
152 {
153 }
154
155 protected:
156 virtual const wxHeaderColumn& GetColumn(unsigned int idx) const
157 {
158 return m_columns[idx];
159 }
160
161 private:
162 wxGrid *GetOwner() const { return static_cast<wxGrid *>(GetParent()); }
163
164 static wxMouseEvent GetDummyMouseEvent()
165 {
166 // make up a dummy event for the grid event to use -- unfortunately we
167 // can't do anything else here
168 wxMouseEvent e;
169 e.SetState(wxGetMouseState());
170 return e;
171 }
172
173 // override the base class method to update our m_columns array
174 virtual void OnColumnCountChanging(unsigned int count)
175 {
176 const unsigned countOld = m_columns.size();
177 if ( count < countOld )
178 {
179 // just discard the columns which don't exist any more (notice that
180 // we can't use resize() here as it would require the vector
181 // value_type, i.e. wxGridHeaderColumn to be default constructible,
182 // which it is not)
183 m_columns.erase(m_columns.begin() + count, m_columns.end());
184 }
185 else // new columns added
186 {
187 // add columns for the new elements
188 for ( unsigned n = countOld; n < count; n++ )
189 m_columns.push_back(wxGridHeaderColumn(GetOwner(), n));
190 }
191 }
192
193 // override to implement column auto sizing
194 virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle)
195 {
196 // TODO: currently grid doesn't support computing the column best width
197 // from its contents so we just use the best label width as is
198 GetOwner()->SetColSize(idx, widthTitle);
199
200 return true;
201 }
202
203 // overridden to react to the actions using the columns popup menu
204 virtual void UpdateColumnVisibility(unsigned int idx, bool show)
205 {
206 GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0);
207
208 // as this is done by the user we should notify the main program about
209 // it
210 GetOwner()->SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, idx,
211 GetDummyMouseEvent());
212 }
213
214 // overridden to react to the columns order changes in the customization
215 // dialog
216 virtual void UpdateColumnsOrder(const wxArrayInt& order)
217 {
218 GetOwner()->SetColumnsOrder(order);
219 }
220
221
222 // event handlers forwarding wxHeaderCtrl events to wxGrid
223 void OnClick(wxHeaderCtrlEvent& event)
224 {
225 GetOwner()->SendEvent(wxEVT_GRID_LABEL_LEFT_CLICK,
226 -1, event.GetColumn(),
227 GetDummyMouseEvent());
228
229 GetOwner()->DoColHeaderClick(event.GetColumn());
230 }
231
232 void OnDoubleClick(wxHeaderCtrlEvent& event)
233 {
234 if ( !GetOwner()->SendEvent(wxEVT_GRID_LABEL_LEFT_DCLICK,
235 -1, event.GetColumn(),
236 GetDummyMouseEvent()) )
237 {
238 event.Skip();
239 }
240 }
241
242 void OnRightClick(wxHeaderCtrlEvent& event)
243 {
244 if ( !GetOwner()->SendEvent(wxEVT_GRID_LABEL_RIGHT_CLICK,
245 -1, event.GetColumn(),
246 GetDummyMouseEvent()) )
247 {
248 event.Skip();
249 }
250 }
251
252 void OnBeginResize(wxHeaderCtrlEvent& event)
253 {
254 GetOwner()->DoStartResizeCol(event.GetColumn());
255
256 event.Skip();
257 }
258
259 void OnResizing(wxHeaderCtrlEvent& event)
260 {
261 GetOwner()->DoUpdateResizeColWidth(event.GetWidth());
262 }
263
264 void OnEndResize(wxHeaderCtrlEvent& event)
265 {
266 // we again need to pass a mouse event to be used for the grid event
267 // generation but we don't have it here so use a dummy one as in
268 // UpdateColumnVisibility()
269 wxMouseEvent e;
270 e.SetState(wxGetMouseState());
271 GetOwner()->DoEndDragResizeCol(e);
272
273 event.Skip();
274 }
275
276 void OnBeginReorder(wxHeaderCtrlEvent& event)
277 {
278 GetOwner()->DoStartMoveCol(event.GetColumn());
279 }
280
281 void OnEndReorder(wxHeaderCtrlEvent& event)
282 {
283 GetOwner()->DoEndMoveCol(event.GetNewOrder());
284 }
285
286 wxVector<wxGridHeaderColumn> m_columns;
287
288 DECLARE_EVENT_TABLE()
289 wxDECLARE_NO_COPY_CLASS(wxGridHeaderCtrl);
290 };
291
292 // common base class for various grid subwindows
293 class WXDLLIMPEXP_ADV wxGridSubwindow : public wxWindow
294 {
295 public:
296 wxGridSubwindow(wxGrid *owner,
297 int additionalStyle = 0,
298 const wxString& name = wxPanelNameStr)
299 : wxWindow(owner, wxID_ANY,
300 wxDefaultPosition, wxDefaultSize,
301 wxBORDER_NONE | additionalStyle,
302 name)
303 {
304 m_owner = owner;
305 }
306
307 virtual wxWindow *GetMainWindowOfCompositeControl() { return m_owner; }
308
309 virtual bool AcceptsFocus() const { return false; }
310
311 wxGrid *GetOwner() { return m_owner; }
312
313 protected:
314 void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
315
316 wxGrid *m_owner;
317
318 DECLARE_EVENT_TABLE()
319 wxDECLARE_NO_COPY_CLASS(wxGridSubwindow);
320 };
321
322 class WXDLLIMPEXP_ADV wxGridRowLabelWindow : public wxGridSubwindow
323 {
324 public:
325 wxGridRowLabelWindow(wxGrid *parent)
326 : wxGridSubwindow(parent)
327 {
328 }
329
330
331 private:
332 void OnPaint( wxPaintEvent& event );
333 void OnMouseEvent( wxMouseEvent& event );
334 void OnMouseWheel( wxMouseEvent& event );
335
336 DECLARE_EVENT_TABLE()
337 wxDECLARE_NO_COPY_CLASS(wxGridRowLabelWindow);
338 };
339
340
341 class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxGridSubwindow
342 {
343 public:
344 wxGridColLabelWindow(wxGrid *parent)
345 : wxGridSubwindow(parent)
346 {
347 }
348
349
350 private:
351 void OnPaint( wxPaintEvent& event );
352 void OnMouseEvent( wxMouseEvent& event );
353 void OnMouseWheel( wxMouseEvent& event );
354
355 DECLARE_EVENT_TABLE()
356 wxDECLARE_NO_COPY_CLASS(wxGridColLabelWindow);
357 };
358
359
360 class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxGridSubwindow
361 {
362 public:
363 wxGridCornerLabelWindow(wxGrid *parent)
364 : wxGridSubwindow(parent)
365 {
366 }
367
368 private:
369 void OnMouseEvent( wxMouseEvent& event );
370 void OnMouseWheel( wxMouseEvent& event );
371 void OnPaint( wxPaintEvent& event );
372
373 DECLARE_EVENT_TABLE()
374 wxDECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow);
375 };
376
377 class WXDLLIMPEXP_ADV wxGridWindow : public wxGridSubwindow
378 {
379 public:
380 wxGridWindow(wxGrid *parent)
381 : wxGridSubwindow(parent,
382 wxWANTS_CHARS | wxCLIP_CHILDREN,
383 "GridWindow")
384 {
385 }
386
387
388 virtual void ScrollWindow( int dx, int dy, const wxRect *rect );
389
390 virtual bool AcceptsFocus() const { return true; }
391
392 private:
393 void OnPaint( wxPaintEvent &event );
394 void OnMouseWheel( wxMouseEvent& event );
395 void OnMouseEvent( wxMouseEvent& event );
396 void OnKeyDown( wxKeyEvent& );
397 void OnKeyUp( wxKeyEvent& );
398 void OnChar( wxKeyEvent& );
399 void OnEraseBackground( wxEraseEvent& );
400 void OnFocus( wxFocusEvent& );
401
402 DECLARE_EVENT_TABLE()
403 wxDECLARE_NO_COPY_CLASS(wxGridWindow);
404 };
405
406 // ----------------------------------------------------------------------------
407 // the internal data representation used by wxGridCellAttrProvider
408 // ----------------------------------------------------------------------------
409
410 // this class stores attributes set for cells
411 class WXDLLIMPEXP_ADV wxGridCellAttrData
412 {
413 public:
414 void SetAttr(wxGridCellAttr *attr, int row, int col);
415 wxGridCellAttr *GetAttr(int row, int col) const;
416 void UpdateAttrRows( size_t pos, int numRows );
417 void UpdateAttrCols( size_t pos, int numCols );
418
419 private:
420 // searches for the attr for given cell, returns wxNOT_FOUND if not found
421 int FindIndex(int row, int col) const;
422
423 wxGridCellWithAttrArray m_attrs;
424 };
425
426 // this class stores attributes set for rows or columns
427 class WXDLLIMPEXP_ADV wxGridRowOrColAttrData
428 {
429 public:
430 // empty ctor to suppress warnings
431 wxGridRowOrColAttrData() {}
432 ~wxGridRowOrColAttrData();
433
434 void SetAttr(wxGridCellAttr *attr, int rowOrCol);
435 wxGridCellAttr *GetAttr(int rowOrCol) const;
436 void UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols );
437
438 private:
439 wxArrayInt m_rowsOrCols;
440 wxArrayAttrs m_attrs;
441 };
442
443 // NB: this is just a wrapper around 3 objects: one which stores cell
444 // attributes, and 2 others for row/col ones
445 class WXDLLIMPEXP_ADV wxGridCellAttrProviderData
446 {
447 public:
448 wxGridCellAttrData m_cellAttrs;
449 wxGridRowOrColAttrData m_rowAttrs,
450 m_colAttrs;
451 };
452
453 // ----------------------------------------------------------------------------
454 // operations classes abstracting the difference between operating on rows and
455 // columns
456 // ----------------------------------------------------------------------------
457
458 // This class allows to write a function only once because by using its methods
459 // it will apply to both columns and rows.
460 //
461 // This is an abstract interface definition, the two concrete implementations
462 // below should be used when working with rows and columns respectively.
463 class wxGridOperations
464 {
465 public:
466 // Returns the operations in the other direction, i.e. wxGridRowOperations
467 // if this object is a wxGridColumnOperations and vice versa.
468 virtual wxGridOperations& Dual() const = 0;
469
470 // Return the number of rows or columns.
471 virtual int GetNumberOfLines(const wxGrid *grid) const = 0;
472
473 // Return the selection mode which allows selecting rows or columns.
474 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const = 0;
475
476 // Make a wxGridCellCoords from the given components: thisDir is row or
477 // column and otherDir is column or row
478 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const = 0;
479
480 // Calculate the scrolled position of the given abscissa or ordinate.
481 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const = 0;
482
483 // Selects the horizontal or vertical component from the given object.
484 virtual int Select(const wxGridCellCoords& coords) const = 0;
485 virtual int Select(const wxPoint& pt) const = 0;
486 virtual int Select(const wxSize& sz) const = 0;
487 virtual int Select(const wxRect& r) const = 0;
488 virtual int& Select(wxRect& r) const = 0;
489
490 // Returns width or height of the rectangle
491 virtual int& SelectSize(wxRect& r) const = 0;
492
493 // Make a wxSize such that Select() applied to it returns first component
494 virtual wxSize MakeSize(int first, int second) const = 0;
495
496 // Sets the row or column component of the given cell coordinates
497 virtual void Set(wxGridCellCoords& coords, int line) const = 0;
498
499
500 // Draws a line parallel to the row or column, i.e. horizontal or vertical:
501 // pos is the horizontal or vertical position of the line and start and end
502 // are the coordinates of the line extremities in the other direction
503 virtual void
504 DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0;
505
506 // Draw a horizontal or vertical line across the given rectangle
507 // (this is implemented in terms of above and uses Select() to extract
508 // start and end from the given rectangle)
509 void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const
510 {
511 const int posStart = Select(rect.GetPosition());
512 DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos);
513 }
514
515
516 // Return the index of the row or column at the given pixel coordinate.
517 virtual int
518 PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0;
519
520 // Get the top/left position, in pixels, of the given row or column
521 virtual int GetLineStartPos(const wxGrid *grid, int line) const = 0;
522
523 // Get the bottom/right position, in pixels, of the given row or column
524 virtual int GetLineEndPos(const wxGrid *grid, int line) const = 0;
525
526 // Get the height/width of the given row/column
527 virtual int GetLineSize(const wxGrid *grid, int line) const = 0;
528
529 // Get wxGrid::m_rowBottoms/m_colRights array
530 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const = 0;
531
532 // Get default height row height or column width
533 virtual int GetDefaultLineSize(const wxGrid *grid) const = 0;
534
535 // Return the minimal acceptable row height or column width
536 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const = 0;
537
538 // Return the minimal row height or column width
539 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const = 0;
540
541 // Set the row height or column width
542 virtual void SetLineSize(wxGrid *grid, int line, int size) const = 0;
543
544 // Set the row default height or column default width
545 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const = 0;
546
547
548 // Return the index of the line at the given position
549 //
550 // NB: currently this is always identity for the rows as reordering is only
551 // implemented for the lines
552 virtual int GetLineAt(const wxGrid *grid, int pos) const = 0;
553
554 // Return the display position of the line with the given index.
555 //
556 // NB: As GetLineAt(), currently this is always identity for rows.
557 virtual int GetLinePos(const wxGrid *grid, int line) const = 0;
558
559 // Return the index of the line just before the given one or wxNOT_FOUND.
560 virtual int GetLineBefore(const wxGrid* grid, int line) const = 0;
561
562 // Get the row or column label window
563 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const = 0;
564
565 // Get the width or height of the row or column label window
566 virtual int GetHeaderWindowSize(wxGrid *grid) const = 0;
567
568
569 // This class is never used polymorphically but give it a virtual dtor
570 // anyhow to suppress g++ complaints about it
571 virtual ~wxGridOperations() { }
572 };
573
574 class wxGridRowOperations : public wxGridOperations
575 {
576 public:
577 virtual wxGridOperations& Dual() const;
578
579 virtual int GetNumberOfLines(const wxGrid *grid) const
580 { return grid->GetNumberRows(); }
581
582 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const
583 { return wxGrid::wxGridSelectRows; }
584
585 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const
586 { return wxGridCellCoords(thisDir, otherDir); }
587
588 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const
589 { return grid->CalcScrolledPosition(wxPoint(pos, 0)).x; }
590
591 virtual int Select(const wxGridCellCoords& c) const { return c.GetRow(); }
592 virtual int Select(const wxPoint& pt) const { return pt.x; }
593 virtual int Select(const wxSize& sz) const { return sz.x; }
594 virtual int Select(const wxRect& r) const { return r.x; }
595 virtual int& Select(wxRect& r) const { return r.x; }
596 virtual int& SelectSize(wxRect& r) const { return r.width; }
597 virtual wxSize MakeSize(int first, int second) const
598 { return wxSize(first, second); }
599 virtual void Set(wxGridCellCoords& coords, int line) const
600 { coords.SetRow(line); }
601
602 virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const
603 { dc.DrawLine(start, pos, end, pos); }
604
605 virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const
606 { return grid->YToRow(pos, clip); }
607 virtual int GetLineStartPos(const wxGrid *grid, int line) const
608 { return grid->GetRowTop(line); }
609 virtual int GetLineEndPos(const wxGrid *grid, int line) const
610 { return grid->GetRowBottom(line); }
611 virtual int GetLineSize(const wxGrid *grid, int line) const
612 { return grid->GetRowHeight(line); }
613 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const
614 { return grid->m_rowBottoms; }
615 virtual int GetDefaultLineSize(const wxGrid *grid) const
616 { return grid->GetDefaultRowSize(); }
617 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const
618 { return grid->GetRowMinimalAcceptableHeight(); }
619 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const
620 { return grid->GetRowMinimalHeight(line); }
621 virtual void SetLineSize(wxGrid *grid, int line, int size) const
622 { grid->SetRowSize(line, size); }
623 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const
624 { grid->SetDefaultRowSize(size, resizeExisting); }
625
626 virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int pos) const
627 { return pos; } // TODO: implement row reordering
628 virtual int GetLinePos(const wxGrid * WXUNUSED(grid), int line) const
629 { return line; } // TODO: implement row reordering
630
631 virtual int GetLineBefore(const wxGrid* WXUNUSED(grid), int line) const
632 { return line - 1; }
633
634 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const
635 { return grid->GetGridRowLabelWindow(); }
636 virtual int GetHeaderWindowSize(wxGrid *grid) const
637 { return grid->GetRowLabelSize(); }
638 };
639
640 class wxGridColumnOperations : public wxGridOperations
641 {
642 public:
643 virtual wxGridOperations& Dual() const;
644
645 virtual int GetNumberOfLines(const wxGrid *grid) const
646 { return grid->GetNumberCols(); }
647
648 virtual wxGrid::wxGridSelectionModes GetSelectionMode() const
649 { return wxGrid::wxGridSelectColumns; }
650
651 virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const
652 { return wxGridCellCoords(otherDir, thisDir); }
653
654 virtual int CalcScrolledPosition(wxGrid *grid, int pos) const
655 { return grid->CalcScrolledPosition(wxPoint(0, pos)).y; }
656
657 virtual int Select(const wxGridCellCoords& c) const { return c.GetCol(); }
658 virtual int Select(const wxPoint& pt) const { return pt.y; }
659 virtual int Select(const wxSize& sz) const { return sz.y; }
660 virtual int Select(const wxRect& r) const { return r.y; }
661 virtual int& Select(wxRect& r) const { return r.y; }
662 virtual int& SelectSize(wxRect& r) const { return r.height; }
663 virtual wxSize MakeSize(int first, int second) const
664 { return wxSize(second, first); }
665 virtual void Set(wxGridCellCoords& coords, int line) const
666 { coords.SetCol(line); }
667
668 virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const
669 { dc.DrawLine(pos, start, pos, end); }
670
671 virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const
672 { return grid->XToCol(pos, clip); }
673 virtual int GetLineStartPos(const wxGrid *grid, int line) const
674 { return grid->GetColLeft(line); }
675 virtual int GetLineEndPos(const wxGrid *grid, int line) const
676 { return grid->GetColRight(line); }
677 virtual int GetLineSize(const wxGrid *grid, int line) const
678 { return grid->GetColWidth(line); }
679 virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const
680 { return grid->m_colRights; }
681 virtual int GetDefaultLineSize(const wxGrid *grid) const
682 { return grid->GetDefaultColSize(); }
683 virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const
684 { return grid->GetColMinimalAcceptableWidth(); }
685 virtual int GetMinimalLineSize(const wxGrid *grid, int line) const
686 { return grid->GetColMinimalWidth(line); }
687 virtual void SetLineSize(wxGrid *grid, int line, int size) const
688 { grid->SetColSize(line, size); }
689 virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const
690 { grid->SetDefaultColSize(size, resizeExisting); }
691
692 virtual int GetLineAt(const wxGrid *grid, int pos) const
693 { return grid->GetColAt(pos); }
694 virtual int GetLinePos(const wxGrid *grid, int line) const
695 { return grid->GetColPos(line); }
696
697 virtual int GetLineBefore(const wxGrid* grid, int line) const
698 {
699 int posBefore = grid->GetColPos(line) - 1;
700 return posBefore >= 0 ? grid->GetColAt(posBefore) : wxNOT_FOUND;
701 }
702
703 virtual wxWindow *GetHeaderWindow(wxGrid *grid) const
704 { return grid->GetGridColLabelWindow(); }
705 virtual int GetHeaderWindowSize(wxGrid *grid) const
706 { return grid->GetColLabelSize(); }
707 };
708
709 // This class abstracts the difference between operations going forward
710 // (down/right) and backward (up/left) and allows to use the same code for
711 // functions which differ only in the direction of grid traversal.
712 //
713 // Notice that all operations in this class work with display positions and not
714 // internal indices which can be different if the columns were reordered.
715 //
716 // Like wxGridOperations it's an ABC with two concrete subclasses below. Unlike
717 // it, this is a normal object and not just a function dispatch table and has a
718 // non-default ctor.
719 //
720 // Note: the explanation of this discrepancy is the existence of (very useful)
721 // Dual() method in wxGridOperations which forces us to make wxGridOperations a
722 // function dispatcher only.
723 class wxGridDirectionOperations
724 {
725 public:
726 // The oper parameter to ctor selects whether we work with rows or columns
727 wxGridDirectionOperations(wxGrid *grid, const wxGridOperations& oper)
728 : m_grid(grid),
729 m_oper(oper)
730 {
731 }
732
733 // Check if the component of this point in our direction is at the
734 // boundary, i.e. is the first/last row/column
735 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const = 0;
736
737 // Increment the component of this point in our direction
738 virtual void Advance(wxGridCellCoords& coords) const = 0;
739
740 // Find the line at the given distance, in pixels, away from this one
741 // (this uses clipping, i.e. anything after the last line is counted as the
742 // last one and anything before the first one as 0)
743 //
744 // TODO: Implementation of this method currently doesn't support column
745 // reordering as it mixes up indices and positions. But this doesn't
746 // really matter as it's only called for rows (Page Up/Down only work
747 // vertically) and row reordering is not currently supported. We'd
748 // need to fix it if this ever changes however.
749 virtual int MoveByPixelDistance(int line, int distance) const = 0;
750
751 // This class is never used polymorphically but give it a virtual dtor
752 // anyhow to suppress g++ complaints about it
753 virtual ~wxGridDirectionOperations() { }
754
755 protected:
756 // Get the position of the row or column from the given coordinates pair.
757 //
758 // This is just a shortcut to avoid repeating m_oper and m_grid multiple
759 // times in the derived classes code.
760 int GetLinePos(const wxGridCellCoords& coords) const
761 {
762 return m_oper.GetLinePos(m_grid, m_oper.Select(coords));
763 }
764
765 // Get the index of the row or column from the position.
766 int GetLineAt(int pos) const
767 {
768 return m_oper.GetLineAt(m_grid, pos);
769 }
770
771 // Check if the given line is visible, i.e. has non 0 size.
772 bool IsLineVisible(int line) const
773 {
774 return m_oper.GetLineSize(m_grid, line) != 0;
775 }
776
777
778 wxGrid * const m_grid;
779 const wxGridOperations& m_oper;
780 };
781
782 class wxGridBackwardOperations : public wxGridDirectionOperations
783 {
784 public:
785 wxGridBackwardOperations(wxGrid *grid, const wxGridOperations& oper)
786 : wxGridDirectionOperations(grid, oper)
787 {
788 }
789
790 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const
791 {
792 wxASSERT_MSG( m_oper.Select(coords) >= 0, "invalid row/column" );
793
794 int pos = GetLinePos(coords);
795 while ( pos )
796 {
797 // Check the previous line.
798 int line = GetLineAt(--pos);
799 if ( IsLineVisible(line) )
800 {
801 // There is another visible line before this one, hence it's
802 // not at boundary.
803 return false;
804 }
805 }
806
807 // We reached the boundary without finding any visible lines.
808 return true;
809 }
810
811 virtual void Advance(wxGridCellCoords& coords) const
812 {
813 int pos = GetLinePos(coords);
814 for ( ;; )
815 {
816 // This is not supposed to happen if IsAtBoundary() returned false.
817 wxCHECK_RET( pos, "can't advance when already at boundary" );
818
819 int line = GetLineAt(--pos);
820 if ( IsLineVisible(line) )
821 {
822 m_oper.Set(coords, line);
823 break;
824 }
825 }
826 }
827
828 virtual int MoveByPixelDistance(int line, int distance) const
829 {
830 int pos = m_oper.GetLineStartPos(m_grid, line);
831 return m_oper.PosToLine(m_grid, pos - distance + 1, true);
832 }
833 };
834
835 // Please refer to the comments above when reading this class code, it's
836 // absolutely symmetrical to wxGridBackwardOperations.
837 class wxGridForwardOperations : public wxGridDirectionOperations
838 {
839 public:
840 wxGridForwardOperations(wxGrid *grid, const wxGridOperations& oper)
841 : wxGridDirectionOperations(grid, oper),
842 m_numLines(oper.GetNumberOfLines(grid))
843 {
844 }
845
846 virtual bool IsAtBoundary(const wxGridCellCoords& coords) const
847 {
848 wxASSERT_MSG( m_oper.Select(coords) < m_numLines, "invalid row/column" );
849
850 int pos = GetLinePos(coords);
851 while ( pos < m_numLines - 1 )
852 {
853 int line = GetLineAt(++pos);
854 if ( IsLineVisible(line) )
855 return false;
856 }
857
858 return true;
859 }
860
861 virtual void Advance(wxGridCellCoords& coords) const
862 {
863 int pos = GetLinePos(coords);
864 for ( ;; )
865 {
866 wxCHECK_RET( pos < m_numLines - 1,
867 "can't advance when already at boundary" );
868
869 int line = GetLineAt(++pos);
870 if ( IsLineVisible(line) )
871 {
872 m_oper.Set(coords, line);
873 break;
874 }
875 }
876 }
877
878 virtual int MoveByPixelDistance(int line, int distance) const
879 {
880 int pos = m_oper.GetLineStartPos(m_grid, line);
881 return m_oper.PosToLine(m_grid, pos + distance, true);
882 }
883
884 private:
885 const int m_numLines;
886 };
887
888 // ----------------------------------------------------------------------------
889 // data structures used for the data type registry
890 // ----------------------------------------------------------------------------
891
892 struct wxGridDataTypeInfo
893 {
894 wxGridDataTypeInfo(const wxString& typeName,
895 wxGridCellRenderer* renderer,
896 wxGridCellEditor* editor)
897 : m_typeName(typeName), m_renderer(renderer), m_editor(editor)
898 {}
899
900 ~wxGridDataTypeInfo()
901 {
902 wxSafeDecRef(m_renderer);
903 wxSafeDecRef(m_editor);
904 }
905
906 wxString m_typeName;
907 wxGridCellRenderer* m_renderer;
908 wxGridCellEditor* m_editor;
909
910 wxDECLARE_NO_COPY_CLASS(wxGridDataTypeInfo);
911 };
912
913
914 WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridDataTypeInfo*, wxGridDataTypeInfoArray,
915 class WXDLLIMPEXP_ADV);
916
917
918 class WXDLLIMPEXP_ADV wxGridTypeRegistry
919 {
920 public:
921 wxGridTypeRegistry() {}
922 ~wxGridTypeRegistry();
923
924 void RegisterDataType(const wxString& typeName,
925 wxGridCellRenderer* renderer,
926 wxGridCellEditor* editor);
927
928 // find one of already registered data types
929 int FindRegisteredDataType(const wxString& typeName);
930
931 // try to FindRegisteredDataType(), if this fails and typeName is one of
932 // standard typenames, register it and return its index
933 int FindDataType(const wxString& typeName);
934
935 // try to FindDataType(), if it fails see if it is not one of already
936 // registered data types with some params in which case clone the
937 // registered data type and set params for it
938 int FindOrCloneDataType(const wxString& typeName);
939
940 wxGridCellRenderer* GetRenderer(int index);
941 wxGridCellEditor* GetEditor(int index);
942
943 private:
944 wxGridDataTypeInfoArray m_typeinfo;
945 };
946
947 #endif // wxUSE_GRID
948 #endif // _WX_GENERIC_GRID_PRIVATE_H_