tableviewer.h

Go to the documentation of this file.
00001 #ifndef tableviewer_included_h_
00002 #define tableviewer_included_h_
00003 #include <cxxtls/viewer.h>
00004 
00005 namespace cxxtls
00006 {
00007 
00008 class TableViewer
00009 : public Viewer
00034 {
00035 public:
00036 
00037   TableViewer(ViewerManager*vm)
00038   :  Viewer(vm)
00039   ,  originRow_(0)         // ul corner row offset (zero based)
00040   ,  originCol_(0)         // ul corner col offset (zero based)
00041   ,  displayTitles_(false) // always display row and column titles.  See setDisplayTitles()
00042   ,  active_(false)        // not currently the active window
00043   ,  layoutDirty_(true)    // need to recompute layout
00044   ,  cursorRow_(-1)        // current cell row within layout_
00045   ,  cursorCol_(-1)        // current cell column within layout_
00046   ,  cursorDisplayed_(1)   // true if the current cursorRow_ and cursorCol_ are shown highlighted
00047   ,  displayOrigin_(0,0)   // for drawing during and after a paint (vp coords)
00048   ,  viewerManager_(vm)    // saved for the clear function
00049   ,  dataDirty_(0)         // field edits have not been saved
00050   ,  pageWidth_(0)         // world columns set painting process     (layout_ columns)
00051   ,  pageHeight_(0)        // world rows set by the painting process (layout_ rows)
00052   ,  mixed_case_(true)     // search parameter
00053   ,  is_regex_(false)      // search parameter
00054   ,  match_words_(false)   // search parameter
00055   ,  search_text_("")      // text to search for
00056   {
00057   }
00058 
00059   // WARNING:  Copies of this object are made, so don't leak memory!  Right now, now
00060   //           raw pointers that we own are kept in this class, if you add one make sure you 
00062 
00063   void triggerLayoutRecompute() { layoutDirty_ = true; }
00068   
00069   virtual ~TableViewer();
00070 
00071   virtual void repaintTitle(CursorWindow::viewport *vp);
00079 
00080   virtual void operator() ( CursorWindow::viewport *     vp,
00081                             int                          cmd
00082                           );
00084 
00085   virtual bool handle_event( CursorWindow::input_event const * e,
00086                              CursorWindow::viewport          * vp
00087                            );
00089 
00090   virtual std::string const &application_name() const; 
00091   virtual std::string description() const;             
00092   virtual void help();                                 
00093   virtual bool is_dirty() const;                       
00094 
00095   struct ColumnInfo
00096   {
00097      std::string title_;
00098      size_t      width_;       // size hint, not actual value.  See TableViewer::colWidths_
00099      bool        leftBorder_;
00100      bool        bold_;
00101      bool        editable_;    // not used in table viewer, but derived classes can use it
00102      bool        executable_;  // ditto
00103 
00104      ColumnInfo()
00105      : title_("")
00106      , width_(0)
00107      , leftBorder_(false)
00108      , bold_(false)
00109      , editable_(true)
00110      , executable_(true)
00111      {
00112      }
00113 
00114      ColumnInfo(std::string const &title, size_t width, bool leftBorder)
00115      : title_(title)
00116      , width_(width)
00117      , leftBorder_(leftBorder)
00118      , bold_(false)
00119      , editable_(true)
00120      , executable_(true)
00121      {
00122      }
00123 
00124      ColumnInfo(std::string const &title, size_t width, bool leftBorder, bool bold, bool edit, bool executable)
00125      : title_(title)
00126      , width_(width)
00127      , leftBorder_(leftBorder)
00128      , bold_(bold)
00129      , editable_(edit)
00130      , executable_(executable)
00131      {
00132      }
00133 
00134   };
00135 
00136   struct RowInfo
00137   {
00138      std::string title_;
00139      size_t      height_;    // size hint, not actual value
00140      bool        bottomBorder_;
00141      bool        bold_;
00142      bool        editable_;   // not used in table viewer, but derived classes can use it
00143      bool        executable_;
00144 
00145      RowInfo()
00146      : title_("")
00147      , height_(0)
00148      , bottomBorder_(false)
00149      , bold_(false)
00150      , editable_(true)
00151      , executable_(true)
00152      {
00153      }
00154 
00155      RowInfo(std::string const &title, size_t height, bool bottomBorder)
00156      : title_(title)
00157      , height_(height)
00158      , bottomBorder_(bottomBorder)
00159      , bold_(false)
00160      , editable_(true)
00161      , executable_(true)
00162      {
00163      }
00164 
00165      RowInfo(std::string const &title, size_t height, bool bottomBorder, bool bold, bool edit, bool executable)
00166      : title_(title)
00167      , height_(height)
00168      , bottomBorder_(bottomBorder)
00169      , bold_(bold)
00170      , editable_(edit)
00171      , executable_(executable)
00172      {
00173      }
00174 
00175      void setRowTitleNumber(size_t row); // Set title_ to be a numeric string
00176 
00177   };
00178 
00179   struct CellInfo
00180   {
00181      std::vector< std::string > text_;  // one vector element for each row (usually 1)
00182 
00183      size_t worldRow_;       // imaginary coordinate system (bigger than screen)
00184      size_t worldColumn_;    // ditto
00185 
00186      size_t widestRow() const;  // returns max of string lengths in text_
00187 
00188   };
00189 
00190 
00191   struct FieldAttributes
00192   {
00193      bool bold_;
00194      bool underlined_;
00195      bool editable_;
00196      bool executable_;
00197 
00198      FieldAttributes(bool b=false, bool u=false, bool e=false, bool x=false)
00199      : bold_(b)
00200      , underlined_(u)
00201      , editable_(e)
00202      , executable_(e)
00203      {
00204      }
00205 
00206      template<class Iterator>
00207      static FieldAttributes
00208      skip(Iterator &first, Iterator const &last)
00217 
00218      {
00219         FieldAttributes fa;
00220      
00221         if(first == last || *first != '[')
00222         {
00223           return fa;
00224         }
00225 
00226         ++first;
00227 
00228         while(first != last && *first != ']' )
00229         {
00230            char c = *first++;
00231 
00232            switch(c)
00233            {
00234               case '!':  fa.bold_         = true; break;
00235               case 'x':  fa.executable_   = true; break;
00236               case 'e':  fa.editable_     = true; break;
00237               case '_':  fa.underlined_   = true; break;
00238            }
00239         }
00240 
00241         if(first != last)
00242           ++first; // skip trailing ]
00243 
00244         return fa;
00245 
00246 
00247      }
00248 
00249 
00250   };
00251 
00252 
00253   size_t rows() const { return rows_.size(); } 
00254   size_t cols() const { return cols_.size(); } 
00255 
00256   size_t originRow() const { return originRow_; } 
00257   size_t originCol() const { return originCol_; } 
00258 
00259   void setDisplayTitles(bool flag) { displayTitles_ = flag; }
00266 
00267   size_t longestRowTitle() const; 
00268 
00269   void setRowsAndColumns(size_t rows, size_t cols);
00276 
00277   size_t columnWidth(size_t column) const; 
00282 
00283   void setRowInfo(size_t row, std::string const &title, size_t height, bool border)
00289   {
00290      if(row < rows_.size())
00291      {
00292         layoutDirty_ = true;
00293 
00294         rows_[row].title_        = title;
00295         rows_[row].height_       = height;
00296         rows_[row].bottomBorder_ = border;
00297      }
00298   }
00299 
00300   void setRowInfo(size_t row, std::string const &title, size_t height, bool border, bool bold, bool edit)
00308   {
00309      if(row < rows_.size())
00310      {
00311         layoutDirty_ = true;
00312 
00313         rows_[row].title_        = title;
00314         rows_[row].height_       = height;
00315         rows_[row].bottomBorder_ = border;
00316         rows_[row].bold_         = bold;
00317         rows_[row].editable_     = edit;
00318      }
00319   }
00320 
00321 
00322   void setColInfo(size_t col, std::string const &title, size_t width, bool border)
00328   {
00329      if(col < cols_.size())
00330      {
00331         layoutDirty_ = true;
00332 
00333         cols_[col].title_ = title;
00334         cols_[col].width_ = width;
00335         cols_[col].leftBorder_ = border;
00336      }
00337   }
00338 
00339   void setColInfo(size_t col, std::string const &title, size_t width, bool border, bool bold, bool edit)
00347   {
00348      if(col < cols_.size())
00349      {
00350         layoutDirty_ = true;
00351 
00352         cols_[col].title_ = title;
00353         cols_[col].width_ = width;
00354         cols_[col].leftBorder_ = border;
00355         cols_[col].bold_       = bold;
00356         cols_[col].editable_   = edit;
00357      }
00358   }
00359 
00360   void addColumnHeader(std::string const &title, size_t width, bool border)
00365   {
00366       layoutDirty_ = true;
00367 
00368       cols_.push_back( ColumnInfo(title, width, border) );
00369   }
00370 
00371   void addColumnHeader(std::string const      &title, 
00372                        size_t                  width, 
00373                        FieldAttributes const  &a, 
00374                        bool                    border)
00380   {
00381       layoutDirty_ = true;
00382 
00383       cols_.push_back( ColumnInfo(title, width, border, a.bold_, a.editable_, a.executable_) );
00384   }
00385 
00386 
00387   void addColumnData(std::string const &text)
00388   {
00389       size_t rows = layout_.size();
00390 
00391       if(rows == 0)
00392       {
00393         addRow("",1,false);
00394 
00395         rows = 1;
00396       }
00397 
00398       std::vector<CellInfo> &row = layout_[rows-1];
00399 
00400       row.push_back(CellInfo());
00401 
00402       CellInfo &cell = row.back();
00403 
00404       cell.text_.push_back(text);  // 1 row in this cell
00405   }
00406 
00407   void addRow(std::string const &title, size_t height, bool bottomBorder, bool bold=false, bool editable=true, bool executable=true)
00408   {
00409      rows_.push_back( RowInfo(title, height, bottomBorder, bold, editable, executable ) );
00410 
00411      layout_.push_back(std::vector<CellInfo>());
00412   }
00413 
00414   RowInfo const &rowInfo(size_t row) const { return rows_[row]; }
00419 
00420   void setRowInfo(size_t row, RowInfo const &r) { rows_[row] = r; }
00424 
00425 
00426 
00427   CellInfo const *cellInfo(size_t row, size_t col) const;
00434 
00435   CellInfo *cellInfo(size_t row, size_t col);
00442 
00443    void setOrigin(size_t row, size_t col) { originRow_ = row; originCol_ = col; }
00449 
00450    virtual void setCursorInfo(CursorWindow::viewport *vp,
00451                               size_t worldRow, 
00452                               size_t worldCol, 
00453                               bool displayed=true);
00471 
00472    struct CursorInfo
00477    {
00478        size_t row_;
00479        size_t col_;
00480        bool   displayed_;
00481 
00482        CursorInfo(size_t r, size_t c, bool d)
00483        : row_(r)
00484        , col_(c)
00485        , displayed_(d)
00486        {
00487        }
00488 
00489    };
00490 
00491    CursorInfo cursorInfo() const { return CursorInfo(cursorRow_, cursorCol_, cursorDisplayed_); }
00494 
00495    void setCursorInfo(CursorWindow::viewport *vp, 
00496                       CursorInfo const &i
00497                      ) 
00498        
00499 
00500 
00501    { 
00502        setCursorInfo(vp, i.row_, i.col_, i.displayed_); 
00503    }
00504 
00505    void moveUp(CursorWindow::viewport *vp);      
00508                        
00509    void moveDown(CursorWindow::viewport *vp);    
00512                        
00513    void moveLeft(CursorWindow::viewport *vp);    
00516                        
00517    void moveRight(CursorWindow::viewport *vp);   
00520                        
00521    void pageUp(CursorWindow::viewport *vp);      
00526                        
00527    void pageDown(CursorWindow::viewport *vp);    
00532                        
00533    void pageBottom(CursorWindow::viewport *vp);  
00538 
00539    void pageTop(CursorWindow::viewport *vp);     
00544                        
00545    void pageRight(CursorWindow::viewport *vp);   
00550                        
00551    void pageLeft(CursorWindow::viewport *vp);    
00556                        
00557    void pageHome(CursorWindow::viewport *vp);    
00561                        
00562    void pageEnd(CursorWindow::viewport *vp);     
00567                        
00568    void clear();       
00569 
00570   void hideCursor(CursorWindow::viewport *vp);       
00573 
00574   void showCursor(CursorWindow::viewport *vp);       
00577 
00578   virtual void paintCursor(CursorWindow::viewport *); 
00586 
00587   void paintCell(CursorWindow::viewport *vp,
00588                  size_t vpRow,
00589                  size_t vpCol,
00590                  size_t tbRow,
00591                  size_t tbCol,
00592                  bool   highlight=false,
00593                  bool   editCursor=true
00594 
00595                 );               
00607 
00608   void set_data_dirty(bool f) { dataDirty_ = f; }
00614 
00615   bool active() const { return active_; }
00620 
00621   bool mixed_case() const { return mixed_case_; }
00623 
00624   typedef std::vector< std::vector< CellInfo > > LayoutType;
00625 
00626 
00627 
00628 private:
00629 
00630 
00631 
00632   size_t                    originRow_;
00633   size_t                    originCol_;
00634 
00635   bool                      displayTitles_;
00636   bool                      active_;  // currently active window?
00637   bool                      layoutDirty_; // need to recompute layout
00638 
00639   size_t                    cursorRow_;
00640   size_t                    cursorCol_;
00641   bool                      cursorDisplayed_;
00642 
00643 
00644   CursorWindow::row_col     displayOrigin_; // scr coords of origin table display 
00645 
00646   ViewerManager*            viewerManager_;  // we don't own this!
00647 
00648   CursorWindow::row_col     textInputPointer_;
00649 
00650   bool                      dataDirty_; // see is_dirty(), set_data_dirty()
00651 
00652 
00653   void recomputeLayout();  
00654 
00655 protected:
00656 
00657   size_t                    pageWidth_;   // set by the painting proc
00658   size_t                    pageHeight_;
00659 
00660   std::vector<size_t>       colWidths_;     // computed widths
00661 
00662 
00663   LayoutType                layout_;  // a cell for each row and column
00664 
00665   std::vector<RowInfo>      rows_;  // titles, size hints etc
00666   std::vector<ColumnInfo>   cols_;
00667 
00669   // search dialog parameters
00670   //
00671   bool                      mixed_case_;     
00672   bool                      is_regex_;       
00673   bool                      match_words_;    
00674   std::string               search_text_;    
00675 
00676 
00677 
00678 
00679   virtual void paintField(CursorWindow::viewport *vp,
00680                           size_t          vpRow, 
00681                           size_t          vpCol, 
00682                           CellInfo const *cell, 
00683                           size_t          cellRow, 
00684                           size_t          vpColumns,
00685                           bool            editCursor
00686                          );
00706 
00707    void setTextInputPointer(size_t vpRow, size_t vpCol)
00711    {
00712        textInputPointer_.row_ = vpRow;
00713        textInputPointer_.col_ = vpCol;
00714    }
00715 
00716    void positionTextInputPointer(CursorWindow::viewport *vp);
00717 
00718    void forceRelayout() { layoutDirty_ = true; } 
00719 
00720 
00721 
00722     void insertRowAbove(CursorWindow::viewport *vp, RowInfo const &info); 
00728 
00729     void insertRowBelow(CursorWindow::viewport *vp, RowInfo const &info); 
00735 
00736     void deleteRow(CursorWindow::viewport *vp);
00740 
00741     void checkLayoutRecompute()
00742     {
00743         CursorInfo ci = cursorInfo();
00744 
00745         CellInfo *cell= cellInfo(ci.row_, ci.col_);
00746 
00747         if(!cell || cell->text_.empty())
00748           return;
00749 
00750         std::string text = cell->text_[0];
00751                         
00752         if(    (text.size() < colWidths_[ci.col_] / 2)
00753            ||  (text.size() > colWidths_[ci.col_] * 1.5)
00754           )
00755         {
00756           triggerLayoutRecompute(); 
00757         }
00758     }
00759 
00760     void findFirst(CursorWindow::viewport *vp);
00763 
00764     virtual bool findNext(CursorWindow::viewport *vp, bool first);
00774 
00775 };
00776 } // namespace cxxtls
00777 #endif
Generated on Wed Feb 29 22:50:04 2012 for CXXUtilities by  doxygen 1.6.3