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