]> git.lyx.org Git - lyx.git/blob - src/tabular.h
restore 1.3 behaviour when changing tabular columns to variable width
[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                 LAST_ACTION
131         };
132         ///
133         enum {
134                 ///
135                 CELL_NORMAL = 0,
136                 ///
137                 CELL_BEGIN_OF_MULTICOLUMN,
138                 ///
139                 CELL_PART_OF_MULTICOLUMN
140         };
141
142         ///
143         enum VAlignment {
144                 ///
145                 LYX_VALIGN_TOP = 0,
146                 ///
147                 LYX_VALIGN_BOTTOM = 1,
148                 ///
149                 LYX_VALIGN_MIDDLE = 2
150         };
151
152         enum BoxType {
153                 ///
154                 BOX_NONE = 0,
155                 ///
156                 BOX_PARBOX = 1,
157                 ///
158                 BOX_MINIPAGE = 2
159         };
160
161         class ltType {
162         public:
163                 // constructor
164                 ltType();
165                 // we have this header type (is set in the getLT... functions)
166                 bool set;
167                 // double borders on top
168                 bool topDL;
169                 // double borders on bottom
170                 bool bottomDL;
171                 // used for FirstHeader & LastFooter and if this is true
172                 // all the rows marked as FirstHeader or LastFooter are
173                 // ignored in the output and it is set to be empty!
174                 bool empty;
175         };
176
177         /// type for row numbers
178         typedef size_t row_type;
179         /// type for column numbers
180         typedef size_t col_type;
181         /// type for cell indices
182         typedef size_t idx_type;
183         /// index indicating an invalid position
184         static const idx_type npos = static_cast<idx_type>(-1);
185
186         /// constructor
187         LyXTabular(BufferParams const &, col_type columns_arg,
188                    row_type rows_arg);
189
190         /// Returns true if there is a topline, returns false if not
191         bool topLine(idx_type cell, bool onlycolumn = false) const;
192         /// Returns true if there is a topline, returns false if not
193         bool bottomLine(idx_type cell, bool onlycolumn = false) const;
194         /// Returns true if there is a topline, returns false if not
195         bool leftLine(idx_type cell, bool onlycolumn = false) const;
196         /// Returns true if there is a topline, returns false if not
197         bool rightLine(idx_type cell, bool onlycolumn = false) const;
198
199         ///
200         bool topAlreadyDrawn(idx_type cell) const;
201         ///
202         bool leftAlreadyDrawn(idx_type cell) const;
203         ///
204         bool isLastRow(idx_type cell) const;
205
206         ///
207         int getAdditionalHeight(row_type row) const;
208         ///
209         int getAdditionalWidth(idx_type cell) const;
210
211         /* returns the maximum over all rows */
212         ///
213         int getWidthOfColumn(idx_type cell) const;
214         ///
215         int getWidthOfTabular() const;
216         ///
217         int getAscentOfRow(row_type row) const;
218         ///
219         int getDescentOfRow(row_type row) const;
220         ///
221         int getHeightOfTabular() const;
222         ///
223         void setAscentOfRow(row_type row, int height);
224         ///
225         void setDescentOfRow(row_type row, int height);
226         ///
227         void setWidthOfCell(idx_type cell, int new_width);
228         ///
229         void setAllLines(idx_type cell, bool line);
230         ///
231         void setTopLine(idx_type cell, bool line, bool onlycolumn = false);
232         ///
233         void setBottomLine(idx_type cell, bool line, bool onlycolumn = false);
234         ///
235         void setLeftLine(idx_type cell, bool line, bool onlycolumn = false);
236         ///
237         void setRightLine(idx_type cell, bool line, bool onlycolumn = false);
238         ///
239         void setAlignment(idx_type cell, LyXAlignment align,
240                           bool onlycolumn = false);
241         ///
242         void setVAlignment(idx_type cell, VAlignment align,
243                            bool onlycolumn = false);
244         ///
245         void setColumnPWidth(LCursor &, idx_type, LyXLength const &);
246         ///
247         bool setMColumnPWidth(LCursor &, idx_type, LyXLength const &);
248         ///
249         void setAlignSpecial(idx_type cell, std::string const & special,
250                              Feature what);
251         ///
252         LyXAlignment getAlignment(idx_type cell,
253                                   bool onlycolumn = false) const;
254         ///
255         VAlignment getVAlignment(idx_type cell,
256                                  bool onlycolumn = false) const;
257         ///
258         LyXLength const getPWidth(idx_type cell) const;
259         ///
260         LyXLength const getColumnPWidth(idx_type cell) const;
261         ///
262         LyXLength const getMColumnPWidth(idx_type cell) const;
263         ///
264         std::string const getAlignSpecial(idx_type cell, int what) const;
265         ///
266         int getWidthOfCell(idx_type cell) const;
267         ///
268         int getBeginningOfTextInCell(idx_type cell) const;
269         ///
270         void appendRow(BufferParams const &, idx_type cell);
271         ///
272         void deleteRow(row_type row);
273         ///
274         void appendColumn(BufferParams const &, idx_type cell);
275         ///
276         void deleteColumn(col_type column);
277         ///
278         bool isFirstCellInRow(idx_type cell) const;
279         ///
280         idx_type getFirstCellInRow(row_type row) const;
281         ///
282         bool isLastCellInRow(idx_type cell) const;
283         ///
284         idx_type getLastCellInRow(row_type row) const;
285         ///
286         idx_type getNumberOfCells() const;
287         ///
288         idx_type numberOfCellsInRow(idx_type cell) const;
289         ///
290         void write(Buffer const &, std::ostream &) const;
291         ///
292         void read(Buffer const &, LyXLex &);
293         ///
294         int latex(Buffer const &, std::ostream &,
295                   OutputParams const &) const;
296         //
297         int linuxdoc(Buffer const & buf, std::ostream & os,
298                      OutputParams const &) const;
299         ///
300         int docbook(Buffer const & buf, std::ostream & os,
301                     OutputParams const &) const;
302         ///
303         int plaintext(Buffer const &, std::ostream &,
304                   OutputParams const & runparams,
305                   int const depth,
306                   bool onlydata, unsigned char delim) const;
307         ///
308         bool isMultiColumn(idx_type cell) const;
309         ///
310         bool isMultiColumnReal(idx_type cell) const;
311         ///
312         void setMultiColumn(Buffer *, idx_type cell, idx_type number);
313         ///
314         idx_type unsetMultiColumn(idx_type cell); // returns number of new cells
315         ///
316         bool isPartOfMultiColumn(row_type row, col_type column) const;
317         ///
318         row_type row_of_cell(idx_type cell) const;
319         ///
320         col_type column_of_cell(idx_type cell) const;
321         ///
322         col_type right_column_of_cell(idx_type cell) const;
323         ///
324         void setLongTabular(bool);
325         ///
326         bool isLongTabular() const;
327         ///
328         void setRotateTabular(bool);
329         ///
330         bool getRotateTabular() const;
331         ///
332         void setRotateCell(idx_type cell, bool);
333         ///
334         bool getRotateCell(idx_type cell) const;
335         ///
336         bool needRotating() const;
337         ///
338         bool isLastCell(idx_type cell) const;
339         ///
340         idx_type getCellAbove(idx_type cell) const;
341         ///
342         idx_type getCellBelow(idx_type cell) const;
343         ///
344         idx_type getLastCellAbove(idx_type cell) const;
345         ///
346         idx_type getLastCellBelow(idx_type cell) const;
347         ///
348         idx_type getCellNumber(row_type row, col_type column) const;
349         ///
350         void setUsebox(idx_type cell, BoxType);
351         ///
352         BoxType getUsebox(idx_type cell) const;
353         //
354         // Long Tabular Options support functions
355         ///
356         bool checkLTType(row_type row, ltType const &) const;
357         ///
358         void setLTHead(row_type row, bool flag, ltType const &, bool first);
359         ///
360         bool getRowOfLTHead(row_type row, ltType &) const;
361         ///
362         bool getRowOfLTFirstHead(row_type row, ltType &) const;
363         ///
364         void setLTFoot(row_type row, bool flag, ltType const &, bool last);
365         ///
366         bool getRowOfLTFoot(row_type row, ltType &) const;
367         ///
368         bool getRowOfLTLastFoot(row_type row, ltType &) const;
369         ///
370         void setLTNewPage(row_type row, bool what);
371         ///
372         bool getLTNewPage(row_type row) const;
373         ///
374         bool haveLTHead() const;
375         ///
376         bool haveLTFirstHead() const;
377         ///
378         bool haveLTFoot() const;
379         ///
380         bool haveLTLastFoot() const;
381         ///
382         // end longtable support
383         ///
384         boost::shared_ptr<InsetText> getCellInset(idx_type cell) const;
385         ///
386         boost::shared_ptr<InsetText> getCellInset(row_type row,
387                                                   col_type column) const;
388         ///
389         void setCellInset(row_type row, col_type column,
390                           boost::shared_ptr<InsetText>) const;
391         /// Search for \param inset in the tabular, with the
392         ///
393         idx_type getCellFromInset(InsetBase const * inset) const;
394         ///
395         row_type rows() const { return rows_; }
396         ///
397         col_type columns() const { return columns_;}
398         ///
399         void validate(LaTeXFeatures &) const;
400         /// Appends \c list with all labels found within this inset.
401         void getLabelList(Buffer const &, std::vector<std::string> & list) const;
402         ///
403 //private:
404         ///
405         class cellstruct {
406         public:
407                 ///
408                 cellstruct(BufferParams const &);
409                 ///
410                 cellstruct(cellstruct const &);
411                 ///
412                 cellstruct & operator=(cellstruct);
413                 ///
414                 void swap(cellstruct & rhs);
415                 ///
416                 idx_type cellno;
417                 ///
418                 int width_of_cell;
419                 ///
420                 int multicolumn;
421                 ///
422                 LyXAlignment alignment;
423                 ///
424                 VAlignment valignment;
425                 ///
426                 bool top_line;
427                 ///
428                 bool bottom_line;
429                 ///
430                 bool left_line;
431                 ///
432                 bool right_line;
433                 ///
434                 BoxType usebox;
435                 ///
436                 bool rotate;
437                 ///
438                 std::string align_special;
439                 ///
440                 LyXLength p_width; // this is only set for multicolumn!!!
441                 ///
442                 boost::shared_ptr<InsetText> inset;
443         };
444         cellstruct & cellinfo_of_cell(idx_type cell) const;
445         ///
446         typedef std::vector<cellstruct> cell_vector;
447         ///
448         typedef std::vector<cell_vector> cell_vvector;
449
450         ///
451         class rowstruct {
452         public:
453                 ///
454                 rowstruct();
455                 ///
456                 int ascent_of_row;
457                 ///
458                 int descent_of_row;
459                 ///
460                 bool top_line;
461                 ///
462                 bool bottom_line;
463                 /// This are for longtabulars only
464                 /// a row of endhead
465                 bool endhead;
466                 /// a row of endfirsthead
467                 bool endfirsthead;
468                 /// a row of endfoot
469                 bool endfoot;
470                 /// row of endlastfoot
471                 bool endlastfoot;
472                 /// row for a pagebreak
473                 bool newpage;
474         };
475         ///
476         typedef std::vector<rowstruct> row_vector;
477
478         ///
479         class columnstruct {
480                 public:
481                 ///
482                 columnstruct();
483                 ///
484                 LyXAlignment alignment;
485                 ///
486                 VAlignment valignment;
487                 ///
488                 bool left_line;
489                 ///
490                 bool right_line;
491                 ///
492                 int  width_of_column;
493                 ///
494                 LyXLength p_width;
495                 ///
496                 std::string align_special;
497         };
498         ///
499         typedef std::vector<columnstruct> column_vector;
500
501         ///
502         row_type rows_;
503         ///
504         col_type columns_;
505         ///
506         idx_type numberofcells;
507         ///
508         std::vector<row_type> rowofcell;
509         ///
510         std::vector<col_type> columnofcell;
511         ///
512         row_vector row_info;
513         ///
514         column_vector column_info;
515         ///
516         mutable cell_vvector cell_info;
517         ///
518         int width_of_tabular;
519         ///
520         bool rotate;
521         //
522         // for long tabulars
523         //
524         bool is_long_tabular;
525         /// endhead data
526         ltType endhead;
527         /// endfirsthead data
528         ltType endfirsthead;
529         /// endfoot data
530         ltType endfoot;
531         /// endlastfoot data
532         ltType endlastfoot;
533
534         ///
535         void init(BufferParams const &, row_type rows_arg,
536                   col_type columns_arg);
537         ///
538         void set_row_column_number_info();
539         /// Returns true if a complete update is necessary, otherwise false
540         bool setWidthOfMulticolCell(idx_type cell, int new_width);
541         ///
542         void recalculateMulticolumnsOfColumn(col_type column);
543         /// Returns true if change
544         void calculate_width_of_column(col_type column);
545         ///
546         bool calculate_width_of_column_NMC(col_type column); // no multi cells
547         ///
548         void calculate_width_of_tabular();
549         ///
550         void delete_column(col_type column);
551         ///
552         idx_type cells_in_multicolumn(idx_type cell) const;
553         ///
554         BoxType useParbox(idx_type cell) const;
555         ///
556         // helper function for Latex returns number of newlines
557         ///
558         int TeXTopHLine(std::ostream &, row_type row) const;
559         ///
560         int TeXBottomHLine(std::ostream &, row_type row) const;
561         ///
562         int TeXCellPreamble(std::ostream &, idx_type cell) const;
563         ///
564         int TeXCellPostamble(std::ostream &, idx_type cell) const;
565         ///
566         int TeXLongtableHeaderFooter(std::ostream &, Buffer const & buf,
567                                      OutputParams const &) const;
568         ///
569         bool isValidRow(row_type const row) const;
570         ///
571         int TeXRow(std::ostream &, row_type const row, Buffer const & buf,
572                    OutputParams const &) const;
573         ///
574         // helper function for ASCII returns number of newlines
575         ///
576         int asciiTopHLine(std::ostream &, row_type row,
577                           std::vector<unsigned int> const &) const;
578         ///
579         int asciiBottomHLine(std::ostream &, row_type row,
580                              std::vector<unsigned int> const &) const;
581         ///
582         int asciiPrintCell(Buffer const &, std::ostream &,
583                            OutputParams const &,
584                            idx_type cell, row_type row, col_type column,
585                            std::vector<unsigned int> const &,
586                                            bool onlydata) const;
587         /// auxiliary function for docbook
588         int docbookRow(Buffer const & buf, std::ostream & os, row_type,
589                        OutputParams const &) const;
590
591 private:
592         /// renumber cells after structural changes
593         void fixCellNums();
594 };
595
596 #endif