]> git.lyx.org Git - lyx.git/blob - src/tabular.h
merge booktabs branch
[lyx.git] / src / tabular.h
1 // -*- C++ -*-
2 /**
3  * \file tabular.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  * \author Matthias Ettrich
9  * \author André Pönitz
10  * \author Jürgen Vigna
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #ifndef TABULAR_H
16 #define TABULAR_H
17
18 #include "lyxlength.h"
19 #include "insets/insettext.h"
20
21 #include <boost/shared_ptr.hpp>
22
23 #include <iosfwd>
24 #include <vector>
25
26 class InsetTabular;
27 class LCursor;
28 class OutputParams;
29
30 /* The features the text class offers for tables */
31
32 ///
33 class LyXTabular  {
34 public:
35         ///
36         enum Feature {
37                 ///
38                 APPEND_ROW = 0,
39                 ///
40                 APPEND_COLUMN,
41                 ///
42                 DELETE_ROW,
43                 ///
44                 DELETE_COLUMN,
45                 ///
46                 TOGGLE_LINE_TOP,
47                 ///
48                 TOGGLE_LINE_BOTTOM,
49                 ///
50                 TOGGLE_LINE_LEFT,
51                 ///
52                 TOGGLE_LINE_RIGHT,
53                 ///
54                 ALIGN_LEFT,
55                 ///
56                 ALIGN_RIGHT,
57                 ///
58                 ALIGN_CENTER,
59                 ///
60                 ALIGN_BLOCK,
61                 ///
62                 VALIGN_TOP,
63                 ///
64                 VALIGN_BOTTOM,
65                 ///
66                 VALIGN_MIDDLE,
67                 ///
68                 M_TOGGLE_LINE_TOP,
69                 ///
70                 M_TOGGLE_LINE_BOTTOM,
71                 ///
72                 M_TOGGLE_LINE_LEFT,
73                 ///
74                 M_TOGGLE_LINE_RIGHT,
75                 ///
76                 M_ALIGN_LEFT,
77                 ///
78                 M_ALIGN_RIGHT,
79                 ///
80                 M_ALIGN_CENTER,
81                 ///
82                 M_VALIGN_TOP,
83                 ///
84                 M_VALIGN_BOTTOM,
85                 ///
86                 M_VALIGN_MIDDLE,
87                 ///
88                 MULTICOLUMN,
89                 ///
90                 SET_ALL_LINES,
91                 ///
92                 UNSET_ALL_LINES,
93                 ///
94                 SET_LONGTABULAR,
95                 ///
96                 UNSET_LONGTABULAR,
97                 ///
98                 SET_PWIDTH,
99                 ///
100                 SET_MPWIDTH,
101                 ///
102                 SET_ROTATE_TABULAR,
103                 ///
104                 UNSET_ROTATE_TABULAR,
105                 ///
106                 SET_ROTATE_CELL,
107                 ///
108                 UNSET_ROTATE_CELL,
109                 ///
110                 SET_USEBOX,
111                 ///
112                 SET_LTHEAD,
113                 UNSET_LTHEAD,
114                 ///
115                 SET_LTFIRSTHEAD,
116                 UNSET_LTFIRSTHEAD,
117                 ///
118                 SET_LTFOOT,
119                 UNSET_LTFOOT,
120                 ///
121                 SET_LTLASTFOOT,
122                 UNSET_LTLASTFOOT,
123                 ///
124                 SET_LTNEWPAGE,
125                 ///
126                 SET_SPECIAL_COLUMN,
127                 ///
128                 SET_SPECIAL_MULTI,
129                 ///
130                 SET_BOOKTABS,
131                 ///
132                 UNSET_BOOKTABS,
133                 ///
134                 SET_TOP_SPACE,
135                 ///
136                 SET_BOTTOM_SPACE,
137                 ///
138                 SET_INTERLINE_SPACE,
139                 ///
140                 LAST_ACTION
141         };
142         ///
143         enum {
144                 ///
145                 CELL_NORMAL = 0,
146                 ///
147                 CELL_BEGIN_OF_MULTICOLUMN,
148                 ///
149                 CELL_PART_OF_MULTICOLUMN
150         };
151
152         ///
153         enum VAlignment {
154                 ///
155                 LYX_VALIGN_TOP = 0,
156                 ///
157                 LYX_VALIGN_BOTTOM = 1,
158                 ///
159                 LYX_VALIGN_MIDDLE = 2
160         };
161
162         enum BoxType {
163                 ///
164                 BOX_NONE = 0,
165                 ///
166                 BOX_PARBOX = 1,
167                 ///
168                 BOX_MINIPAGE = 2
169         };
170
171         class ltType {
172         public:
173                 // constructor
174                 ltType();
175                 // we have this header type (is set in the getLT... functions)
176                 bool set;
177                 // double borders on top
178                 bool topDL;
179                 // double borders on bottom
180                 bool bottomDL;
181                 // used for FirstHeader & LastFooter and if this is true
182                 // all the rows marked as FirstHeader or LastFooter are
183                 // ignored in the output and it is set to be empty!
184                 bool empty;
185         };
186
187         /// type for row numbers
188         typedef size_t row_type;
189         /// type for column numbers
190         typedef size_t col_type;
191         /// type for cell indices
192         typedef size_t idx_type;
193         /// index indicating an invalid position
194         static const idx_type npos = static_cast<idx_type>(-1);
195
196         /// constructor
197         LyXTabular(BufferParams const &, col_type columns_arg,
198                    row_type rows_arg);
199
200         /// Returns true if there is a topline, returns false if not
201         bool topLine(idx_type cell, bool onlycolumn = false) const;
202         /// Returns true if there is a topline, returns false if not
203         bool bottomLine(idx_type cell, bool onlycolumn = false) const;
204         /// Returns true if there is a topline, returns false if not
205         bool leftLine(idx_type cell, bool onlycolumn = false) const;
206         /// Returns true if there is a topline, returns false if not
207         bool rightLine(idx_type cell, bool onlycolumn = false) const;
208
209         ///
210         bool topAlreadyDrawn(idx_type cell) const;
211         ///
212         bool leftAlreadyDrawn(idx_type cell) const;
213         ///
214         bool isLastRow(idx_type cell) const;
215
216         /// return space occupied by the second horizontal line and
217         /// interline space above row \p row in pixels
218         int getAdditionalHeight(row_type row) const;
219         ///
220         int getAdditionalWidth(idx_type cell) const;
221
222         /* returns the maximum over all rows */
223         ///
224         int getWidthOfColumn(idx_type cell) const;
225         ///
226         int getWidthOfTabular() const;
227         ///
228         int getAscentOfRow(row_type row) const;
229         ///
230         int getDescentOfRow(row_type row) const;
231         ///
232         int getHeightOfTabular() const;
233         ///
234         void setAscentOfRow(row_type row, int height);
235         ///
236         void setDescentOfRow(row_type row, int height);
237         ///
238         void setWidthOfCell(idx_type cell, int new_width);
239         ///
240         void setAllLines(idx_type cell, bool line);
241         ///
242         void setTopLine(idx_type cell, bool line, bool onlycolumn = false);
243         ///
244         void setBottomLine(idx_type cell, bool line, bool onlycolumn = false);
245         ///
246         void setLeftLine(idx_type cell, bool line, bool onlycolumn = false);
247         ///
248         void setRightLine(idx_type cell, bool line, bool onlycolumn = false);
249         ///
250         void setAlignment(idx_type cell, LyXAlignment align,
251                           bool onlycolumn = false);
252         ///
253         void setVAlignment(idx_type cell, VAlignment align,
254                            bool onlycolumn = false);
255         ///
256         void setColumnPWidth(LCursor &, idx_type, LyXLength const &);
257         ///
258         bool setMColumnPWidth(LCursor &, idx_type, LyXLength const &);
259         ///
260         void setAlignSpecial(idx_type cell, std::string const & special,
261                              Feature what);
262         ///
263         LyXAlignment getAlignment(idx_type cell,
264                                   bool onlycolumn = false) const;
265         ///
266         VAlignment getVAlignment(idx_type cell,
267                                  bool onlycolumn = false) const;
268         ///
269         LyXLength const getPWidth(idx_type cell) const;
270         ///
271         LyXLength const getColumnPWidth(idx_type cell) const;
272         ///
273         LyXLength const getMColumnPWidth(idx_type cell) const;
274         ///
275         std::string const getAlignSpecial(idx_type cell, int what) const;
276         ///
277         int getWidthOfCell(idx_type cell) const;
278         ///
279         int getBeginningOfTextInCell(idx_type cell) const;
280         ///
281         void appendRow(BufferParams const &, idx_type cell);
282         ///
283         void deleteRow(row_type row);
284         ///
285         void appendColumn(BufferParams const &, idx_type cell);
286         ///
287         void deleteColumn(col_type column);
288         ///
289         bool isFirstCellInRow(idx_type cell) const;
290         ///
291         idx_type getFirstCellInRow(row_type row) const;
292         ///
293         bool isLastCellInRow(idx_type cell) const;
294         ///
295         idx_type getLastCellInRow(row_type row) const;
296         ///
297         idx_type getNumberOfCells() const;
298         ///
299         idx_type numberOfCellsInRow(idx_type cell) const;
300         ///
301         void write(Buffer const &, std::ostream &) const;
302         ///
303         void read(Buffer const &, LyXLex &);
304         ///
305         int latex(Buffer const &, std::ostream &,
306                   OutputParams const &) const;
307         //
308         int linuxdoc(Buffer const & buf, std::ostream & os,
309                      OutputParams const &) const;
310         ///
311         int docbook(Buffer const & buf, std::ostream & os,
312                     OutputParams const &) const;
313         ///
314         int plaintext(Buffer const &, std::ostream &,
315                   OutputParams const & runparams,
316                   int const depth,
317                   bool onlydata, unsigned char delim) const;
318         ///
319         bool isMultiColumn(idx_type cell) const;
320         ///
321         bool isMultiColumnReal(idx_type cell) const;
322         ///
323         void setMultiColumn(Buffer *, idx_type cell, idx_type number);
324         ///
325         idx_type unsetMultiColumn(idx_type cell); // returns number of new cells
326         ///
327         bool isPartOfMultiColumn(row_type row, col_type column) const;
328         ///
329         row_type row_of_cell(idx_type cell) const;
330         ///
331         col_type column_of_cell(idx_type cell) const;
332         ///
333         col_type right_column_of_cell(idx_type cell) const;
334         ///
335         void setBookTabs(bool);
336         ///
337         bool useBookTabs() const;
338         ///
339         void setLongTabular(bool);
340         ///
341         bool isLongTabular() const;
342         ///
343         void setRotateTabular(bool);
344         ///
345         bool getRotateTabular() const;
346         ///
347         void setRotateCell(idx_type cell, bool);
348         ///
349         bool getRotateCell(idx_type cell) const;
350         ///
351         bool needRotating() const;
352         ///
353         bool isLastCell(idx_type cell) const;
354         ///
355         idx_type getCellAbove(idx_type cell) const;
356         ///
357         idx_type getCellBelow(idx_type cell) const;
358         ///
359         idx_type getLastCellAbove(idx_type cell) const;
360         ///
361         idx_type getLastCellBelow(idx_type cell) const;
362         ///
363         idx_type getCellNumber(row_type row, col_type column) const;
364         ///
365         void setUsebox(idx_type cell, BoxType);
366         ///
367         BoxType getUsebox(idx_type cell) const;
368         //
369         // Long Tabular Options support functions
370         ///
371         bool checkLTType(row_type row, ltType const &) const;
372         ///
373         void setLTHead(row_type row, bool flag, ltType const &, bool first);
374         ///
375         bool getRowOfLTHead(row_type row, ltType &) const;
376         ///
377         bool getRowOfLTFirstHead(row_type row, ltType &) const;
378         ///
379         void setLTFoot(row_type row, bool flag, ltType const &, bool last);
380         ///
381         bool getRowOfLTFoot(row_type row, ltType &) const;
382         ///
383         bool getRowOfLTLastFoot(row_type row, ltType &) const;
384         ///
385         void setLTNewPage(row_type row, bool what);
386         ///
387         bool getLTNewPage(row_type row) const;
388         ///
389         bool haveLTHead() const;
390         ///
391         bool haveLTFirstHead() const;
392         ///
393         bool haveLTFoot() const;
394         ///
395         bool haveLTLastFoot() const;
396         ///
397         // end longtable support
398         ///
399         boost::shared_ptr<InsetText> getCellInset(idx_type cell) const;
400         ///
401         boost::shared_ptr<InsetText> getCellInset(row_type row,
402                                                   col_type column) const;
403         ///
404         void setCellInset(row_type row, col_type column,
405                           boost::shared_ptr<InsetText>) const;
406         /// Search for \param inset in the tabular, with the
407         ///
408         idx_type getCellFromInset(InsetBase const * inset) const;
409         ///
410         row_type rows() const { return rows_; }
411         ///
412         col_type columns() const { return columns_;}
413         ///
414         void validate(LaTeXFeatures &) const;
415         ///
416 //private:
417         ///
418         class cellstruct {
419         public:
420                 ///
421                 cellstruct(BufferParams const &);
422                 ///
423                 cellstruct(cellstruct const &);
424                 ///
425                 cellstruct & operator=(cellstruct);
426                 ///
427                 void swap(cellstruct & rhs);
428                 ///
429                 idx_type cellno;
430                 ///
431                 int width_of_cell;
432                 ///
433                 int multicolumn;
434                 ///
435                 LyXAlignment alignment;
436                 ///
437                 VAlignment valignment;
438                 ///
439                 bool top_line;
440                 ///
441                 bool bottom_line;
442                 ///
443                 bool left_line;
444                 ///
445                 bool right_line;
446                 ///
447                 BoxType usebox;
448                 ///
449                 bool rotate;
450                 ///
451                 std::string align_special;
452                 ///
453                 LyXLength p_width; // this is only set for multicolumn!!!
454                 ///
455                 boost::shared_ptr<InsetText> inset;
456         };
457         cellstruct & cellinfo_of_cell(idx_type cell) const;
458         ///
459         typedef std::vector<cellstruct> cell_vector;
460         ///
461         typedef std::vector<cell_vector> cell_vvector;
462
463         ///
464         class rowstruct {
465         public:
466                 ///
467                 rowstruct();
468                 ///
469                 int ascent_of_row;
470                 ///
471                 int descent_of_row;
472                 ///
473                 bool top_line;
474                 ///
475                 bool bottom_line;
476                 /// Extra space between the top line and this row
477                 LyXLength top_space;
478                 /// Ignore top_space if true and use the default top space
479                 bool top_space_default;
480                 /// Extra space between this row and the bottom line
481                 LyXLength bottom_space;
482                 /// Ignore bottom_space if true and use the default bottom space
483                 bool bottom_space_default;
484                 /// Extra space between the bottom line and the next top line
485                 LyXLength interline_space;
486                 /// Ignore interline_space if true and use the default interline space
487                 bool interline_space_default;
488                 /// This are for longtabulars only
489                 /// a row of endhead
490                 bool endhead;
491                 /// a row of endfirsthead
492                 bool endfirsthead;
493                 /// a row of endfoot
494                 bool endfoot;
495                 /// row of endlastfoot
496                 bool endlastfoot;
497                 /// row for a pagebreak
498                 bool newpage;
499         };
500         ///
501         typedef std::vector<rowstruct> row_vector;
502
503         ///
504         class columnstruct {
505                 public:
506                 ///
507                 columnstruct();
508                 ///
509                 LyXAlignment alignment;
510                 ///
511                 VAlignment valignment;
512                 ///
513                 bool left_line;
514                 ///
515                 bool right_line;
516                 ///
517                 int  width_of_column;
518                 ///
519                 LyXLength p_width;
520                 ///
521                 std::string align_special;
522         };
523         ///
524         typedef std::vector<columnstruct> column_vector;
525
526         ///
527         row_type rows_;
528         ///
529         col_type columns_;
530         ///
531         idx_type numberofcells;
532         ///
533         std::vector<row_type> rowofcell;
534         ///
535         std::vector<col_type> columnofcell;
536         ///
537         row_vector row_info;
538         ///
539         column_vector column_info;
540         ///
541         mutable cell_vvector cell_info;
542         ///
543         int width_of_tabular;
544         ///
545         bool use_booktabs;
546         ///
547         bool rotate;
548         //
549         // for long tabulars
550         //
551         bool is_long_tabular;
552         /// endhead data
553         ltType endhead;
554         /// endfirsthead data
555         ltType endfirsthead;
556         /// endfoot data
557         ltType endfoot;
558         /// endlastfoot data
559         ltType endlastfoot;
560
561         ///
562         void init(BufferParams const &, row_type rows_arg,
563                   col_type columns_arg);
564         ///
565         void set_row_column_number_info();
566         /// Returns true if a complete update is necessary, otherwise false
567         bool setWidthOfMulticolCell(idx_type cell, int new_width);
568         ///
569         void recalculateMulticolumnsOfColumn(col_type column);
570         /// Returns true if change
571         void calculate_width_of_column(col_type column);
572         ///
573         bool calculate_width_of_column_NMC(col_type column); // no multi cells
574         ///
575         void calculate_width_of_tabular();
576         ///
577         void delete_column(col_type column);
578         ///
579         idx_type cells_in_multicolumn(idx_type cell) const;
580         ///
581         BoxType useParbox(idx_type cell) const;
582         ///
583         // helper function for Latex returns number of newlines
584         ///
585         int TeXTopHLine(std::ostream &, row_type row) const;
586         ///
587         int TeXBottomHLine(std::ostream &, row_type row) const;
588         ///
589         int TeXCellPreamble(std::ostream &, idx_type cell) const;
590         ///
591         int TeXCellPostamble(std::ostream &, idx_type cell) const;
592         ///
593         int TeXLongtableHeaderFooter(std::ostream &, Buffer const & buf,
594                                      OutputParams const &) const;
595         ///
596         bool isValidRow(row_type const row) const;
597         ///
598         int TeXRow(std::ostream &, row_type const row, Buffer const & buf,
599                    OutputParams const &) const;
600         ///
601         // helper function for ASCII returns number of newlines
602         ///
603         int asciiTopHLine(std::ostream &, row_type row,
604                           std::vector<unsigned int> const &) const;
605         ///
606         int asciiBottomHLine(std::ostream &, row_type row,
607                              std::vector<unsigned int> const &) const;
608         ///
609         int asciiPrintCell(Buffer const &, std::ostream &,
610                            OutputParams const &,
611                            idx_type cell, row_type row, col_type column,
612                            std::vector<unsigned int> const &,
613                                            bool onlydata) const;
614         /// auxiliary function for docbook
615         int docbookRow(Buffer const & buf, std::ostream & os, row_type,
616                        OutputParams const &) const;
617
618 private:
619         /// renumber cells after structural changes
620         void fixCellNums();
621 };
622
623 #endif