]> git.lyx.org Git - lyx.git/blob - src/tabular.h
Fix natbib bug spotted by JMarc.
[lyx.git] / src / tabular.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ======================================================
4  *
5  *           LyX, The Document Processor
6  *
7  *           Copyright 2000-2001 The LyX Team.
8  *
9  *           @author: Jürgen Vigna
10  *
11  * ====================================================== */
12 #ifndef TABULAR_H
13 #define TABULAR_H
14
15 #ifdef __GNUG__
16 #pragma interface
17 #endif
18
19 #include "layout.h"
20 #include "LString.h"
21 #include "lyxlength.h"
22
23 #include "insets/insettext.h"
24
25 #include <iosfwd>
26 #include <vector>
27
28 class InsetTabular;
29 class BufferParams;
30 class LaTeXFeatures;
31 class Buffer;
32 class LyXLex;
33
34 /* The features the text class offers for tables */
35
36 ///
37 class LyXTabular  {
38 public:
39         ///
40         enum Feature {
41                 ///
42                 APPEND_ROW = 0,
43                 ///
44                 APPEND_COLUMN,
45                 ///
46                 DELETE_ROW,
47                 ///
48                 DELETE_COLUMN,
49                 ///
50                 TOGGLE_LINE_TOP,
51                 ///
52                 TOGGLE_LINE_BOTTOM,
53                 ///
54                 TOGGLE_LINE_LEFT,
55                 ///
56                 TOGGLE_LINE_RIGHT,
57                 ///
58                 ALIGN_LEFT,
59                 ///
60                 ALIGN_RIGHT,
61                 ///
62                 ALIGN_CENTER,
63                 ///
64                 ALIGN_BLOCK,
65                 ///
66                 VALIGN_TOP,
67                 ///
68                 VALIGN_BOTTOM,
69                 ///
70                 VALIGN_CENTER,
71                 ///
72                 M_TOGGLE_LINE_TOP,
73                 ///
74                 M_TOGGLE_LINE_BOTTOM,
75                 ///
76                 M_TOGGLE_LINE_LEFT,
77                 ///
78                 M_TOGGLE_LINE_RIGHT,
79                 ///
80                 M_ALIGN_LEFT,
81                 ///
82                 M_ALIGN_RIGHT,
83                 ///
84                 M_ALIGN_CENTER,
85                 ///
86                 M_VALIGN_TOP,
87                 ///
88                 M_VALIGN_BOTTOM,
89                 ///
90                 M_VALIGN_CENTER,
91                 ///
92                 MULTICOLUMN,
93                 ///
94                 SET_ALL_LINES,
95                 ///
96                 UNSET_ALL_LINES,
97                 ///
98                 SET_LONGTABULAR,
99                 ///
100                 UNSET_LONGTABULAR,
101                 ///
102                 SET_PWIDTH,
103                 ///
104                 SET_MPWIDTH,
105                 ///
106                 SET_ROTATE_TABULAR,
107                 ///
108                 UNSET_ROTATE_TABULAR,
109                 ///
110                 SET_ROTATE_CELL,
111                 ///
112                 UNSET_ROTATE_CELL,
113                 ///
114                 SET_USEBOX,
115                 ///
116                 SET_LTHEAD,
117                 UNSET_LTHEAD,
118                 ///
119                 SET_LTFIRSTHEAD,
120                 UNSET_LTFIRSTHEAD,
121                 ///
122                 SET_LTFOOT,
123                 UNSET_LTFOOT,
124                 ///
125                 SET_LTLASTFOOT,
126                 UNSET_LTLASTFOOT,
127                 ///
128                 SET_LTNEWPAGE,
129                 ///
130                 SET_SPECIAL_COLUMN,
131                 ///
132                 SET_SPECIAL_MULTI,
133                 ///
134                 LAST_ACTION
135         };
136         ///
137         enum {
138                 ///
139                 CELL_NORMAL = 0,
140                 ///
141                 CELL_BEGIN_OF_MULTICOLUMN,
142                 ///
143                 CELL_PART_OF_MULTICOLUMN
144         };
145
146         ///
147         enum VAlignment {
148                 ///
149                 LYX_VALIGN_TOP = 0,
150                 ///
151                 LYX_VALIGN_BOTTOM = 1,
152                 ///
153                 LYX_VALIGN_CENTER = 2
154         };
155
156         enum BoxType {
157                 ///
158                 BOX_NONE = 0,
159                 ///
160                 BOX_PARBOX = 1,
161                 ///
162                 BOX_MINIPAGE = 2
163         };
164
165         struct lttype {
166                 // constructor
167                 lttype();
168                 // we have this header type (is set in the GetLT... functions)
169                 bool set;
170                 // double borders on top
171                 bool topDL;
172                 // double borders on bottom
173                 bool bottomDL;
174                 // used for FirstHeader & LastFooter and if this is true
175                 // all the rows marked as FirstHeader or LastFooter are
176                 // ignored in the output and it is set to be empty!
177                 bool empty;
178         };
179         ///
180         typedef struct lttype ltType;
181
182         /* konstruktor */
183         ///
184         LyXTabular(BufferParams const &,
185                    InsetTabular *, int columns_arg, int rows_arg);
186         ///
187         LyXTabular(BufferParams const &,
188                    InsetTabular *, LyXTabular const &, bool same_id = false);
189         ///
190         explicit
191         LyXTabular(Buffer const *, InsetTabular *, LyXLex & lex);
192         ///
193         LyXTabular & operator=(LyXTabular const &);
194         ///
195         LyXTabular * clone(BufferParams const &,
196                            InsetTabular *, bool same_id = false);
197
198         /// Returns true if there is a topline, returns false if not
199         bool TopLine(int cell, bool onlycolumn = false) const;
200         /// Returns true if there is a topline, returns false if not
201         bool BottomLine(int cell, bool onlycolumn = false) const;
202         /// Returns true if there is a topline, returns false if not
203         bool LeftLine(int cell, bool onlycolumn = false) const;
204         /// Returns true if there is a topline, returns false if not
205         bool RightLine(int cell, bool onlycolumn = false) const;
206
207         ///
208         bool TopAlreadyDrawed(int cell) const;
209         ///
210         bool LeftAlreadyDrawed(int cell) const;
211         ///
212         bool IsLastRow(int cell) const;
213
214         ///
215         int GetAdditionalHeight(int row) const;
216         ///
217         int GetAdditionalWidth(int cell) const;
218
219         /* returns the maximum over all rows */
220         ///
221         int GetWidthOfColumn(int cell) const;
222         ///
223         int GetWidthOfTabular() const;
224         ///
225         int GetAscentOfRow(int row) const;
226         ///
227         int GetDescentOfRow(int row) const;
228         ///
229         int GetHeightOfTabular() const;
230         /// Returns true if a complete update is necessary, otherwise false
231         bool SetAscentOfRow(int row, int height);
232         /// Returns true if a complete update is necessary, otherwise false
233         bool SetDescentOfRow(int row, int height);
234         /// Returns true if a complete update is necessary, otherwise false
235         bool SetWidthOfCell(int cell, int new_width);
236         /// Returns true if a complete update is necessary, otherwise false
237         bool SetAllLines(int cell, bool line);
238         /// Returns true if a complete update is necessary, otherwise false
239         bool SetTopLine(int cell, bool line, bool onlycolumn = false);
240         /// Returns true if a complete update is necessary, otherwise false
241         bool SetBottomLine(int cell, bool line, bool onlycolumn = false);
242         /// Returns true if a complete update is necessary, otherwise false
243         bool SetLeftLine(int cell, bool line, bool onlycolumn = false);
244         /// Returns true if a complete update is necessary, otherwise false
245         bool SetRightLine(int cell, bool line, bool onlycolumn = false);
246         /// Returns true if a complete update is necessary, otherwise false
247         bool SetAlignment(int cell, LyXAlignment align,
248                           bool onlycolumn = false);
249         /// Returns true if a complete update is necessary, otherwise false
250         bool SetVAlignment(int cell, VAlignment align,
251                            bool onlycolumn = false);
252         ///
253         bool SetColumnPWidth(int cell, LyXLength const & width);
254         ///
255         bool SetMColumnPWidth(int cell, LyXLength const & width);
256         ///
257         bool SetAlignSpecial(int cell, string const & special, Feature what);
258         ///
259         LyXAlignment GetAlignment(int cell, bool onlycolumn = false) const;
260         ///
261         VAlignment GetVAlignment(int cell, bool onlycolumn = false) const;
262         ///
263         LyXLength const GetPWidth(int cell) const;
264         ///
265         LyXLength const GetColumnPWidth(int cell) const;
266         ///
267         LyXLength const GetMColumnPWidth(int cell) const;
268         ///
269         string const GetAlignSpecial(int cell, int what) const;
270         ///
271         int GetWidthOfCell(int cell) const;
272         ///
273         int GetBeginningOfTextInCell(int cell) const;
274         ///
275         void AppendRow(BufferParams const &, int cell);
276         ///
277         void DeleteRow(int row);
278         ///
279         void AppendColumn(BufferParams const &, int cell);
280         ///
281         void DeleteColumn(int column);
282         ///
283         bool IsFirstCellInRow(int cell) const;
284         ///
285         int GetFirstCellInRow(int row) const;
286         ///
287         bool IsLastCellInRow(int cell) const;
288         ///
289         int GetLastCellInRow(int row) const;
290         ///
291         int GetNumberOfCells() const;
292         ///
293         int NumberOfCellsInRow(int cell) const;
294         ///
295         void Write(Buffer const *, std::ostream &) const;
296         ///
297         void Read(Buffer const *, LyXLex &);
298         ///
299         void OldFormatRead(BufferParams const &, LyXLex &, string const &);
300         ///
301         int latex(Buffer const *, std::ostream &, bool, bool) const;
302         ///
303         int docbook(Buffer const * buf, std::ostream & os, bool mixcont) const;
304         ///
305         int ascii(Buffer const *, std::ostream &, int const depth,
306                   bool onlydata, unsigned char delim) const;
307         ///
308         bool IsMultiColumn(int cell, bool real = false) const;
309         ///
310         void SetMultiColumn(Buffer const *, int cell, int number);
311         ///
312         int UnsetMultiColumn(int cell); // returns number of new cells
313         ///
314         bool IsPartOfMultiColumn(int row, int column) const;
315         ///
316         int row_of_cell(int cell) const;
317         ///
318         int column_of_cell(int cell) const;
319         ///
320         int right_column_of_cell(int cell) const;
321         ///
322         void SetLongTabular(bool);
323         ///
324         bool IsLongTabular() const;
325         ///
326         void SetRotateTabular(bool);
327         ///
328         bool GetRotateTabular() const;
329         ///
330         void SetRotateCell(int cell, bool);
331         ///
332         bool GetRotateCell(int cell) const;
333         ///
334         bool NeedRotating() const;
335         ///
336         bool IsLastCell(int cell) const;
337         ///
338         int GetCellAbove(int cell) const;
339         ///
340         int GetCellBelow(int cell) const;
341         ///
342         int GetLastCellAbove(int cell) const;
343         ///
344         int GetLastCellBelow(int cell) const;
345         ///
346         int GetCellNumber(int row, int column) const;
347         ///
348         void SetUsebox(int cell, BoxType);
349         ///
350         BoxType GetUsebox(int cell) const;
351         //
352         // Long Tabular Options support functions
353         ///
354         bool checkLTType(int row, ltType const &) const;
355         ///
356         void SetLTHead(int row, bool flag, ltType const &, bool first);
357         ///
358         bool GetRowOfLTHead(int row, ltType &) const;
359         ///
360         bool GetRowOfLTFirstHead(int row, ltType &) const;
361         ///
362         void SetLTFoot(int row, bool flag, ltType const &, bool last);
363         ///
364         bool GetRowOfLTFoot(int row, ltType &) const;
365         ///
366         bool GetRowOfLTLastFoot(int row, ltType &) const;
367         ///
368         void SetLTNewPage(int row, bool what);
369         ///
370         bool GetLTNewPage(int row) const;
371         ///
372         bool haveLTHead() const;
373         ///
374         bool haveLTFirstHead() const;
375         ///
376         bool haveLTFoot() const;
377         ///
378         bool haveLTLastFoot() const;
379         ///
380         // end longtable support
381         ///
382         InsetText * GetCellInset(int cell) const;
383         ///
384         InsetText * GetCellInset(int row, int column) const;
385         /// Search for \param inset in the tabular, with the
386         /// additional hint that it could be at \param maybe_cell
387         int GetCellFromInset(Inset const * inset, int maybe_cell = -1) const;
388         ///
389         int rows() const { return rows_; }
390         ///
391         int columns() const { return columns_;}
392         ///
393         InsetTabular * owner() const { return owner_; }
394         ///
395         void Validate(LaTeXFeatures &) const;
396         ///
397         std::vector<string> const getLabelList() const;
398         ///
399         /// recalculate the widths/heights only!
400         void reinit();
401         ///
402         mutable int cur_cell;
403 private:
404         ///
405         struct cellstruct {
406                 ///
407                 cellstruct(BufferParams const &);
408                 ///
409                 int cellno;
410                 ///
411                 int width_of_cell;
412                 ///
413                 int multicolumn;
414                 ///
415                 LyXAlignment alignment;
416                 ///
417                 VAlignment valignment;
418                 ///
419                 bool top_line;
420                 ///
421                 bool bottom_line;
422                 ///
423                 bool left_line;
424                 ///
425                 bool right_line;
426                 ///
427                 BoxType usebox;
428                 ///
429                 bool rotate;
430                 ///
431                 string align_special;
432                 ///
433                 LyXLength p_width; // this is only set for multicolumn!!!
434                 ///
435                 InsetText inset;
436         };
437         ///
438         typedef std::vector<cellstruct> cell_vector;
439         ///
440         typedef std::vector<cell_vector> cell_vvector;
441
442         ///
443         struct rowstruct {
444                 ///
445                 rowstruct();
446                 ///
447                 int ascent_of_row;
448                 ///
449                 int descent_of_row;
450                 ///
451                 bool top_line;
452                 ///
453                 bool bottom_line;
454                 /// This are for longtabulars only
455                 /// a row of endhead
456                 bool endhead;
457                 /// a row of endfirsthead
458                 bool endfirsthead;
459                 /// a row of endfoot
460                 bool endfoot;
461                 /// row of endlastfoot
462                 bool endlastfoot;
463                 /// row for a pagebreak
464                 bool newpage;
465         };
466         ///
467         typedef std::vector<rowstruct> row_vector;
468
469         ///
470         struct columnstruct {
471                 ///
472                 columnstruct();
473                 ///
474                 LyXAlignment alignment;
475                 ///
476                 VAlignment valignment;
477                 ///
478                 bool left_line;
479                 ///
480                 bool right_line;
481                 ///
482                 int  width_of_column;
483                 ///
484                 LyXLength p_width;
485                 ///
486                 string align_special;
487         };
488         ///
489         typedef std::vector<columnstruct> column_vector;
490
491         ///
492         void ReadNew(Buffer const * buf, std::istream & is,
493                                  LyXLex & lex, string const & l, int const version);
494         ///
495         void ReadOld(Buffer const * buf, std::istream & is,
496                                  LyXLex & lex, string const & l);
497         ///
498         int rows_;
499         ///
500         int columns_;
501         ///
502         int numberofcells;
503         ///
504         std::vector<int> rowofcell;
505         ///
506         std::vector<int> columnofcell;
507         ///
508         row_vector row_info;
509         ///
510         column_vector column_info;
511         ///
512         mutable cell_vvector cell_info;
513         ///
514         int width_of_tabular;
515         ///
516         bool rotate;
517         //
518         // for long tabulars
519         //
520         bool is_long_tabular;
521         /// endhead data
522         ltType endhead;
523         /// endfirsthead data
524         ltType endfirsthead;
525         /// endfoot data
526         ltType endfoot;
527         /// endlastfoot data
528         ltType endlastfoot;
529         //
530         ///
531         InsetTabular * owner_;
532
533         ///
534         void Init(BufferParams const &,
535                   int columns_arg, int rows_arg, LyXTabular const * lt = 0);
536         ///
537         void Reinit(bool reset_widths = true);
538         ///
539         void set_row_column_number_info(bool oldformat = false);
540         /// Returns true if a complete update is necessary, otherwise false
541         bool SetWidthOfMulticolCell(int cell, int new_width);
542         ///
543         void recalculateMulticolumnsOfColumn(int column);
544         /// Returns true if change
545         bool calculate_width_of_column(int column);
546         ///
547         bool calculate_width_of_column_NMC(int column); // no multi cells
548         ///
549         void calculate_width_of_tabular();
550         ///
551         cellstruct * cellinfo_of_cell(int cell) const;
552         ///
553         void delete_column(int column);
554         ///
555         int cells_in_multicolumn(int cell) const;
556         ///
557         BoxType UseParbox(int cell) const;
558         ///
559         void setHeaderFooterRows(int header, int fheader, int footer, int lfooter);
560         ///
561         // helper function for Latex returns number of newlines
562         ///
563         int TeXTopHLine(std::ostream &, int row) const;
564         ///
565         int TeXBottomHLine(std::ostream &, int row) const;
566         ///
567         int TeXCellPreamble(std::ostream &, int cell) const;
568         ///
569         int TeXCellPostamble(std::ostream &, int cell) const;
570         ///
571         int TeXLongtableHeaderFooter(std::ostream &, Buffer const * buf,
572                                      bool fragile, bool fp) const;
573         ///
574         bool isValidRow(int const row) const;
575         ///
576         int TeXRow(std::ostream &, int const row, Buffer const * buf,
577                    bool fragile, bool fp) const;
578         ///
579         // helper function for ASCII returns number of newlines
580         ///
581         int asciiTopHLine(std::ostream &, int row,
582                           std::vector<unsigned int> const &) const;
583         ///
584         int asciiBottomHLine(std::ostream &, int row,
585                              std::vector<unsigned int> const &) const;
586         ///
587         int asciiPrintCell(Buffer const *, std::ostream &,
588                            int cell, int row, int column,
589                            std::vector<unsigned int> const &,
590                                            bool onlydata) const;
591         /// auxiliary function for docbook
592         int docbookRow(Buffer const * buf, std::ostream & os, int row) const;
593 };
594
595 #endif