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)
00040 , originCol_(0)
00041 , displayTitles_(false)
00042 , active_(false)
00043 , layoutDirty_(true)
00044 , cursorRow_(-1)
00045 , cursorCol_(-1)
00046 , cursorDisplayed_(1)
00047 , displayOrigin_(0,0)
00048 , viewerManager_(vm)
00049 , dataDirty_(0)
00050 , pageWidth_(0)
00051 , pageHeight_(0)
00052 , mixed_case_(true)
00053 , is_regex_(false)
00054 , match_words_(false)
00055 , search_text_("")
00056 {
00057 }
00058
00059
00060
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_;
00099 bool leftBorder_;
00100 bool bold_;
00101 bool editable_;
00102 bool executable_;
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_;
00140 bool bottomBorder_;
00141 bool bold_;
00142 bool editable_;
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);
00176
00177 };
00178
00179 struct CellInfo
00180 {
00181 std::vector< std::string > text_;
00182
00183 size_t worldRow_;
00184 size_t worldColumn_;
00185
00186 size_t widestRow() const;
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;
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);
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_;
00637 bool layoutDirty_;
00638
00639 size_t cursorRow_;
00640 size_t cursorCol_;
00641 bool cursorDisplayed_;
00642
00643
00644 CursorWindow::row_col displayOrigin_;
00645
00646 ViewerManager* viewerManager_;
00647
00648 CursorWindow::row_col textInputPointer_;
00649
00650 bool dataDirty_;
00651
00652
00653 void recomputeLayout();
00654
00655 protected:
00656
00657 size_t pageWidth_;
00658 size_t pageHeight_;
00659
00660 std::vector<size_t> colWidths_;
00661
00662
00663 LayoutType layout_;
00664
00665 std::vector<RowInfo> rows_;
00666 std::vector<ColumnInfo> cols_;
00667
00669
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 }
00777 #endif