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