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