home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / samples / newgrid / griddemo.cpp next >
C/C++ Source or Header  |  2002-12-16  |  40KB  |  1,362 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        griddemo.cpp
  3. // Purpose:     Grid control wxWindows sample
  4. // Author:      Michael Bedward
  5. // Modified by:
  6. // RCS-ID:      $Id: griddemo.cpp,v 1.58.2.4 2002/12/15 17:25:16 MBN Exp $
  7. // Copyright:   (c) Michael Bedward, Julian Smart
  8. // Licence:     wxWindows license
  9. /////////////////////////////////////////////////////////////////////////////
  10.  
  11. // ============================================================================
  12. // declarations
  13. // ============================================================================
  14.  
  15. // ----------------------------------------------------------------------------
  16. // headers
  17. // ----------------------------------------------------------------------------
  18.  
  19. #ifdef __GNUG__
  20.     #pragma implementation
  21.     #pragma interface
  22. #endif
  23.  
  24. // For compilers that support precompilation, includes "wx/wx.h".
  25. #include "wx/wxprec.h"
  26.  
  27. #ifdef __BORLANDC__
  28. #pragma hdrstop
  29. #endif
  30.  
  31. #ifndef WX_PRECOMP
  32.     #include "wx/wx.h"
  33. #endif
  34.  
  35. #include "wx/colordlg.h"
  36. #include "wx/fontdlg.h"
  37.  
  38. #include "wx/grid.h"
  39. #include "wx/generic/gridctrl.h"
  40.  
  41. #include "griddemo.h"
  42.  
  43. // ----------------------------------------------------------------------------
  44. // wxWin macros
  45. // ----------------------------------------------------------------------------
  46.  
  47. IMPLEMENT_APP( GridApp )
  48.  
  49. // ============================================================================
  50. // implementation
  51. // ============================================================================
  52.  
  53. // ----------------------------------------------------------------------------
  54. // GridApp
  55. // ----------------------------------------------------------------------------
  56.  
  57. bool GridApp::OnInit()
  58. {
  59.     GridFrame *frame = new GridFrame;
  60.     frame->Show( TRUE );
  61.  
  62.     return TRUE;
  63. }
  64.  
  65. // ----------------------------------------------------------------------------
  66. // GridFrame
  67. // ----------------------------------------------------------------------------
  68.  
  69. BEGIN_EVENT_TABLE( GridFrame, wxFrame )
  70.     EVT_MENU( ID_TOGGLEROWLABELS,  GridFrame::ToggleRowLabels )
  71.     EVT_MENU( ID_TOGGLECOLLABELS,  GridFrame::ToggleColLabels )
  72.     EVT_MENU( ID_TOGGLEEDIT, GridFrame::ToggleEditing )
  73.     EVT_MENU( ID_TOGGLEROWSIZING, GridFrame::ToggleRowSizing )
  74.     EVT_MENU( ID_TOGGLECOLSIZING, GridFrame::ToggleColSizing )
  75.     EVT_MENU( ID_TOGGLEGRIDSIZING, GridFrame::ToggleGridSizing )
  76.     EVT_MENU( ID_TOGGLEGRIDLINES, GridFrame::ToggleGridLines )
  77.     EVT_MENU( ID_AUTOSIZECOLS, GridFrame::AutoSizeCols )
  78.     EVT_MENU( ID_CELLOVERFLOW, GridFrame::CellOverflow )
  79.     EVT_MENU( ID_RESIZECELL, GridFrame::ResizeCell )
  80.     EVT_MENU( ID_SETLABELCOLOUR, GridFrame::SetLabelColour )
  81.     EVT_MENU( ID_SETLABELTEXTCOLOUR, GridFrame::SetLabelTextColour )
  82.     EVT_MENU( ID_SETLABEL_FONT, GridFrame::SetLabelFont )
  83.     EVT_MENU( ID_ROWLABELHORIZALIGN, GridFrame::SetRowLabelHorizAlignment )
  84.     EVT_MENU( ID_ROWLABELVERTALIGN, GridFrame::SetRowLabelVertAlignment )
  85.     EVT_MENU( ID_COLLABELHORIZALIGN, GridFrame::SetColLabelHorizAlignment )
  86.     EVT_MENU( ID_COLLABELVERTALIGN, GridFrame::SetColLabelVertAlignment )
  87.     EVT_MENU( ID_GRIDLINECOLOUR, GridFrame::SetGridLineColour )
  88.     EVT_MENU( ID_INSERTROW, GridFrame::InsertRow )
  89.     EVT_MENU( ID_INSERTCOL, GridFrame::InsertCol )
  90.     EVT_MENU( ID_DELETEROW, GridFrame::DeleteSelectedRows )
  91.     EVT_MENU( ID_DELETECOL, GridFrame::DeleteSelectedCols )
  92.     EVT_MENU( ID_CLEARGRID, GridFrame::ClearGrid )
  93.     EVT_MENU( ID_SELCELLS,  GridFrame::SelectCells )
  94.     EVT_MENU( ID_SELROWS,  GridFrame::SelectRows )
  95.     EVT_MENU( ID_SELCOLS,  GridFrame::SelectCols )
  96.  
  97.     EVT_MENU( ID_SET_CELL_FG_COLOUR, GridFrame::SetCellFgColour )
  98.     EVT_MENU( ID_SET_CELL_BG_COLOUR, GridFrame::SetCellBgColour )
  99.  
  100.     EVT_MENU( ID_ABOUT, GridFrame::About )
  101.     EVT_MENU( wxID_EXIT, GridFrame::OnQuit )
  102.     EVT_MENU( ID_VTABLE, GridFrame::OnVTable)
  103.     EVT_MENU( ID_BUGS_TABLE, GridFrame::OnBugsTable)
  104.     EVT_MENU( ID_SMALL_GRID, GridFrame::OnSmallGrid)
  105.  
  106.     EVT_MENU( ID_DESELECT_CELL, GridFrame::DeselectCell)
  107.     EVT_MENU( ID_DESELECT_COL, GridFrame::DeselectCol)
  108.     EVT_MENU( ID_DESELECT_ROW, GridFrame::DeselectRow)
  109.     EVT_MENU( ID_DESELECT_ALL, GridFrame::DeselectAll)
  110.     EVT_MENU( ID_SELECT_CELL, GridFrame::SelectCell)
  111.     EVT_MENU( ID_SELECT_COL, GridFrame::SelectCol)
  112.     EVT_MENU( ID_SELECT_ROW, GridFrame::SelectRow)
  113.     EVT_MENU( ID_SELECT_ALL, GridFrame::SelectAll)
  114.     EVT_MENU( ID_SELECT_UNSELECT, GridFrame::OnAddToSelectToggle)
  115.  
  116.     EVT_MENU( ID_SET_HIGHLIGHT_WIDTH, GridFrame::OnSetHighlightWidth)
  117.     EVT_MENU( ID_SET_RO_HIGHLIGHT_WIDTH, GridFrame::OnSetROHighlightWidth)
  118.  
  119.     EVT_GRID_LABEL_LEFT_CLICK( GridFrame::OnLabelLeftClick )
  120.     EVT_GRID_CELL_LEFT_CLICK( GridFrame::OnCellLeftClick )
  121.     EVT_GRID_ROW_SIZE( GridFrame::OnRowSize )
  122.     EVT_GRID_COL_SIZE( GridFrame::OnColSize )
  123.     EVT_GRID_SELECT_CELL( GridFrame::OnSelectCell )
  124.     EVT_GRID_RANGE_SELECT( GridFrame::OnRangeSelected )
  125.     EVT_GRID_CELL_CHANGE( GridFrame::OnCellValueChanged )
  126.  
  127.     EVT_GRID_EDITOR_SHOWN( GridFrame::OnEditorShown )
  128.     EVT_GRID_EDITOR_HIDDEN( GridFrame::OnEditorHidden )
  129. END_EVENT_TABLE()
  130.  
  131.  
  132. GridFrame::GridFrame()
  133.         : wxFrame( (wxFrame *)NULL, -1, _T("wxWindows grid class demo"),
  134.                    wxDefaultPosition,
  135.                    wxDefaultSize )
  136. {
  137.     int gridW = 600, gridH = 300;
  138.     int logW = gridW, logH = 100;
  139.  
  140.     wxMenu *fileMenu = new wxMenu;
  141.     fileMenu->Append( ID_VTABLE, _T("&Virtual table test\tCtrl-V"));
  142.     fileMenu->Append( ID_BUGS_TABLE, _T("&Bugs table test\tCtrl-B"));
  143.     fileMenu->Append( ID_SMALL_GRID, _T("&Small Grid test\tCtrl-S"));
  144.     fileMenu->AppendSeparator();
  145.     fileMenu->Append( wxID_EXIT, _T("E&xit\tAlt-X") );
  146.  
  147.     wxMenu *viewMenu = new wxMenu;
  148.     viewMenu->Append( ID_TOGGLEROWLABELS,  _T("&Row labels"), _T(""), TRUE );
  149.     viewMenu->Append( ID_TOGGLECOLLABELS,  _T("&Col labels"), _T(""), TRUE );
  150.     viewMenu->Append( ID_TOGGLEEDIT,  _T("&Editable"), _T(""), TRUE );
  151.     viewMenu->Append( ID_TOGGLEROWSIZING, _T("Ro&w drag-resize"), _T(""), TRUE );
  152.     viewMenu->Append( ID_TOGGLECOLSIZING, _T("C&ol drag-resize"), _T(""), TRUE );
  153.     viewMenu->Append( ID_TOGGLEGRIDSIZING, _T("&Grid drag-resize"), _T(""), TRUE );
  154.     viewMenu->Append( ID_TOGGLEGRIDLINES, _T("&Grid Lines"), _T(""), TRUE );
  155.     viewMenu->Append( ID_SET_HIGHLIGHT_WIDTH, _T("&Set Cell Highlight Width..."), _T("") );
  156.     viewMenu->Append( ID_SET_RO_HIGHLIGHT_WIDTH, _T("&Set Cell RO Highlight Width..."), _T("") );
  157.     viewMenu->Append( ID_AUTOSIZECOLS, _T("&Auto-size cols") );
  158.     viewMenu->Append( ID_CELLOVERFLOW, _T("&Overflow cells"), _T(""), TRUE );
  159.     viewMenu->Append( ID_RESIZECELL, _T("&Resize cell (7,1)"), _T(""), TRUE );
  160.  
  161.     wxMenu *rowLabelMenu = new wxMenu;
  162.  
  163.     viewMenu->Append( ID_ROWLABELALIGN, _T("R&ow label alignment"),
  164.                       rowLabelMenu,
  165.                       _T("Change alignment of row labels") );
  166.  
  167.     rowLabelMenu->Append( ID_ROWLABELHORIZALIGN, _T("&Horizontal") );
  168.     rowLabelMenu->Append( ID_ROWLABELVERTALIGN, _T("&Vertical") );
  169.  
  170.     wxMenu *colLabelMenu = new wxMenu;
  171.  
  172.     viewMenu->Append( ID_COLLABELALIGN, _T("Col l&abel alignment"),
  173.                       colLabelMenu,
  174.                       _T("Change alignment of col labels") );
  175.  
  176.     colLabelMenu->Append( ID_COLLABELHORIZALIGN, _T("&Horizontal") );
  177.     colLabelMenu->Append( ID_COLLABELVERTALIGN, _T("&Vertical") );
  178.  
  179.     wxMenu *colMenu = new wxMenu;
  180.     colMenu->Append( ID_SETLABELCOLOUR, _T("Set &label colour...") );
  181.     colMenu->Append( ID_SETLABELTEXTCOLOUR, _T("Set label &text colour...") );
  182.     colMenu->Append( ID_SETLABEL_FONT, _T("Set label fo&nt...") );
  183.     colMenu->Append( ID_GRIDLINECOLOUR, _T("&Grid line colour...") );
  184.     colMenu->Append( ID_SET_CELL_FG_COLOUR, _T("Set cell &foreground colour...") );
  185.     colMenu->Append( ID_SET_CELL_BG_COLOUR, _T("Set cell &background colour...") );
  186.  
  187.     wxMenu *editMenu = new wxMenu;
  188.     editMenu->Append( ID_INSERTROW, _T("Insert &row") );
  189.     editMenu->Append( ID_INSERTCOL, _T("Insert &column") );
  190.     editMenu->Append( ID_DELETEROW, _T("Delete selected ro&ws") );
  191.     editMenu->Append( ID_DELETECOL, _T("Delete selected co&ls") );
  192.     editMenu->Append( ID_CLEARGRID, _T("Cl&ear grid cell contents") );
  193.  
  194.     wxMenu *selectMenu = new wxMenu;
  195.     selectMenu->Append( ID_SELECT_UNSELECT, _T("Add new cells to the selection"),
  196.                         _T("When off, old selection is deselected before ")
  197.                         _T("selecting the new cells"), TRUE );
  198.     selectMenu->Append( ID_SELECT_ALL, _T("Select all"));
  199.     selectMenu->Append( ID_SELECT_ROW, _T("Select row 2"));
  200.     selectMenu->Append( ID_SELECT_COL, _T("Select col 2"));
  201.     selectMenu->Append( ID_SELECT_CELL, _T("Select cell (3, 1)"));
  202.     selectMenu->Append( ID_DESELECT_ALL, _T("Deselect all"));
  203.     selectMenu->Append( ID_DESELECT_ROW, _T("Deselect row 2"));
  204.     selectMenu->Append( ID_DESELECT_COL, _T("Deselect col 2"));
  205.     selectMenu->Append( ID_DESELECT_CELL, _T("Deselect cell (3, 1)"));
  206.     wxMenu *selectionMenu = new wxMenu;
  207.     selectMenu->Append( ID_CHANGESEL, _T("Change &selection mode"),
  208.                       selectionMenu,
  209.                       _T("Change selection mode") );
  210.  
  211.     selectionMenu->Append( ID_SELCELLS, _T("Select &Cells") );
  212.     selectionMenu->Append( ID_SELROWS, _T("Select &Rows") );
  213.     selectionMenu->Append( ID_SELCOLS, _T("Select C&ols") );
  214.  
  215.  
  216.     wxMenu *helpMenu = new wxMenu;
  217.     helpMenu->Append( ID_ABOUT, _T("&About wxGrid demo") );
  218.  
  219.     wxMenuBar *menuBar = new wxMenuBar;
  220.     menuBar->Append( fileMenu, _T("&File") );
  221.     menuBar->Append( viewMenu, _T("&View") );
  222.     menuBar->Append( colMenu,  _T("&Colours") );
  223.     menuBar->Append( editMenu, _T("&Edit") );
  224.     menuBar->Append( selectMenu, _T("&Select") );
  225.     menuBar->Append( helpMenu, _T("&Help") );
  226.  
  227.     SetMenuBar( menuBar );
  228.  
  229.     m_addToSel = FALSE;
  230.  
  231.     grid = new wxGrid( this,
  232.                        -1,
  233.                        wxPoint( 0, 0 ),
  234.                        wxSize( 400, 300 ) );
  235.  
  236.     logWin = new wxTextCtrl( this,
  237.                              -1,
  238.                              wxEmptyString,
  239.                              wxPoint( 0, gridH + 20 ),
  240.                              wxSize( logW, logH ),
  241.                              wxTE_MULTILINE );
  242.  
  243.     logger = new wxLogTextCtrl( logWin );
  244.     m_logOld = logger->SetActiveTarget( logger );
  245.     logger->SetTimestamp( NULL );
  246.  
  247.     // this will create a grid and, by default, an associated grid
  248.     // table for strings
  249.     grid->CreateGrid( 0, 0 );
  250.     grid->AppendRows(100);
  251.     grid->AppendCols(100);
  252.  
  253.     int ir = grid->GetNumberRows();
  254.     grid->DeleteRows(0, ir);
  255.     grid->AppendRows(ir);
  256.  
  257.     grid->SetRowSize( 0, 60 );
  258.     grid->SetCellValue( 0, 0, _T("Ctrl+Home\nwill go to\nthis cell") );
  259.  
  260.     grid->SetCellValue( 0, 1, _T("A long piece of text to demonstrate wrapping.") );
  261.     grid->SetCellRenderer(0 , 1, new wxGridCellAutoWrapStringRenderer);
  262.     grid->SetCellEditor( 0,  1 , new wxGridCellAutoWrapStringEditor);
  263.  
  264.     grid->SetCellValue( 0, 2, _T("Blah") );
  265.     grid->SetCellValue( 0, 3, _T("Read only") );
  266.     grid->SetReadOnly( 0, 3 );
  267.  
  268.     grid->SetCellValue( 0, 4, _T("Can veto edit this cell") );
  269.  
  270.     grid->SetCellValue( 0, 5, _T("Press\nCtrl+arrow\nto skip over\ncells") );
  271.  
  272.     grid->SetRowSize( 99, 60 );
  273.     grid->SetCellValue( 99, 99, _T("Ctrl+End\nwill go to\nthis cell") );
  274.     grid->SetCellValue( 1, 0, _T("This default cell will overflow into neighboring cells, but not if you turn overflow off."));
  275.  
  276.     grid->SetCellTextColour(1, 2, *wxRED);
  277.     grid->SetCellBackgroundColour(1, 2, *wxGREEN);
  278.  
  279.     grid->SetCellValue( 1, 4, _T("I'm in the middle"));
  280.  
  281.     grid->SetCellValue(2, 2, _T("red"));
  282.  
  283.     grid->SetCellTextColour(2, 2, *wxRED);
  284.     grid->SetCellValue(3, 3, _T("green on grey"));
  285.     grid->SetCellTextColour(3, 3, *wxGREEN);
  286.     grid->SetCellBackgroundColour(3, 3, *wxLIGHT_GREY);
  287.  
  288.     grid->SetCellValue(4, 4, _T("a weird looking cell"));
  289.     grid->SetCellAlignment(4, 4, wxALIGN_CENTRE, wxALIGN_CENTRE);
  290.     grid->SetCellRenderer(4, 4, new MyGridCellRenderer);
  291.  
  292.     grid->SetCellValue(3, 0, _T("0"));
  293.     grid->SetCellRenderer(3, 0, new wxGridCellBoolRenderer);
  294.     grid->SetCellEditor(3, 0, new wxGridCellBoolEditor);
  295.  
  296.     wxGridCellAttr *attr;
  297.     attr = new wxGridCellAttr;
  298.     attr->SetTextColour(*wxBLUE);
  299.     grid->SetColAttr(5, attr);
  300.     attr = new wxGridCellAttr;
  301.     attr->SetBackgroundColour(*wxRED);
  302.     grid->SetRowAttr(5, attr);
  303.  
  304.     grid->SetCellValue(2, 4, _T("a wider column"));
  305.     grid->SetColSize(4, 120);
  306.     grid->SetColMinimalWidth(4, 120);
  307.  
  308.     grid->SetCellTextColour(5, 8, *wxGREEN);
  309.     grid->SetCellValue(5, 8, _T("Bg from row attr\nText col from cell attr"));
  310.     grid->SetCellValue(5, 5, _T("Bg from row attr Text col from col attr and this text is so long that it covers over many many empty cells but is broken by one that isn't"));
  311.  
  312.     grid->SetColFormatFloat(6);
  313.     grid->SetCellValue(0, 6, _T("3.1415"));
  314.     grid->SetCellValue(1, 6, _T("1415"));
  315.     grid->SetCellValue(2, 6, _T("12345.67890"));
  316.  
  317.     grid->SetColFormatFloat(7, 6, 2);
  318.     grid->SetCellValue(0, 7, _T("3.1415"));
  319.     grid->SetCellValue(1, 7, _T("1415"));
  320.     grid->SetCellValue(2, 7, _T("12345.67890"));
  321.  
  322.     const wxString choices[] =
  323.     {
  324.         _T("Please select a choice"),
  325.         _T("This takes two cells"),
  326.         _T("Another choice"),
  327.     };
  328.     grid->SetCellEditor(4, 0, new wxGridCellChoiceEditor(WXSIZEOF(choices), choices));
  329.     grid->SetCellSize(4, 0, 1, 2);
  330.     grid->SetCellValue(4, 0, choices[0]);
  331.     grid->SetCellOverflow(4, 0, FALSE);
  332.  
  333.     grid->SetCellSize(7, 1, 3, 4);
  334.     grid->SetCellAlignment(7, 1, wxALIGN_CENTRE, wxALIGN_CENTRE);
  335.     grid->SetCellValue(7, 1, _T("Big box!"));
  336.  
  337.     wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
  338.     topSizer->Add( grid,
  339.                    1,
  340.                    wxEXPAND );
  341.  
  342.     topSizer->Add( logWin,
  343.                    0,
  344.                    wxEXPAND );
  345.  
  346.     SetAutoLayout( TRUE );
  347.     SetSizer( topSizer );
  348.  
  349.     topSizer->Fit( this );
  350.     topSizer->SetSizeHints( this );
  351.  
  352.     Centre();
  353.     SetDefaults();
  354. }
  355.  
  356.  
  357. GridFrame::~GridFrame()
  358. {
  359.     delete wxLog::SetActiveTarget(m_logOld);
  360. }
  361.  
  362.  
  363. void GridFrame::SetDefaults()
  364. {
  365.     GetMenuBar()->Check( ID_TOGGLEROWLABELS, TRUE );
  366.     GetMenuBar()->Check( ID_TOGGLECOLLABELS, TRUE );
  367.     GetMenuBar()->Check( ID_TOGGLEEDIT, TRUE );
  368.     GetMenuBar()->Check( ID_TOGGLEROWSIZING, TRUE );
  369.     GetMenuBar()->Check( ID_TOGGLECOLSIZING, TRUE );
  370.     GetMenuBar()->Check( ID_TOGGLEGRIDSIZING, TRUE );
  371.     GetMenuBar()->Check( ID_TOGGLEGRIDLINES, TRUE );
  372.     GetMenuBar()->Check( ID_CELLOVERFLOW, TRUE );
  373. }
  374.  
  375.  
  376. void GridFrame::ToggleRowLabels( wxCommandEvent& WXUNUSED(ev) )
  377. {
  378.     if ( GetMenuBar()->IsChecked( ID_TOGGLEROWLABELS ) )
  379.     {
  380.         grid->SetRowLabelSize( grid->GetDefaultRowLabelSize() );
  381.     }
  382.     else
  383.     {
  384.         grid->SetRowLabelSize( 0 );
  385.     }
  386. }
  387.  
  388.  
  389. void GridFrame::ToggleColLabels( wxCommandEvent& WXUNUSED(ev) )
  390. {
  391.     if ( GetMenuBar()->IsChecked( ID_TOGGLECOLLABELS ) )
  392.     {
  393.         grid->SetColLabelSize( grid->GetDefaultColLabelSize() );
  394.     }
  395.     else
  396.     {
  397.         grid->SetColLabelSize( 0 );
  398.     }
  399. }
  400.  
  401.  
  402. void GridFrame::ToggleEditing( wxCommandEvent& WXUNUSED(ev) )
  403. {
  404.     grid->EnableEditing(
  405.         GetMenuBar()->IsChecked( ID_TOGGLEEDIT ) );
  406. }
  407.  
  408.  
  409. void GridFrame::ToggleRowSizing( wxCommandEvent& WXUNUSED(ev) )
  410. {
  411.     grid->EnableDragRowSize(
  412.         GetMenuBar()->IsChecked( ID_TOGGLEROWSIZING ) );
  413. }
  414.  
  415.  
  416. void GridFrame::ToggleColSizing( wxCommandEvent& WXUNUSED(ev) )
  417. {
  418.     grid->EnableDragColSize(
  419.         GetMenuBar()->IsChecked( ID_TOGGLECOLSIZING ) );
  420. }
  421.  
  422. void GridFrame::ToggleGridSizing( wxCommandEvent& WXUNUSED(ev) )
  423. {
  424.     grid->EnableDragGridSize(
  425.         GetMenuBar()->IsChecked( ID_TOGGLEGRIDSIZING ) );
  426. }
  427.  
  428.  
  429. void GridFrame::ToggleGridLines( wxCommandEvent& WXUNUSED(ev) )
  430. {
  431.     grid->EnableGridLines(
  432.         GetMenuBar()->IsChecked( ID_TOGGLEGRIDLINES ) );
  433. }
  434.  
  435. void GridFrame::OnSetHighlightWidth( wxCommandEvent& WXUNUSED(ev) )
  436. {
  437.     wxString choices[] = { _T("0"), _T("1"), _T("2"), _T("3"), _T("4"), _T("5"), _T("6"), _T("7"), _T("8"), _T("9"), _T("10")};
  438.  
  439.     wxSingleChoiceDialog dlg(this, _T("Choose the thickness of the highlight pen:"),
  440.                              _T("Pen Width"), 11, choices);
  441.  
  442.     int current = grid->GetCellHighlightPenWidth();
  443.     dlg.SetSelection(current);
  444.     if (dlg.ShowModal() == wxID_OK) {
  445.         grid->SetCellHighlightPenWidth(dlg.GetSelection());
  446.     }
  447. }
  448.  
  449. void GridFrame::OnSetROHighlightWidth( wxCommandEvent& WXUNUSED(ev) )
  450. {
  451.     wxString choices[] = { _T("0"), _T("1"), _T("2"), _T("3"), _T("4"), _T("5"), _T("6"), _T("7"), _T("8"), _T("9"), _T("10")};
  452.  
  453.     wxSingleChoiceDialog dlg(this, _T("Choose the thickness of the highlight pen:"),
  454.                              _T("Pen Width"), 11, choices);
  455.  
  456.     int current = grid->GetCellHighlightROPenWidth();
  457.     dlg.SetSelection(current);
  458.     if (dlg.ShowModal() == wxID_OK) {
  459.         grid->SetCellHighlightROPenWidth(dlg.GetSelection());
  460.     }
  461. }
  462.  
  463.  
  464.  
  465. void GridFrame::AutoSizeCols( wxCommandEvent& WXUNUSED(ev) )
  466. {
  467.     grid->AutoSizeColumns();
  468.     grid->Refresh();
  469. }
  470.  
  471. void GridFrame::CellOverflow( wxCommandEvent& ev )
  472. {
  473.     grid->SetDefaultCellOverflow(ev.IsChecked());
  474.     grid->Refresh();
  475. }
  476.  
  477. void GridFrame::ResizeCell( wxCommandEvent& ev )
  478. {
  479.     if (ev.IsChecked())
  480.         grid->SetCellSize( 7, 1, 5, 5 );
  481.     else
  482.         grid->SetCellSize( 7, 1, 1, 5 );
  483.     grid->Refresh();
  484. }
  485.  
  486. void GridFrame::SetLabelColour( wxCommandEvent& WXUNUSED(ev) )
  487. {
  488.     wxColourDialog dlg( NULL );
  489.     if ( dlg.ShowModal() == wxID_OK )
  490.     {
  491.         wxColourData retData;
  492.         retData = dlg.GetColourData();
  493.         wxColour colour = retData.GetColour();
  494.  
  495.         grid->SetLabelBackgroundColour( colour );
  496.     }
  497. }
  498.  
  499.  
  500. void GridFrame::SetLabelTextColour( wxCommandEvent& WXUNUSED(ev) )
  501. {
  502.     wxColourDialog dlg( NULL );
  503.     if ( dlg.ShowModal() == wxID_OK )
  504.     {
  505.         wxColourData retData;
  506.         retData = dlg.GetColourData();
  507.         wxColour colour = retData.GetColour();
  508.  
  509.         grid->SetLabelTextColour( colour );
  510.     }
  511. }
  512.  
  513. void GridFrame::SetLabelFont( wxCommandEvent& WXUNUSED(ev) )
  514. {
  515.     wxFont font = wxGetFontFromUser(this);
  516.     if ( font.Ok() )
  517.     {
  518.         grid->SetLabelFont(font);
  519.     }
  520. }
  521.  
  522. void GridFrame::SetRowLabelHorizAlignment( wxCommandEvent& WXUNUSED(ev) )
  523. {
  524.     int horiz, vert;
  525.     grid->GetRowLabelAlignment( &horiz, &vert );
  526.  
  527.     switch ( horiz )
  528.     {
  529.         case wxALIGN_LEFT:
  530.             horiz = wxALIGN_CENTRE;
  531.             break;
  532.  
  533.         case wxALIGN_CENTRE:
  534.             horiz = wxALIGN_RIGHT;
  535.             break;
  536.  
  537.         case wxALIGN_RIGHT:
  538.             horiz = wxALIGN_LEFT;
  539.             break;
  540.     }
  541.  
  542.     grid->SetRowLabelAlignment( horiz, -1 );
  543. }
  544.  
  545. void GridFrame::SetRowLabelVertAlignment( wxCommandEvent& WXUNUSED(ev) )
  546. {
  547.     int horiz, vert;
  548.     grid->GetRowLabelAlignment( &horiz, &vert );
  549.  
  550.     switch ( vert )
  551.     {
  552.         case wxALIGN_TOP:
  553.             vert = wxALIGN_CENTRE;
  554.             break;
  555.  
  556.         case wxALIGN_CENTRE:
  557.             vert = wxALIGN_BOTTOM;
  558.             break;
  559.  
  560.         case wxALIGN_BOTTOM:
  561.             vert = wxALIGN_TOP;
  562.             break;
  563.     }
  564.  
  565.     grid->SetRowLabelAlignment( -1, vert );
  566. }
  567.  
  568.  
  569. void GridFrame::SetColLabelHorizAlignment( wxCommandEvent& WXUNUSED(ev) )
  570. {
  571.     int horiz, vert;
  572.     grid->GetColLabelAlignment( &horiz, &vert );
  573.  
  574.     switch ( horiz )
  575.     {
  576.         case wxALIGN_LEFT:
  577.             horiz = wxALIGN_CENTRE;
  578.             break;
  579.  
  580.         case wxALIGN_CENTRE:
  581.             horiz = wxALIGN_RIGHT;
  582.             break;
  583.  
  584.         case wxALIGN_RIGHT:
  585.             horiz = wxALIGN_LEFT;
  586.             break;
  587.     }
  588.  
  589.     grid->SetColLabelAlignment( horiz, -1 );
  590. }
  591.  
  592.  
  593. void GridFrame::SetColLabelVertAlignment( wxCommandEvent& WXUNUSED(ev) )
  594. {
  595.     int horiz, vert;
  596.     grid->GetColLabelAlignment( &horiz, &vert );
  597.  
  598.     switch ( vert )
  599.     {
  600.         case wxALIGN_TOP:
  601.             vert = wxALIGN_CENTRE;
  602.             break;
  603.  
  604.         case wxALIGN_CENTRE:
  605.             vert = wxALIGN_BOTTOM;
  606.             break;
  607.  
  608.         case wxALIGN_BOTTOM:
  609.             vert = wxALIGN_TOP;
  610.             break;
  611.     }
  612.  
  613.     grid->SetColLabelAlignment( -1, vert );
  614. }
  615.  
  616.  
  617. void GridFrame::SetGridLineColour( wxCommandEvent& WXUNUSED(ev) )
  618. {
  619.     wxColourDialog dlg( NULL );
  620.     if ( dlg.ShowModal() == wxID_OK )
  621.     {
  622.         wxColourData retData;
  623.         retData = dlg.GetColourData();
  624.         wxColour colour = retData.GetColour();
  625.  
  626.         grid->SetGridLineColour( colour );
  627.     }
  628. }
  629.  
  630.  
  631. void GridFrame::InsertRow( wxCommandEvent& WXUNUSED(ev) )
  632. {
  633.     grid->InsertRows( grid->GetGridCursorRow(), 1 );
  634. }
  635.  
  636.  
  637. void GridFrame::InsertCol( wxCommandEvent& WXUNUSED(ev) )
  638. {
  639.     grid->InsertCols( grid->GetGridCursorCol(), 1 );
  640. }
  641.  
  642.  
  643. void GridFrame::DeleteSelectedRows( wxCommandEvent& WXUNUSED(ev) )
  644. {
  645.     if ( grid->IsSelection() )
  646.     {
  647.         grid->BeginBatch();
  648.         for ( int n = 0; n < grid->GetNumberRows(); )
  649.             if ( grid->IsInSelection( n , 0 ) )
  650.                 grid->DeleteRows( n, 1 );
  651.         else
  652.             n++;
  653.         grid->EndBatch();
  654.     }
  655. }
  656.  
  657.  
  658. void GridFrame::DeleteSelectedCols( wxCommandEvent& WXUNUSED(ev) )
  659. {
  660.     if ( grid->IsSelection() )
  661.     {
  662.         grid->BeginBatch();
  663.         for ( int n = 0; n < grid->GetNumberCols(); )
  664.             if ( grid->IsInSelection( 0 , n ) )
  665.                 grid->DeleteCols( n, 1 );
  666.         else
  667.             n++;
  668.         grid->EndBatch();
  669.     }
  670. }
  671.  
  672.  
  673. void GridFrame::ClearGrid( wxCommandEvent& WXUNUSED(ev) )
  674. {
  675.     grid->ClearGrid();
  676. }
  677.  
  678. void GridFrame::SelectCells( wxCommandEvent& WXUNUSED(ev) )
  679. {
  680.     grid->SetSelectionMode( wxGrid::wxGridSelectCells );
  681. }
  682.  
  683. void GridFrame::SelectRows( wxCommandEvent& WXUNUSED(ev) )
  684. {
  685.     grid->SetSelectionMode( wxGrid::wxGridSelectRows );
  686. }
  687.  
  688. void GridFrame::SelectCols( wxCommandEvent& WXUNUSED(ev) )
  689. {
  690.     grid->SetSelectionMode( wxGrid::wxGridSelectColumns );
  691. }
  692.  
  693. void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) )
  694. {
  695.     wxColour col = wxGetColourFromUser(this);
  696.     if ( col.Ok() )
  697.     {
  698.         grid->SetDefaultCellTextColour(col);
  699.         grid->Refresh();
  700.     }
  701. }
  702.  
  703. void GridFrame::SetCellBgColour( wxCommandEvent& WXUNUSED(ev) )
  704. {
  705.     wxColour col = wxGetColourFromUser(this);
  706.     if ( col.Ok() )
  707.     {
  708.         // Check the new Refresh function by passing it a rectangle
  709.         // which exactly fits the grid.
  710.         wxRect r(wxPoint(0, 0), grid->GetSize());
  711.         grid->SetDefaultCellBackgroundColour(col);
  712.         grid->Refresh(TRUE, &r);
  713.     }
  714. }
  715.  
  716. void GridFrame::DeselectCell(wxCommandEvent& WXUNUSED(event))
  717. {
  718.       grid->DeselectCell(3, 1);
  719. }
  720.  
  721. void GridFrame::DeselectCol(wxCommandEvent& WXUNUSED(event))
  722. {
  723.       grid->DeselectCol(2);
  724. }
  725.  
  726. void GridFrame::DeselectRow(wxCommandEvent& WXUNUSED(event))
  727. {
  728.       grid->DeselectRow(2);
  729. }
  730.  
  731. void GridFrame::DeselectAll(wxCommandEvent& WXUNUSED(event))
  732. {
  733.       grid->ClearSelection();
  734. }
  735.  
  736. void GridFrame::SelectCell(wxCommandEvent& WXUNUSED(event))
  737. {
  738.       grid->SelectBlock(3, 1, 3, 1, m_addToSel);
  739. }
  740.  
  741. void GridFrame::SelectCol(wxCommandEvent& WXUNUSED(event))
  742. {
  743.       grid->SelectCol(2, m_addToSel);
  744. }
  745.  
  746. void GridFrame::SelectRow(wxCommandEvent& WXUNUSED(event))
  747. {
  748.       grid->SelectRow(2, m_addToSel);
  749. }
  750.  
  751. void GridFrame::SelectAll(wxCommandEvent& WXUNUSED(event))
  752. {
  753.       grid->SelectAll();
  754. }
  755.  
  756. void GridFrame::OnAddToSelectToggle(wxCommandEvent& event)
  757. {
  758.     m_addToSel = event.IsChecked();
  759. }
  760.  
  761. void GridFrame::OnLabelLeftClick( wxGridEvent& ev )
  762. {
  763.     logBuf = _T("");
  764.     if ( ev.GetRow() != -1 )
  765.     {
  766.         logBuf << _T("Left click on row label ") << ev.GetRow();
  767.     }
  768.     else if ( ev.GetCol() != -1 )
  769.     {
  770.         logBuf << _T("Left click on col label ") << ev.GetCol();
  771.     }
  772.     else
  773.     {
  774.         logBuf << _T("Left click on corner label");
  775.     }
  776.  
  777.     if ( ev.ShiftDown() ) logBuf << _T(" (shift down)");
  778.     if ( ev.ControlDown() ) logBuf << _T(" (control down)");
  779.     wxLogMessage( wxT("%s"), logBuf.c_str() );
  780.  
  781.     // you must call event skip if you want default grid processing
  782.     //
  783.     ev.Skip();
  784. }
  785.  
  786.  
  787. void GridFrame::OnCellLeftClick( wxGridEvent& ev )
  788. {
  789.     logBuf = _T("");
  790.     logBuf << _T("Left click at row ") << ev.GetRow()
  791.            << _T(" col ") << ev.GetCol();
  792.     wxLogMessage( wxT("%s"), logBuf.c_str() );
  793.  
  794.     // you must call event skip if you want default grid processing
  795.     // (cell highlighting etc.)
  796.     //
  797.     ev.Skip();
  798. }
  799.  
  800.  
  801. void GridFrame::OnRowSize( wxGridSizeEvent& ev )
  802. {
  803.     logBuf = _T("");
  804.     logBuf << _T("Resized row ") << ev.GetRowOrCol();
  805.     wxLogMessage( wxT("%s"), logBuf.c_str() );
  806.  
  807.     ev.Skip();
  808. }
  809.  
  810.  
  811. void GridFrame::OnColSize( wxGridSizeEvent& ev )
  812. {
  813.     logBuf = _T("");
  814.     logBuf << _T("Resized col ") << ev.GetRowOrCol();
  815.     wxLogMessage( wxT("%s"), logBuf.c_str() );
  816.  
  817.     ev.Skip();
  818. }
  819.  
  820.  
  821. void GridFrame::OnSelectCell( wxGridEvent& ev )
  822. {
  823.     logBuf = _T("");
  824.     if ( ev.Selecting() )
  825.         logBuf << _T("Selected ");
  826.     else
  827.         logBuf << _T("Deselected ");
  828.     logBuf << _T("cell at row ") << ev.GetRow()
  829.            << _T(" col ") << ev.GetCol()
  830.            << _T(" ( ControlDown: ")<< (ev.ControlDown() ? 'T':'F')
  831.            << _T(", ShiftDown: ")<< (ev.ShiftDown() ? 'T':'F')
  832.            << _T(", AltDown: ")<< (ev.AltDown() ? 'T':'F')
  833.            << _T(", MetaDown: ")<< (ev.MetaDown() ? 'T':'F') << _T(" )");
  834.     wxLogMessage( wxT("%s"), logBuf.c_str() );
  835.  
  836.     // you must call Skip() if you want the default processing
  837.     // to occur in wxGrid
  838.     ev.Skip();
  839. }
  840.  
  841. void GridFrame::OnRangeSelected( wxGridRangeSelectEvent& ev )
  842. {
  843.     logBuf = _T("");
  844.     if ( ev.Selecting() )
  845.         logBuf << _T("Selected ");
  846.     else
  847.         logBuf << _T("Deselected ");
  848.     logBuf << _T("cells from row ") << ev.GetTopRow()
  849.            << _T(" col ") << ev.GetLeftCol()
  850.            << _T(" to row ") << ev.GetBottomRow()
  851.            << _T(" col ") << ev.GetRightCol()
  852.            << _T(" ( ControlDown: ")<< (ev.ControlDown() ? 'T':'F')
  853.            << _T(", ShiftDown: ")<< (ev.ShiftDown() ? 'T':'F')
  854.            << _T(", AltDown: ")<< (ev.AltDown() ? 'T':'F')
  855.            << _T(", MetaDown: ")<< (ev.MetaDown() ? 'T':'F') << _T(" )");
  856.     wxLogMessage( wxT("%s"), logBuf.c_str() );
  857.  
  858.     ev.Skip();
  859. }
  860.  
  861. void GridFrame::OnCellValueChanged( wxGridEvent& ev )
  862. {
  863.     logBuf = _T("");
  864.     logBuf  << _T("Value changed for cell at")
  865.             << _T(" row ") << ev.GetRow()
  866.             << _T(" col ") << ev.GetCol();
  867.  
  868.     wxLogMessage( wxT("%s"), logBuf.c_str() );
  869.  
  870.     ev.Skip();
  871. }
  872.  
  873. void GridFrame::OnEditorShown( wxGridEvent& ev )
  874. {
  875.  
  876.     if ( (ev.GetCol() == 4) &&
  877.          (ev.GetRow() == 0) &&
  878.      (wxMessageBox(_T("Are you sure you wish to edit this cell"),
  879.                    _T("Checking"),wxYES_NO) == wxNO ) ) {
  880.  
  881.      ev.Veto();
  882.      return;
  883.     }
  884.  
  885.     wxLogMessage( wxT("Cell editor shown.") );
  886.  
  887.     ev.Skip();
  888. }
  889.  
  890. void GridFrame::OnEditorHidden( wxGridEvent& ev )
  891. {
  892.  
  893.     if ( (ev.GetCol() == 4) &&
  894.          (ev.GetRow() == 0) &&
  895.      (wxMessageBox(_T("Are you sure you wish to finish editing this cell"),
  896.                    _T("Checking"),wxYES_NO) == wxNO ) ) {
  897.  
  898.         ev.Veto();
  899.         return;
  900.     }
  901.  
  902.     wxLogMessage( wxT("Cell editor hidden.") );
  903.  
  904.     ev.Skip();
  905. }
  906.  
  907. void GridFrame::About(  wxCommandEvent& WXUNUSED(ev) )
  908. {
  909.     (void)wxMessageBox( _T("\n\nwxGrid demo \n\n")
  910.                         _T("Michael Bedward \n")
  911.                         _T("mbedward@ozemail.com.au \n\n"),
  912.                         _T("About"),
  913.                         wxOK );
  914. }
  915.  
  916.  
  917. void GridFrame::OnQuit( wxCommandEvent& WXUNUSED(ev) )
  918. {
  919.     Close( TRUE );
  920. }
  921.  
  922. void GridFrame::OnBugsTable(wxCommandEvent& )
  923. {
  924.     BugsGridFrame *frame = new BugsGridFrame;
  925.     frame->Show(TRUE);
  926. }
  927.  
  928. void GridFrame::OnSmallGrid(wxCommandEvent& )
  929. {
  930.     wxFrame* frame = new wxFrame(NULL, -1, _T("A Small Grid"),
  931.                                  wxDefaultPosition, wxSize(640, 480));
  932.     wxPanel* panel = new wxPanel(frame, -1);
  933.     wxGrid* grid = new wxGrid(panel, -1, wxPoint(10,10), wxSize(400,400),
  934.                               wxWANTS_CHARS | wxSIMPLE_BORDER);
  935.     grid->CreateGrid(3,3);
  936.     frame->Show(TRUE);
  937. }
  938.  
  939. void GridFrame::OnVTable(wxCommandEvent& )
  940. {
  941.     static long s_sizeGrid = 10000;
  942.  
  943. #ifdef __WXMOTIF__
  944.     // MB: wxGetNumberFromUser doesn't work properly for wxMotif
  945.     wxString s;
  946.     s << s_sizeGrid;
  947.     s = wxGetTextFromUser( _T("Size of the table to create"),
  948.                            _T("Size:"),
  949.                            s );
  950.  
  951.     s.ToLong( &s_sizeGrid );
  952.  
  953. #else
  954.     s_sizeGrid = wxGetNumberFromUser(_T("Size of the table to create"),
  955.                                      _T("Size: "),
  956.                                      _T("wxGridDemo question"),
  957.                                      s_sizeGrid,
  958.                                      0, 32000, this);
  959. #endif
  960.  
  961.     if ( s_sizeGrid != -1 )
  962.     {
  963.         BigGridFrame* win = new BigGridFrame(s_sizeGrid);
  964.         win->Show(TRUE);
  965.     }
  966. }
  967.  
  968. // ----------------------------------------------------------------------------
  969. // MyGridCellRenderer
  970. // ----------------------------------------------------------------------------
  971.  
  972. // do something that the default renderer doesn't here just to show that it is
  973. // possible to alter the appearance of the cell beyond what the attributes
  974. // allow
  975. void MyGridCellRenderer::Draw(wxGrid& grid,
  976.                               wxGridCellAttr& attr,
  977.                               wxDC& dc,
  978.                               const wxRect& rect,
  979.                               int row, int col,
  980.                               bool isSelected)
  981. {
  982.     wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
  983.  
  984.     dc.SetPen(*wxGREEN_PEN);
  985.     dc.SetBrush(*wxTRANSPARENT_BRUSH);
  986.     dc.DrawEllipse(rect);
  987. }
  988.  
  989. // ----------------------------------------------------------------------------
  990. // MyGridCellAttrProvider
  991. // ----------------------------------------------------------------------------
  992.  
  993. MyGridCellAttrProvider::MyGridCellAttrProvider()
  994. {
  995.     m_attrForOddRows = new wxGridCellAttr;
  996.     m_attrForOddRows->SetBackgroundColour(*wxLIGHT_GREY);
  997. }
  998.  
  999. MyGridCellAttrProvider::~MyGridCellAttrProvider()
  1000. {
  1001.     m_attrForOddRows->DecRef();
  1002. }
  1003.  
  1004. wxGridCellAttr *MyGridCellAttrProvider::GetAttr(int row, int col,
  1005.                            wxGridCellAttr::wxAttrKind  kind /* = wxGridCellAttr::Any */) const
  1006. {
  1007.     wxGridCellAttr *attr = wxGridCellAttrProvider::GetAttr(row, col, kind);
  1008.  
  1009.     if ( row % 2 )
  1010.     {
  1011.         if ( !attr )
  1012.         {
  1013.             attr = m_attrForOddRows;
  1014.             attr->IncRef();
  1015.         }
  1016.         else
  1017.         {
  1018.             if ( !attr->HasBackgroundColour() )
  1019.             {
  1020.                 wxGridCellAttr *attrNew = attr->Clone();
  1021.                 attr->DecRef();
  1022.                 attr = attrNew;
  1023.                 attr->SetBackgroundColour(*wxLIGHT_GREY);
  1024.             }
  1025.         }
  1026.     }
  1027.  
  1028.     return attr;
  1029. }
  1030.  
  1031. // ============================================================================
  1032. // BigGridFrame and BigGridTable:  Sample of a non-standard table
  1033. // ============================================================================
  1034.  
  1035. BigGridFrame::BigGridFrame(long sizeGrid)
  1036.             : wxFrame(NULL, -1, _T("Plugin Virtual Table"),
  1037.                       wxDefaultPosition, wxSize(500, 450))
  1038. {
  1039.     m_grid = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize);
  1040.     m_table = new BigGridTable(sizeGrid);
  1041.  
  1042.     // VZ: I don't understand why this slows down the display that much,
  1043.     //     must profile it...
  1044.     //m_table->SetAttrProvider(new MyGridCellAttrProvider);
  1045.  
  1046.     m_grid->SetTable(m_table, TRUE);
  1047.  
  1048. #if defined __WXMOTIF__
  1049.     // MB: the grid isn't getting a sensible default size under wxMotif
  1050.     int cw, ch;
  1051.     GetClientSize( &cw, &ch );
  1052.     m_grid->SetSize( cw, ch );
  1053. #endif
  1054. }
  1055.  
  1056. // ============================================================================
  1057. // BugsGridFrame: a "realistic" table
  1058. // ============================================================================
  1059.  
  1060. // ----------------------------------------------------------------------------
  1061. // bugs table data
  1062. // ----------------------------------------------------------------------------
  1063.  
  1064. enum Columns
  1065. {
  1066.     Col_Id,
  1067.     Col_Summary,
  1068.     Col_Severity,
  1069.     Col_Priority,
  1070.     Col_Platform,
  1071.     Col_Opened,
  1072.     Col_Max
  1073. };
  1074.  
  1075. enum Severity
  1076. {
  1077.     Sev_Wish,
  1078.     Sev_Minor,
  1079.     Sev_Normal,
  1080.     Sev_Major,
  1081.     Sev_Critical,
  1082.     Sev_Max
  1083. };
  1084.  
  1085. static const wxString severities[] =
  1086. {
  1087.     _T("wishlist"),
  1088.     _T("minor"),
  1089.     _T("normal"),
  1090.     _T("major"),
  1091.     _T("critical"),
  1092. };
  1093.  
  1094. static struct BugsGridData
  1095. {
  1096.     int id;
  1097.     wxChar summary[80];
  1098.     Severity severity;
  1099.     int prio;
  1100.     wxChar platform[12];
  1101.     bool opened;
  1102. } gs_dataBugsGrid [] =
  1103. {
  1104.     { 18, _T("foo doesn't work"), Sev_Major, 1, _T("wxMSW"), TRUE },
  1105.     { 27, _T("bar crashes"), Sev_Critical, 1, _T("all"), FALSE },
  1106.     { 45, _T("printing is slow"), Sev_Minor, 3, _T("wxMSW"), TRUE },
  1107.     { 68, _T("Rectangle() fails"), Sev_Normal, 1, _T("wxMSW"), FALSE },
  1108. };
  1109.  
  1110. static const wxChar *headers[Col_Max] =
  1111. {
  1112.     _T("Id"),
  1113.     _T("Summary"),
  1114.     _T("Severity"),
  1115.     _T("Priority"),
  1116.     _T("Platform"),
  1117.     _T("Opened?"),
  1118. };
  1119.  
  1120. // ----------------------------------------------------------------------------
  1121. // BugsGridTable
  1122. // ----------------------------------------------------------------------------
  1123.  
  1124. wxString BugsGridTable::GetTypeName(int WXUNUSED(row), int col)
  1125. {
  1126.     switch ( col )
  1127.     {
  1128.         case Col_Id:
  1129.         case Col_Priority:
  1130.             return wxGRID_VALUE_NUMBER;;
  1131.  
  1132.         case Col_Severity:
  1133.             // fall thorugh (TODO should be a list)
  1134.  
  1135.         case Col_Summary:
  1136.             return wxString::Format(_T("%s:80"), wxGRID_VALUE_STRING);
  1137.  
  1138.         case Col_Platform:
  1139.             return wxString::Format(_T("%s:all,MSW,GTK,other"), wxGRID_VALUE_CHOICE);
  1140.  
  1141.         case Col_Opened:
  1142.             return wxGRID_VALUE_BOOL;
  1143.     }
  1144.  
  1145.     wxFAIL_MSG(_T("unknown column"));
  1146.  
  1147.     return wxEmptyString;
  1148. }
  1149.  
  1150. int BugsGridTable::GetNumberRows()
  1151. {
  1152.     return WXSIZEOF(gs_dataBugsGrid);
  1153. }
  1154.  
  1155. int BugsGridTable::GetNumberCols()
  1156. {
  1157.     return Col_Max;
  1158. }
  1159.  
  1160. bool BugsGridTable::IsEmptyCell( int row, int col )
  1161. {
  1162.     return FALSE;
  1163. }
  1164.  
  1165. wxString BugsGridTable::GetValue( int row, int col )
  1166. {
  1167.     const BugsGridData& gd = gs_dataBugsGrid[row];
  1168.  
  1169.     switch ( col )
  1170.     {
  1171.         case Col_Id:
  1172.         case Col_Priority:
  1173.         case Col_Opened:
  1174.             wxFAIL_MSG(_T("unexpected column"));
  1175.             break;
  1176.  
  1177.         case Col_Severity:
  1178.             return severities[gd.severity];
  1179.  
  1180.         case Col_Summary:
  1181.             return gd.summary;
  1182.  
  1183.         case Col_Platform:
  1184.             return gd.platform;
  1185.     }
  1186.  
  1187.     return wxEmptyString;
  1188. }
  1189.  
  1190. void BugsGridTable::SetValue( int row, int col, const wxString& value )
  1191. {
  1192.     BugsGridData& gd = gs_dataBugsGrid[row];
  1193.  
  1194.     switch ( col )
  1195.     {
  1196.         case Col_Id:
  1197.         case Col_Priority:
  1198.         case Col_Opened:
  1199.             wxFAIL_MSG(_T("unexpected column"));
  1200.             break;
  1201.  
  1202.         case Col_Severity:
  1203.             {
  1204.                 size_t n;
  1205.                 for ( n = 0; n < WXSIZEOF(severities); n++ )
  1206.                 {
  1207.                     if ( severities[n] == value )
  1208.                     {
  1209.                         gd.severity = (Severity)n;
  1210.                         break;
  1211.                     }
  1212.                 }
  1213.  
  1214.                 if ( n == WXSIZEOF(severities) )
  1215.                 {
  1216.                     wxLogWarning(_T("Invalid severity value '%s'."),
  1217.                                  value.c_str());
  1218.                     gd.severity = Sev_Normal;
  1219.                 }
  1220.             }
  1221.             break;
  1222.  
  1223.         case Col_Summary:
  1224.             wxStrncpy(gd.summary, value, WXSIZEOF(gd.summary));
  1225.             break;
  1226.  
  1227.         case Col_Platform:
  1228.             wxStrncpy(gd.platform, value, WXSIZEOF(gd.platform));
  1229.             break;
  1230.     }
  1231. }
  1232.  
  1233. bool BugsGridTable::CanGetValueAs( int WXUNUSED(row), int col, const wxString& typeName )
  1234. {
  1235.     if ( typeName == wxGRID_VALUE_STRING )
  1236.     {
  1237.         return TRUE;
  1238.     }
  1239.     else if ( typeName == wxGRID_VALUE_BOOL )
  1240.     {
  1241.         return col == Col_Opened;
  1242.     }
  1243.     else if ( typeName == wxGRID_VALUE_NUMBER )
  1244.     {
  1245.         return col == Col_Id || col == Col_Priority || col == Col_Severity;
  1246.     }
  1247.     else
  1248.     {
  1249.         return FALSE;
  1250.     }
  1251. }
  1252.  
  1253. bool BugsGridTable::CanSetValueAs( int row, int col, const wxString& typeName )
  1254. {
  1255.     return CanGetValueAs(row, col, typeName);
  1256. }
  1257.  
  1258. long BugsGridTable::GetValueAsLong( int row, int col )
  1259. {
  1260.     const BugsGridData& gd = gs_dataBugsGrid[row];
  1261.  
  1262.     switch ( col )
  1263.     {
  1264.         case Col_Id:
  1265.             return gd.id;
  1266.  
  1267.         case Col_Priority:
  1268.             return gd.prio;
  1269.  
  1270.         case Col_Severity:
  1271.             return gd.severity;
  1272.  
  1273.         default:
  1274.             wxFAIL_MSG(_T("unexpected column"));
  1275.             return -1;
  1276.     }
  1277. }
  1278.  
  1279. bool BugsGridTable::GetValueAsBool( int row, int col )
  1280. {
  1281.     if ( col == Col_Opened )
  1282.     {
  1283.         return gs_dataBugsGrid[row].opened;
  1284.     }
  1285.     else
  1286.     {
  1287.         wxFAIL_MSG(_T("unexpected column"));
  1288.  
  1289.         return FALSE;
  1290.     }
  1291. }
  1292.  
  1293. void BugsGridTable::SetValueAsLong( int row, int col, long value )
  1294. {
  1295.     BugsGridData& gd = gs_dataBugsGrid[row];
  1296.  
  1297.     switch ( col )
  1298.     {
  1299.         case Col_Priority:
  1300.             gd.prio = value;
  1301.             break;
  1302.  
  1303.         default:
  1304.             wxFAIL_MSG(_T("unexpected column"));
  1305.     }
  1306. }
  1307.  
  1308. void BugsGridTable::SetValueAsBool( int row, int col, bool value )
  1309. {
  1310.     if ( col == Col_Opened )
  1311.     {
  1312.         gs_dataBugsGrid[row].opened = value;
  1313.     }
  1314.     else
  1315.     {
  1316.         wxFAIL_MSG(_T("unexpected column"));
  1317.     }
  1318. }
  1319.  
  1320. wxString BugsGridTable::GetColLabelValue( int col )
  1321. {
  1322.     return headers[col];
  1323. }
  1324.  
  1325. BugsGridTable::BugsGridTable()
  1326. {
  1327. }
  1328.  
  1329. // ----------------------------------------------------------------------------
  1330. // BugsGridFrame
  1331. // ----------------------------------------------------------------------------
  1332.  
  1333. BugsGridFrame::BugsGridFrame()
  1334.              : wxFrame(NULL, -1, _T("Bugs table"),
  1335.                        wxDefaultPosition, wxSize(500, 300))
  1336. {
  1337.     wxGrid *grid = new wxGrid(this, -1, wxDefaultPosition);
  1338.     wxGridTableBase *table = new BugsGridTable();
  1339.     table->SetAttrProvider(new MyGridCellAttrProvider);
  1340.     grid->SetTable(table, TRUE);
  1341.  
  1342.     wxGridCellAttr *attrRO = new wxGridCellAttr,
  1343.                    *attrRangeEditor = new wxGridCellAttr,
  1344.                    *attrCombo = new wxGridCellAttr;
  1345.  
  1346.     attrRO->SetReadOnly();
  1347.     attrRangeEditor->SetEditor(new wxGridCellNumberEditor(1, 5));
  1348.     attrCombo->SetEditor(new wxGridCellChoiceEditor(WXSIZEOF(severities),
  1349.                                                     severities));
  1350.  
  1351.     grid->SetColAttr(Col_Id, attrRO);
  1352.     grid->SetColAttr(Col_Priority, attrRangeEditor);
  1353.     grid->SetColAttr(Col_Severity, attrCombo);
  1354.  
  1355.     grid->SetMargins(0, 0);
  1356.  
  1357.     grid->Fit();
  1358.     SetClientSize(grid->GetSize());
  1359. }
  1360.  
  1361.  
  1362.