home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / generic / gridctrl.cpp < prev    next >
C/C++ Source or Header  |  2002-09-06  |  12KB  |  401 lines

  1. ///////////////////////////////////////////////////////////////////////////
  2. // Name:        generic/gridctrl.cpp
  3. // Purpose:     wxGrid controls
  4. // Author:      Paul Gammans, Roger Gammans
  5. // Modified by:
  6. // Created:     11/04/2001
  7. // RCS-ID:      $Id: gridctrl.cpp,v 1.9 2002/09/06 14:42:47 JS Exp $
  8. // Copyright:   (c) The Computer Surgery (paul@compsurg.co.uk)
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13.     #pragma implementation "gridctrl.h"
  14. #endif
  15.  
  16. #include "wx/wxprec.h"
  17.  
  18. #ifdef __BORLANDC__
  19.     #pragma hdrstop
  20. #endif
  21.  
  22. #if wxUSE_GRID || wxUSE_NEW_GRID
  23.  
  24. #ifndef WX_PRECOMP
  25.     #include "wx/textctrl.h"
  26.     #include "wx/dc.h"
  27. #endif // WX_PRECOMP
  28.  
  29. #include "wx/generic/gridctrl.h"
  30. #include "wx/tokenzr.h"
  31.  
  32. // ----------------------------------------------------------------------------
  33. // wxGridCellDateTimeRenderer
  34. // ----------------------------------------------------------------------------
  35.  
  36. // Enables a grid cell to display a formated date and or time
  37.  
  38. wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(wxString outformat, wxString informat)
  39. {
  40.     m_iformat = informat;
  41.     m_oformat = outformat;
  42.     m_tz = wxDateTime::Local;
  43.     m_dateDef = wxDefaultDateTime;
  44. }
  45.  
  46. wxGridCellRenderer *wxGridCellDateTimeRenderer::Clone() const
  47. {
  48.     wxGridCellDateTimeRenderer *renderer = new wxGridCellDateTimeRenderer;
  49.     renderer->m_iformat = m_iformat;
  50.     renderer->m_oformat = m_oformat;
  51.     renderer->m_dateDef = m_dateDef;
  52.     renderer->m_tz = m_tz;
  53.  
  54.     return renderer;
  55. }
  56.  
  57. wxString wxGridCellDateTimeRenderer::GetString(wxGrid& grid, int row, int col)
  58. {
  59.     wxGridTableBase *table = grid.GetTable();
  60.  
  61.     bool hasDatetime = FALSE;
  62.     wxDateTime val;
  63.     wxString text;
  64.     if ( table->CanGetValueAs(row, col, wxGRID_VALUE_DATETIME) )
  65.     {
  66.         void * tempval = table->GetValueAsCustom(row, col,wxGRID_VALUE_DATETIME);
  67.  
  68.         if (tempval){
  69.             val = *((wxDateTime *)tempval);
  70.             hasDatetime = TRUE;
  71.             delete (wxDateTime *)tempval;
  72.         }
  73.  
  74.     }
  75.  
  76.     if (!hasDatetime )
  77.     {
  78.         text = table->GetValue(row, col);
  79.         hasDatetime = (val.ParseFormat( text, m_iformat, m_dateDef ) != (wxChar *)NULL) ;
  80.     }
  81.  
  82.     if ( hasDatetime )
  83.         text = val.Format(m_oformat, m_tz );
  84.  
  85.     //If we faild to parse string just show what we where given?
  86.     return text;
  87. }
  88.  
  89. void wxGridCellDateTimeRenderer::Draw(wxGrid& grid,
  90.                                    wxGridCellAttr& attr,
  91.                                    wxDC& dc,
  92.                                    const wxRect& rectCell,
  93.                                    int row, int col,
  94.                                    bool isSelected)
  95. {
  96.     wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
  97.  
  98.     SetTextColoursAndFont(grid, attr, dc, isSelected);
  99.  
  100.     // draw the text right aligned by default
  101.     int hAlign, vAlign;
  102.     attr.GetAlignment(&hAlign, &vAlign);
  103.     hAlign = wxRIGHT;
  104.  
  105.     wxRect rect = rectCell;
  106.     rect.Inflate(-1);
  107.  
  108.     grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
  109. }
  110.  
  111. wxSize wxGridCellDateTimeRenderer::GetBestSize(wxGrid& grid,
  112.                                             wxGridCellAttr& attr,
  113.                                             wxDC& dc,
  114.                                             int row, int col)
  115. {
  116.     return DoGetBestSize(attr, dc, GetString(grid, row, col));
  117. }
  118.  
  119. void wxGridCellDateTimeRenderer::SetParameters(const wxString& params){
  120.     if (!params.IsEmpty())
  121.         m_oformat=params;
  122. }
  123.  
  124. // ----------------------------------------------------------------------------
  125. // wxGridCellChoiceNumberRenderer
  126. // ----------------------------------------------------------------------------
  127. // Renders a number as a textual equivalent.
  128. // eg data in cell is 0,1,2 ... n the cell could be rendered as "John","Fred"..."Bob"
  129.  
  130.  
  131. wxGridCellEnumRenderer::wxGridCellEnumRenderer(const wxString& choices)
  132. {
  133.     if (!choices.IsEmpty())
  134.         SetParameters(choices);
  135. }
  136.  
  137. wxGridCellRenderer *wxGridCellEnumRenderer::Clone() const
  138. {
  139.     wxGridCellEnumRenderer *renderer = new wxGridCellEnumRenderer;
  140.     renderer->m_choices = m_choices;
  141.     return renderer;
  142. }
  143.  
  144. wxString wxGridCellEnumRenderer::GetString(wxGrid& grid, int row, int col)
  145. {
  146.     wxGridTableBase *table = grid.GetTable();
  147.     wxString text;
  148.     if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
  149.     {
  150.         int choiceno = table->GetValueAsLong(row, col);
  151.         text.Printf(_T("%s"), m_choices[ choiceno ].c_str() );
  152.     }
  153.     else
  154.     {
  155.         text = table->GetValue(row, col);
  156.     }
  157.  
  158.  
  159.     //If we faild to parse string just show what we where given?
  160.     return text;
  161. }
  162.  
  163. void wxGridCellEnumRenderer::Draw(wxGrid& grid,
  164.                                    wxGridCellAttr& attr,
  165.                                    wxDC& dc,
  166.                                    const wxRect& rectCell,
  167.                                    int row, int col,
  168.                                    bool isSelected)
  169. {
  170.     wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
  171.  
  172.     SetTextColoursAndFont(grid, attr, dc, isSelected);
  173.  
  174.     // draw the text right aligned by default
  175.     int hAlign, vAlign;
  176.     attr.GetAlignment(&hAlign, &vAlign);
  177.     hAlign = wxRIGHT;
  178.  
  179.     wxRect rect = rectCell;
  180.     rect.Inflate(-1);
  181.  
  182.     grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
  183. }
  184.  
  185. wxSize wxGridCellEnumRenderer::GetBestSize(wxGrid& grid,
  186.                                             wxGridCellAttr& attr,
  187.                                             wxDC& dc,
  188.                                             int row, int col)
  189. {
  190.     return DoGetBestSize(attr, dc, GetString(grid, row, col));
  191. }
  192.  
  193. void wxGridCellEnumRenderer::SetParameters(const wxString& params)
  194. {
  195.     if ( !params )
  196.     {
  197.         // what can we do?
  198.         return;
  199.     }
  200.  
  201.     m_choices.Empty();
  202.  
  203.     wxStringTokenizer tk(params, _T(','));
  204.     while ( tk.HasMoreTokens() )
  205.     {
  206.         m_choices.Add(tk.GetNextToken());
  207.     }
  208. }
  209.  
  210. #if wxUSE_COMBOBOX
  211.  
  212. // ----------------------------------------------------------------------------
  213. // wxGridCellEnumEditor
  214. // ----------------------------------------------------------------------------
  215.  
  216. // A cell editor which displays an enum number as a textual equivalent. eg
  217. // data in cell is 0,1,2 ... n the cell could be displayed as
  218. // "John","Fred"..."Bob" in the combo choice box
  219.  
  220. wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices)
  221.                     : wxGridCellChoiceEditor()
  222. {
  223.     m_startint = -1;
  224.  
  225.     if (!choices.IsEmpty())
  226.         SetParameters(choices);
  227. }
  228.  
  229. wxGridCellEditor *wxGridCellEnumEditor::Clone() const
  230. {
  231.     wxGridCellEnumEditor *editor = new wxGridCellEnumEditor();
  232.     editor->m_startint = m_startint;
  233.     return editor;
  234. }
  235.  
  236. void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid)
  237. {
  238.     wxASSERT_MSG(m_control,
  239.                  wxT("The wxGridCellEnumEditor must be Created first!"));
  240.  
  241.     wxGridTableBase *table = grid->GetTable();
  242.  
  243.     if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
  244.     {
  245.         m_startint = table->GetValueAsLong(row, col);
  246.     }
  247.     else
  248.     {
  249.         wxString startValue = table->GetValue(row, col);
  250.         if (startValue.IsNumber() && !startValue.IsEmpty())
  251.         {
  252.             startValue.ToLong(&m_startint);
  253.         }
  254.         else
  255.         {
  256.             m_startint=-1;
  257.         }
  258.     }
  259.  
  260.     Combo()->SetSelection(m_startint);
  261.     Combo()->SetInsertionPointEnd();
  262.     Combo()->SetFocus();
  263.  
  264. }
  265.  
  266. bool wxGridCellEnumEditor::EndEdit(int row, int col, wxGrid* grid)
  267. {
  268.     int pos = Combo()->GetSelection();
  269.     bool changed = (pos != m_startint);
  270.     if (changed)
  271.     {
  272.         if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER))
  273.             grid->GetTable()->SetValueAsLong(row, col, pos);
  274.         else
  275.             grid->GetTable()->SetValue(row, col,wxString::Format(wxT("%i"),pos));
  276.     }
  277.  
  278.     return changed;
  279. }
  280.  
  281. #endif // wxUSE_COMBOBOX
  282.  
  283. // ----------------------------------------------------------------------------
  284. // wxGridCellAutoWrapStringEditor
  285. // ----------------------------------------------------------------------------
  286.  
  287. void
  288. wxGridCellAutoWrapStringEditor::Create(wxWindow* parent,
  289.                                        wxWindowID id,
  290.                                        wxEvtHandler* evtHandler)
  291. {
  292.   m_control = new wxTextCtrl(parent, id, wxEmptyString,
  293.                              wxDefaultPosition, wxDefaultSize,
  294.                              wxTE_MULTILINE | wxTE_RICH);
  295.  
  296.  
  297.   wxGridCellEditor::Create(parent, id, evtHandler);
  298. }
  299.  
  300. void
  301. wxGridCellAutoWrapStringRenderer::Draw(wxGrid& grid,
  302.                       wxGridCellAttr& attr,
  303.                       wxDC& dc,
  304.                       const wxRect& rectCell,
  305.                       int row, int col,
  306.                       bool isSelected) {
  307.  
  308.  
  309.     wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
  310.  
  311.     // now we only have to draw the text
  312.     SetTextColoursAndFont(grid, attr, dc, isSelected);
  313.  
  314.     int horizAlign, vertAlign;
  315.     attr.GetAlignment(&horizAlign, &vertAlign);
  316.  
  317.     wxRect rect = rectCell;
  318.     rect.Inflate(-1);
  319.  
  320.     grid.DrawTextRectangle(dc, GetTextLines(grid,dc,attr,rect,row,col),
  321.                            rect, horizAlign, vertAlign);
  322. }
  323.  
  324.  
  325. wxArrayString
  326. wxGridCellAutoWrapStringRenderer::GetTextLines(wxGrid& grid,
  327.                                                wxDC& dc,
  328.                                                wxGridCellAttr& attr,
  329.                                                const wxRect& rect,
  330.                                                int row, int col)
  331. {
  332.     wxString  data = grid.GetCellValue(row, col);
  333.  
  334.     wxArrayString lines;
  335.     dc.SetFont(attr.GetFont());
  336.  
  337.     //Taken from wxGrid again!
  338.     wxCoord x = 0, y = 0, curr_x = 0;
  339.     wxCoord max_x = rect.GetWidth();
  340.  
  341.     dc.SetFont(attr.GetFont());
  342.     wxStringTokenizer tk(data , _T(" \n\t\r"));
  343.     wxString thisline(wxT(""));
  344.  
  345.     while ( tk.HasMoreTokens() )
  346.     {
  347.         wxString tok = tk.GetNextToken();
  348.     //FIXME: this causes us to print an extra unnecesary
  349.     //       space at the end of the line. But it
  350.     //       is invisible , simplifies the size calculation
  351.     //       and ensures tokens are seperated in the display
  352.     tok += _T(" ");
  353.  
  354.         dc.GetTextExtent(tok, &x, &y);
  355.         if ( curr_x + x > max_x) {
  356.             lines.Add( wxString(thisline) );
  357.         thisline = tok;
  358.         curr_x=x;
  359.     } else {
  360.             thisline+= tok;
  361.         curr_x += x;
  362.     }
  363.  
  364.     }
  365.     //Add last line
  366.     lines.Add( wxString(thisline) );
  367.  
  368.     return lines;
  369. }
  370.  
  371.  
  372. wxSize
  373. wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid& grid,
  374.                                               wxGridCellAttr& attr,
  375.                                               wxDC& dc,
  376.                                               int row, int col)
  377. {
  378.     wxCoord x,y, height , width = grid.GetColSize(col) -10;
  379.     int count = 250; //Limit iterations..
  380.  
  381.     wxRect rect(0,0,width,10);
  382.  
  383.     // M is a nice large character 'y' gives descender!.
  384.     dc.GetTextExtent(wxT("My"), &x, &y);
  385.  
  386.     do
  387.     {
  388.         width+=10;
  389.         rect.SetWidth(width);
  390.         height = y *( GetTextLines(grid,dc,attr,rect,row,col).GetCount());
  391.         count--;
  392.     // Search for a shape no taller than the golden ratio.
  393.     } while (count && (width  < (height*1.68)) );
  394.  
  395.  
  396.     return wxSize(width,height);
  397. }
  398.  
  399. #endif // wxUSE_GRID
  400.  
  401.