]> git.lyx.org Git - lyx.git/blob - src/tabular.h
Fix bug 2485 and crash on middle mouse paste on math
[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         ///
401 //private:
402         ///
403         class cellstruct {
404         public:
405                 ///
406                 cellstruct(BufferParams const &);
407                 ///
408                 cellstruct(cellstruct const &);
409                 ///
410                 cellstruct & operator=(cellstruct);
411                 ///
412                 void swap(cellstruct & rhs);
413                 ///
414                 idx_type cellno;
415                 ///
416                 int width_of_cell;
417                 ///
418                 int multicolumn;
419                 ///
420                 LyXAlignment alignment;
421                 ///
422                 VAlignment valignment;
423                 ///
424                 bool top_line;
425                 ///
426                 bool bottom_line;
427                 ///
428                 bool left_line;
429                 ///
430                 bool right_line;
431                 ///
432                 BoxType usebox;
433                 ///
434                 bool rotate;
435                 ///
436                 std::string align_special;
437                 ///
438                 LyXLength p_width; // this is only set for multicolumn!!!
439                 ///
440                 boost::shared_ptr<InsetText> inset;
441         };
442         cellstruct & cellinfo_of_cell(idx_type cell) const;
443         ///
444         typedef std::vector<cellstruct> cell_vector;
445         ///
446         typedef std::vector<cell_vector> cell_vvector;
447
448         ///
449         class rowstruct {
450         public:
451                 ///
452                 rowstruct();
453                 ///
454                 int ascent_of_row;
455                 ///
456                 int descent_of_row;
457                 ///
458                 bool top_line;
459                 ///
460                 bool bottom_line;
461                 /// This are for longtabulars only
462                 /// a row of endhead
463                 bool endhead;
464                 /// a row of endfirsthead
465                 bool endfirsthead;
466                 /// a row of endfoot
467                 bool endfoot;
468                 /// row of endlastfoot
469                 bool endlastfoot;
470                 /// row for a pagebreak
471                 bool newpage;
472         };
473         ///
474         typedef std::vector<rowstruct> row_vector;
475
476         ///
477         class columnstruct {
478                 public:
479                 ///
480                 columnstruct();
481                 ///
482                 LyXAlignment alignment;
483                 ///
484                 VAlignment valignment;
485                 ///
486                 bool left_line;
487                 ///
488                 bool right_line;
489                 ///
490                 int  width_of_column;
491                 ///
492                 LyXLength p_width;
493                 ///
494                 std::string align_special;
495         };
496         ///
497         typedef std::vector<columnstruct> column_vector;
498
499         ///
500         row_type rows_;
501         ///
502         col_type columns_;
503         ///
504         idx_type numberofcells;
505         ///
506         std::vector<row_type> rowofcell;
507         ///
508         std::vector<col_type> columnofcell;
509         ///
510         row_vector row_info;
511         ///
512         column_vector column_info;
513         ///
514         mutable cell_vvector cell_info;
515         ///
516         int width_of_tabular;
517         ///
518         bool rotate;
519         //
520         // for long tabulars
521         //
522         bool is_long_tabular;
523         /// endhead data
524         ltType endhead;
525         /// endfirsthead data
526         ltType endfirsthead;
527         /// endfoot data
528         ltType endfoot;
529         /// endlastfoot data
530         ltType endlastfoot;
531
532         ///
533         void init(BufferParams const &, row_type rows_arg,
534                   col_type columns_arg);
535         ///
536         void set_row_column_number_info();
537         /// Returns true if a complete update is necessary, otherwise false
538         bool setWidthOfMulticolCell(idx_type cell, int new_width);
539         ///
540         void recalculateMulticolumnsOfColumn(col_type column);
541         /// Returns true if change
542         void calculate_width_of_column(col_type column);
543         ///
544         bool calculate_width_of_column_NMC(col_type column); // no multi cells
545         ///
546         void calculate_width_of_tabular();
547         ///
548         void delete_column(col_type column);
549         ///
550         idx_type cells_in_multicolumn(idx_type cell) const;
551         ///
552         BoxType useParbox(idx_type cell) const;
553         ///
554         // helper function for Latex returns number of newlines
555         ///
556         int TeXTopHLine(std::ostream &, row_type row) const;
557         ///
558         int TeXBottomHLine(std::ostream &, row_type row) const;
559         ///
560         int TeXCellPreamble(std::ostream &, idx_type cell) const;
561         ///
562         int TeXCellPostamble(std::ostream &, idx_type cell) const;
563         ///
564         int TeXLongtableHeaderFooter(std::ostream &, Buffer const & buf,
565                                      OutputParams const &) const;
566         ///
567         bool isValidRow(row_type const row) const;
568         ///
569         int TeXRow(std::ostream &, row_type const row, Buffer const & buf,
570                    OutputParams const &) const;
571         ///
572         // helper function for ASCII returns number of newlines
573         ///
574         int asciiTopHLine(std::ostream &, row_type row,
575                           std::vector<unsigned int> const &) const;
576         ///
577         int asciiBottomHLine(std::ostream &, row_type row,
578                              std::vector<unsigned int> const &) const;
579         ///
580         int asciiPrintCell(Buffer const &, std::ostream &,
581                            OutputParams const &,
582                            idx_type cell, row_type row, col_type column,
583                            std::vector<unsigned int> const &,
584                                            bool onlydata) const;
585         /// auxiliary function for docbook
586         int docbookRow(Buffer const & buf, std::ostream & os, row_type,
587                        OutputParams const &) const;
588
589 private:
590         /// renumber cells after structural changes
591         void fixCellNums();
592 };
593
594 #endif