]> git.lyx.org Git - lyx.git/blob - src/lyxparagraph.h
more NEW_INSETS changes, define NEW_MANUBAR as default some other changes, read ChangeLog
[lyx.git] / src / lyxparagraph.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright 1995 Matthias Ettrich
8  *          Copyright 1995-2000 The LyX Team.
9  *
10  * ====================================================== */
11
12 #ifndef LYXPARAGRAPH_H
13 #define LYXPARAGRAPH_H
14
15 #ifdef __GNUG__
16 #pragma interface
17 #endif
18
19 #include <vector>
20 #include <list>
21
22 #include "insets/lyxinset.h"
23 #include "table.h"
24 #include "vspace.h"
25 #include "layout.h"
26 #include "support/block.h"
27 #include "language.h"
28
29 class BufferParams;
30 class LyXBuffer;
31 class TexRow;
32 struct LaTeXFeatures;
33 class InsetBibKey;
34 class BufferView;
35
36 // I dare you to enable this and help me find all the bugs that then show
37 // up. (Lgb)
38 //#define NEW_INSETS 1
39
40 // I dare you to try this one too. It is ortogonal with NEW_INSETS so you
41 // can try both or just one of them.
42 //#define NEW_TABULAR 1
43
44 /// A LyXParagraph holds all text, attributes and insets in a text paragraph
45 class LyXParagraph  {
46 public:
47         ///
48         enum PEXTRA_TYPE {
49                 ///
50                 PEXTRA_NONE,
51                 ///
52                 PEXTRA_INDENT,
53                 ///
54                 PEXTRA_MINIPAGE,
55                 ///
56                 PEXTRA_FLOATFLT
57         };
58         ///
59         enum MINIPAGE_ALIGNMENT {
60                 ///
61                 MINIPAGE_ALIGN_TOP,
62                 ///
63                 MINIPAGE_ALIGN_MIDDLE,
64                 ///
65                 MINIPAGE_ALIGN_BOTTOM
66         };
67         ///
68         enum META_KIND {
69 #ifndef NEW_INSETS
70                 ///
71                 META_FOOTNOTE = 1,
72                 ///
73                 META_MARGIN,
74                 ///
75                 META_FIG,
76                 ///
77                 META_TAB,
78                 ///
79                 META_ALGORITHM,
80                 ///
81                 META_WIDE_FIG,
82                 ///
83                 META_WIDE_TAB,
84                 ///
85                 META_HFILL,
86 #else
87                 ///
88                 META_HFILL = 1,
89 #endif
90                 ///
91                 META_NEWLINE,
92                 ///
93                 //META_PROTECTED_SEPARATOR,
94                 ///
95                 META_INSET
96         };
97 #ifndef NEW_INSETS
98
99         /// The footnoteflag
100         enum footnote_flag {
101                 ///
102                 NO_FOOTNOTE,
103                 ///
104                 OPEN_FOOTNOTE,
105                 ///
106                 CLOSED_FOOTNOTE
107         };
108
109         /// The footnotekinds
110         enum footnote_kind {
111                 ///
112                 FOOTNOTE,
113                 ///
114                 MARGIN,
115                 ///
116                 FIG,
117                 ///
118                 TAB,
119                 ///
120                 ALGORITHM,  // Bernhard, 970807
121                 ///
122                 WIDE_FIG,   // CFO-G, 971106
123                 ///
124                 WIDE_TAB    // CFO-G, 971106
125         };
126 #endif
127         ///
128         typedef char value_type;
129         ///
130         typedef std::vector<value_type> TextContainer;
131         ///
132         typedef int size_type;
133
134         ///
135         LyXParagraph();
136         /// this konstruktor inserts the new paragraph in a list
137         explicit
138         LyXParagraph(LyXParagraph * par);
139         /// the destruktors removes the new paragraph from the list
140         ~LyXParagraph();
141
142         ///
143         Language const * getParLanguage(BufferParams const &) const;
144         ///
145         bool isRightToLeftPar(BufferParams const &) const;
146         ///
147         void ChangeLanguage(BufferParams const & bparams,
148                             Language const * from, Language const * to);
149         ///
150         bool isMultiLingual(BufferParams const &);
151         ///
152
153         string String(Buffer const *, bool label);
154         ///
155         string String(Buffer const *, size_type beg, size_type end);
156         
157         ///
158         void writeFile(Buffer const *, std::ostream &, BufferParams const &,
159                        char, char) const;
160         ///
161         void validate(LaTeXFeatures &) const;
162         
163         ///
164         int id() const {
165                 return id_;
166         }
167         ///
168         void id(int id_arg) {
169                 id_ = id_arg;
170         }
171
172         ///
173         void read();
174
175         ///
176         LyXParagraph * TeXOnePar(Buffer const *, BufferParams const &,
177                                  std::ostream &, TexRow & texrow,
178                                  bool moving_arg
179 #ifndef NEW_INSETS
180                                  ,
181                                  std::ostream & foot, TexRow & foot_texrow,
182                                  int & foot_count
183 #endif
184                 );
185         ///
186         bool SimpleTeXOnePar(Buffer const *, BufferParams const &,
187                              std::ostream &, TexRow & texrow, bool moving_arg);
188
189         ///
190         LyXParagraph * TeXEnvironment(Buffer const *, BufferParams const &,
191                                       std::ostream &, TexRow & texrow
192 #ifndef NEW_INSETS
193                                       ,std::ostream & foot, TexRow & foot_texrow,
194                                       int & foot_count
195 #endif
196                 );
197         ///
198         LyXParagraph * Clone() const;
199         
200         ///
201         bool HasSameLayout(LyXParagraph const * par) const;
202         
203         ///
204         void MakeSameLayout(LyXParagraph const * par);
205
206         /// Is it the first par with same depth and layout?
207         bool IsFirstInSequence() const {
208                 LyXParagraph const * dhook = DepthHook(GetDepth());
209                 return (dhook == this
210                         || dhook->GetLayout() != GetLayout()
211                         || dhook->GetDepth() != GetDepth());
212         }
213
214         /** Check if the current paragraph is the last paragraph in a
215             proof environment */
216         int GetEndLabel(BufferParams const &) const;
217         ///
218         Inset * InInset() { return inset_owner; }
219         ///
220         void SetInsetOwner(Inset * i);
221         ///
222         void deleteInsetsLyXText(BufferView *);
223         void resizeInsetsLyXText(BufferView *);
224 private:
225         ///
226         TextContainer text;
227         ///
228         Inset * inset_owner;
229
230 public:
231         ///
232         size_type size() const { return text.size(); }
233         ///
234         void fitToSize() {
235                 text.resize(text.size());
236         }
237         ///
238         void setContentsFromPar(LyXParagraph * par) {
239                 text = par->text;
240         }
241         ///
242         void clearContents() {
243                 text.clear();
244         }
245         
246         /// 
247         VSpace added_space_top;
248         
249         /// 
250         VSpace added_space_bottom;
251
252         ///
253         Spacing spacing;
254         
255         ///
256         LyXTextClass::LayoutList::size_type layout;
257 #ifndef NEW_INSETS
258         /**
259           \begin{itemize}
260           \item no footnote, closed footnote, 
261           \item open footnote, where footnote
262           \item means footnote-environment
263           \end{itemize}
264          */
265         footnote_flag footnoteflag;
266
267         /// footnote, margin, fig, tab
268         footnote_kind footnotekind;
269 #endif
270         //@Man: the LyX- DTP-switches
271         //@{
272         ///
273         bool line_top;
274         
275         ///
276         bool line_bottom;
277         
278         ///
279         bool pagebreak_top;
280         
281         ///
282         bool pagebreak_bottom;
283         
284         ///
285         LyXAlignment align;
286         
287         ///
288         char depth;
289         
290         ///
291         bool noindent;
292         
293 private:
294         ///
295         block<int, 10> counter_;
296 public:
297         ///
298         void setCounter(int i, int v) { counter_[i] = v; }
299         int getCounter(int i) const { return counter_[i]; }
300         void incCounter(int i) { counter_[i]++; }
301         ///
302         bool start_of_appendix;
303
304         ///
305         bool appendix;
306
307         ///
308         char enumdepth;
309         
310         ///
311         char itemdepth;
312
313         /* This is for the paragraph extra stuff */
314         ///
315         int pextra_type;
316         ///
317         string pextra_width;
318         ///
319         string pextra_widthp;
320         ///
321         int pextra_alignment;
322         ///
323         bool pextra_hfill;
324         ///
325         bool pextra_start_minipage;
326         
327         ///
328         string labelstring;
329         
330         ///
331         string labelwidthstring;
332         //@}
333         
334         ///
335         LyXParagraph * next;
336         ///
337         LyXParagraph * previous;
338
339 #ifndef NEW_TABULAR
340         /* table stuff -- begin*/
341         ///
342         LyXTable * table;
343         /* table stuff -- end*/
344 #endif
345         /// 
346         InsetBibKey * bibkey;  // ale970302
347
348         /** these function are able to hide closed footnotes
349          */
350         LyXParagraph * Next();
351         
352         ///
353         LyXParagraph * Previous();
354         ///
355         LyXParagraph const * Previous() const;
356
357 #ifndef NEW_INSETS
358         /** these function are able to hide open and closed footnotes
359          */ 
360         LyXParagraph * NextAfterFootnote();
361         ///
362         LyXParagraph const * NextAfterFootnote() const;
363         
364         ///
365         LyXParagraph * PreviousBeforeFootnote();
366         ///
367         LyXParagraph * LastPhysicalPar();
368         ///
369         LyXParagraph const * LastPhysicalPar() const;
370         
371         ///
372         LyXParagraph * FirstPhysicalPar();
373         ///
374         LyXParagraph const * FirstPhysicalPar() const;
375         /// returns the physical paragraph
376         LyXParagraph * ParFromPos(size_type pos);
377         /// returns the position in the physical par
378         int PositionInParFromPos(size_type pos) const;
379 #endif
380
381         /// for the environments
382         LyXParagraph * DepthHook(int depth);
383         /// for the environments
384         LyXParagraph const * DepthHook(int depth) const;
385         ///
386         int BeginningOfMainBody() const;
387         ///
388         string const & GetLabelstring() const;
389         
390         /// the next two functions are for the manual labels
391         string GetLabelWidthString() const;
392         ///
393         void SetLabelWidthString(string const & s);
394         ///
395         LyXTextClass::LayoutList::size_type GetLayout() const;
396         ///
397         char GetAlign() const;
398         ///
399         char GetDepth() const;
400         ///
401         void SetLayout(BufferParams const &,
402                        LyXTextClass::LayoutList::size_type new_layout);
403         ///
404         void SetOnlyLayout(BufferParams const &,
405                            LyXTextClass::LayoutList::size_type new_layout);
406         ///
407         int GetFirstCounter(int i) const;
408         ///
409         size_type Last() const;
410         ///
411         void Erase(size_type pos);
412         /** the flag determines wether the layout should be copied
413          */ 
414         void BreakParagraph(BufferParams const &, size_type pos, int flag);
415         ///
416         void BreakParagraphConservative(BufferParams const &, size_type pos);
417         /** Get unistantiated font setting. Returns the difference
418           between the characters font and the layoutfont.
419           This is what is stored in the fonttable
420          */
421         LyXFont GetFontSettings(BufferParams const &, size_type pos) const;
422         ///
423         LyXFont GetFirstFontSettings() const;
424
425         /** Get fully instantiated font. If pos == -1, use the layout
426           font attached to this paragraph.
427           If pos == -2, use the label font of the layout attached here.
428           In all cases, the font is instantiated, i.e. does not have any
429           attributes with values LyXFont::INHERIT, LyXFont::IGNORE or 
430           LyXFont::TOGGLE.
431           */
432         LyXFont getFont(BufferParams const &, size_type pos) const;
433         ///
434         value_type GetChar(size_type pos) const;
435         /// The position must already exist.
436         void SetChar(size_type pos, value_type c) {
437                 text[pos] = c;
438         }
439         
440         ///
441         void SetFont(size_type pos, LyXFont const & font);
442         ///
443         string GetWord(size_type &) const;
444         /// Returns the height of the highest font in range
445         LyXFont::FONT_SIZE HighestFontInRange(size_type startpos,
446                                               size_type endpos) const;
447         ///
448         void InsertChar(size_type pos, value_type c);
449         ///
450         void InsertChar(size_type pos, value_type c, LyXFont const &);
451         ///
452         void InsertInset(size_type pos, Inset * inset);
453         ///
454         void InsertInset(size_type pos, Inset * inset, LyXFont const &);
455         ///
456         bool InsertInsetAllowed(Inset * inset);
457         ///
458         Inset * GetInset(size_type pos);
459         ///
460         Inset const * GetInset(size_type pos) const;
461 #ifndef NEW_INSETS
462         ///
463         void OpenFootnote(size_type pos);
464         ///
465         void CloseFootnote(size_type pos);
466 #endif
467         /// important for cut and paste
468         void CopyIntoMinibuffer(BufferParams const &, size_type pos) const;
469         ///
470         void CutIntoMinibuffer(BufferParams const &, size_type pos);
471         ///
472         bool InsertFromMinibuffer(size_type pos);
473
474         ///
475         bool IsHfill(size_type pos) const;
476         ///
477         bool IsInset(size_type pos) const;
478 #ifndef NEW_INSETS
479         ///
480         bool IsFloat(size_type pos) const;
481 #endif
482         ///
483         bool IsNewline(size_type pos) const;
484         ///
485         bool IsSeparator(size_type pos) const;
486         ///
487         bool IsLineSeparator(size_type pos) const;
488         ///
489         bool IsKomma(size_type pos) const;
490         /// Used by the spellchecker
491         bool IsLetter(size_type pos) const;
492         /// 
493         bool IsWord(size_type pos) const;
494
495         /** This one resets all layout and dtp switches but not the font
496          of the single characters
497          */ 
498         void Clear();
499
500         /** paste this paragraph with the next one
501           be carefull, this doesent make any check at all
502           */ 
503         void PasteParagraph(BufferParams const &);
504
505         /// used to remove the error messages
506         int AutoDeleteInsets();
507
508         /// returns -1 if inset not found
509         int GetPositionOfInset(Inset * inset) const;
510
511 #ifndef NEW_INSETS
512         /// ok and now some footnote functions
513         void OpenFootnotes();
514
515         ///
516         void CloseFootnotes();
517         ///
518         LyXParagraph * FirstSelfrowPar();
519 #endif
520
521         ///
522         int StripLeadingSpaces(LyXTextClassList::size_type tclass); 
523
524 #ifndef NEW_INSETS
525         /** A paragraph following a footnote is a "dummy". A paragraph
526           with a footnote in it is stored as three paragraphs:
527           First a paragraph with the text up to the footnote, then
528           one (or more) paragraphs with the footnote, and finally
529           the a paragraph with the text after the footnote. Only the
530           first paragraph keeps information  about layoutparameters, */
531         bool IsDummy() const;
532 #endif
533         /* If I set a PExtra Indent on one paragraph of a ENV_LIST-TYPE
534            I have to set it on each of it's elements */
535         ///
536         void SetPExtraType(BufferParams const &,
537                            int type, char const * width, char const * widthp);
538         ///
539         void UnsetPExtraType(BufferParams const &);
540         ///
541         bool linuxDocConvertChar(char c, string & sgml_string);
542 #ifndef NEW_TABULAR
543         ///
544         void DocBookContTableRows(Buffer const *,
545                                   std::ostream &, string & extra,
546                                   int & desc_on, size_type i,
547                                   int current_cell_number, int & column);
548         ///
549         void SimpleDocBookOneTablePar(Buffer const *,
550                                       std::ostream &, string & extra,
551                                       int & desc_on, int depth);
552 #endif
553 private:
554         ///
555         struct InsetTable {
556                 ///
557                 size_type pos;
558                 ///
559                 Inset * inset;
560                 ///
561                 InsetTable(size_type p, Inset * i) { pos = p; inset = i;}
562         };
563         ///
564         friend struct matchIT;
565         ///
566         struct matchIT {
567                 /// used by lower_bound and upper_bound
568                 inline
569                 int operator()(LyXParagraph::InsetTable const & a,
570                                LyXParagraph::InsetTable const & b) const {
571                         return a.pos < b.pos;
572                 }
573         };
574         /** A font entry covers a range of positions. Notice that the
575           entries in the list are inserted in random order.
576           I don't think it's worth the effort to implement a more effective
577           datastructure, because the number of different fonts in a paragraph
578           is limited. (Asger)
579           Nevertheless, I decided to store fontlist using a sorted vector:
580           fontlist = { {pos_1,font_1} , {pos_2,font_2} , ... } where
581           pos_1 < pos_2 < ..., font_{i-1} != font_i for all i,
582           and font_i covers the chars in positions pos_{i-1}+1,...,pos_i
583           (font_1 covers the chars 0,...,pos_1) (Dekel)
584         */
585         struct FontTable  {
586                 /// End position of paragraph this font attribute covers
587                 size_type pos;
588                 /** Font. Interpretation of the font values:
589                 If a value is LyXFont::INHERIT_*, it means that the font 
590                 attribute is inherited from either the layout of this
591                 paragraph or, in the case of nested paragraphs, from the 
592                 layout in the environment one level up until completely 
593                 resolved.
594                 The values LyXFont::IGNORE_* and LyXFont::TOGGLE are NOT 
595                 allowed in these font tables.
596                 */
597                 LyXFont font;
598                 ///
599                 FontTable(size_type p, LyXFont const & f) {pos = p; font = f;}
600         };
601         friend struct matchFT;
602         ///
603         struct matchFT {
604                 /// used by lower_bound and upper_bound
605                 inline
606                 int operator()(LyXParagraph::FontTable const & a,
607                                LyXParagraph::FontTable const & b) const {
608                         return a.pos < b.pos;
609                 }
610         };
611
612         ///
613         typedef std::vector<FontTable> FontList;
614         ///
615         FontList fontlist;
616         ///
617         typedef std::vector<InsetTable> InsetList;
618         ///
619         InsetList insetlist;
620         ///
621         LyXParagraph * TeXDeeper(Buffer const *, BufferParams const &,
622                                  std::ostream &, TexRow & texrow
623 #ifndef NEW_INSETS
624                                  ,std::ostream & foot, TexRow & foot_texrow,
625                                  int & foot_count
626 #endif
627                 );
628 #ifndef NEW_INSETS
629         ///
630         LyXParagraph * TeXFootnote(Buffer const *, BufferParams const &,
631                                    std::ostream &, TexRow & texrow,
632                                    std::ostream & foot, TexRow & foot_texrow,
633                                    int & foot_count,
634                                    bool parent_is_rtl);
635 #endif
636 #ifndef NEW_TABULAR
637         ///
638         bool SimpleTeXOneTablePar(Buffer const *, BufferParams const &,
639                                   std::ostream &, TexRow & texrow);
640         ///
641         bool TeXContTableRows(Buffer const *, BufferParams const &,
642                               std::ostream &, size_type i,
643                               int current_cell_number,
644                               int & column, TexRow & texrow);
645 #endif
646         ///
647         void SimpleTeXBlanks(std::ostream &, TexRow & texrow,
648                              size_type const i,
649                              int & column, LyXFont const & font,
650                              LyXLayout const & style);
651         ///
652         void SimpleTeXSpecialChars(Buffer const *, BufferParams const &,
653                                    std::ostream &, TexRow & texrow,
654                                    bool moving_arg,
655                                    LyXFont & font, LyXFont & running_font,
656                                    LyXFont & basefont, bool & open_font,
657                                    LyXLayout const & style,
658                                    size_type & i,
659                                    int & column, value_type const c);
660         ///
661         unsigned int id_;
662         ///
663         static unsigned int paragraph_id;
664 public:
665         class inset_iterator {
666         public:
667                 inset_iterator() {}
668                 inset_iterator(InsetList::iterator const & iter) : it(iter) {};
669                 inset_iterator & operator++() {
670                         ++it;
671                         return *this;
672                 }
673                 Inset * operator*() { return (*it).inset; }
674                 size_type getPos() {return (*it).pos; }
675                 bool operator==(inset_iterator const & iter) const {
676                         return it == iter.it;
677                 }
678                 bool operator!=(inset_iterator const & iter) const {
679                         return it != iter.it;
680                 }
681         private:
682                 InsetList::iterator it;
683         };
684         ///
685         inset_iterator inset_iterator_begin() {
686                 return inset_iterator(insetlist.begin());
687         }
688         ///
689         inset_iterator inset_iterator_end() {
690                 return inset_iterator(insetlist.end());
691         }
692         ///
693         inset_iterator InsetIterator(size_type pos);
694 };
695
696 #endif