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