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