]> git.lyx.org Git - lyx.git/blob - src/paragraph_pimpl.h
The big change tracking patch. Changes from posted version :
[lyx.git] / src / paragraph_pimpl.h
1 // -*- C++ -*-
2 /**
3  * \file paragraph_pimpl.h
4  * Copyright 1995-2002 the LyX Team
5  * Read the file COPYING
6  */
7
8 #ifndef PARAGRAPH_PIMPL_H
9 #define PARAGRAPH_PIMPL_H
10
11 #ifdef __GNUG__
12 #pragma interface
13 #endif
14
15 #include "paragraph.h"
16 #include "ParagraphParameters.h"
17 #include "changes.h"
18 #include "counters.h"
19
20 #include <boost/scoped_ptr.hpp>
21  
22 class LyXLayout;
23
24 struct Paragraph::Pimpl {
25         ///
26         typedef std::vector<value_type> TextContainer;
27
28         ///
29         Pimpl(Paragraph * owner);
30         /// Copy constructor
31         Pimpl(Pimpl const &, Paragraph * owner, bool same_ids = false);
32         ///
33         lyx::pos_type size() const {
34                 return text.size();
35         }
36         ///
37         bool empty() const {
38                 return text.empty();
39         }
40         ///
41         void clear();
42         ///
43         void setContentsFromPar(Paragraph const * par);
44         /// set tracking mode
45         void trackChanges(Change::Type type = Change::UNCHANGED);
46         /// stop tracking
47         void untrackChanges();
48         /// set all text as new for change mode
49         void cleanChanges();
50         /// look up change type at given pos
51         Change::Type lookupChange(lyx::pos_type pos) const;
52         /// look up change at given pos
53         Change const lookupChangeFull(lyx::pos_type pos) const;
54         /// is there a change in the given range ?
55         bool isChanged(lyx::pos_type start, lyx::pos_type end) const;
56         /// is there a non-addition in this range ?
57         bool isChangeEdited(lyx::pos_type start, lyx::pos_type end) const;
58  
59         /// set change at pos
60         void setChange(lyx::pos_type pos, Change::Type type);
61  
62         /// mark as erased
63         void markErased();
64  
65         /// accept change
66         void acceptChange(lyx::pos_type start, lyx::pos_type end);
67
68         /// reject change
69         void rejectChange(lyx::pos_type start, lyx::pos_type end);
70  
71         /// are we tracking changes ?
72         bool tracking() const {
73                 return changes_.get();
74         }
75  
76         ///
77         value_type getChar(lyx::pos_type pos) const;
78         ///
79         void setChar(lyx::pos_type pos, value_type c);
80         ///
81         void insertChar(lyx::pos_type pos, value_type c, LyXFont const & font, Change change = Change(Change::INSERTED));
82         ///
83         void insertInset(lyx::pos_type pos, Inset * inset, LyXFont const & font, Change change = Change(Change::INSERTED));
84         /// definite erase
85         void eraseIntern(lyx::pos_type pos);
86         /// erase the given position
87         void erase(lyx::pos_type pos);
88         /// erase the given range
89         bool erase(lyx::pos_type start, lyx::pos_type end);
90         ///
91         LyXFont const realizeFont(LyXFont const & font,
92                                   BufferParams const & bparams) const;
93         ///
94         Inset * inset_owner;
95
96         /** A font entry covers a range of positions. Notice that the
97             entries in the list are inserted in random order.
98             I don't think it's worth the effort to implement a more effective
99             datastructure, because the number of different fonts in a paragraph
100             is limited. (Asger)
101             Nevertheless, I decided to store fontlist using a sorted vector:
102             fontlist = { {pos_1,font_1} , {pos_2,font_2} , ... } where
103             pos_1 < pos_2 < ..., font_{i-1} != font_i for all i,
104             and font_i covers the chars in positions pos_{i-1}+1,...,pos_i
105             (font_1 covers the chars 0,...,pos_1) (Dekel)
106         */
107         struct FontTable  {
108                 ///
109                 FontTable(lyx::pos_type p, LyXFont const & f)
110                         : pos_(p)
111                         {
112                                 font_ = container.get(f);
113                         }
114                 ///
115                 lyx::pos_type pos() const { return pos_; }
116                 ///
117                 void pos(lyx::pos_type p) { pos_ = p; }
118                 ///
119                 LyXFont const & font() const { return *font_; }
120                 ///
121                 void font(LyXFont const & f) { font_ = container.get(f);}
122         private:
123                 /// End position of paragraph this font attribute covers
124                 lyx::pos_type pos_;
125                 /** Font. Interpretation of the font values:
126                     If a value is LyXFont::INHERIT_*, it means that the font
127                     attribute is inherited from either the layout of this
128                     paragraph or, in the case of nested paragraphs, from the
129                     layout in the environment one level up until completely
130                     resolved.
131                     The values LyXFont::IGNORE_* and LyXFont::TOGGLE are NOT
132                     allowed in these font tables.
133                 */
134                 boost::shared_ptr<LyXFont> font_;
135                 ///
136                 static ShareContainer<LyXFont> container;
137         };
138         ///
139         friend struct matchFT;
140         ///
141         struct matchFT {
142                 /// used by lower_bound and upper_bound
143                 inline
144                 int operator()(FontTable const & a, FontTable const & b) const {
145                         return a.pos() < b.pos();
146                 }
147         };
148
149         ///
150         typedef std::vector<FontTable> FontList;
151         ///
152         FontList fontlist;
153
154         ///
155         Paragraph * TeXDeeper(Buffer const *, BufferParams const &,
156                                  std::ostream &, TexRow & texrow);
157         ///
158         void simpleTeXBlanks(std::ostream &, TexRow & texrow,
159                              lyx::pos_type const i,
160                              unsigned int & column,
161                              LyXFont const & font,
162                              LyXLayout const & style);
163         ///
164         void simpleTeXSpecialChars(Buffer const *, BufferParams const &,
165                                    std::ostream &, TexRow & texrow,
166                                    bool moving_arg,
167                                    LyXFont & font, LyXFont & running_font,
168                                    LyXFont & basefont, bool & open_font,
169                                    Change::Type & running_change,
170                                    LyXLayout const & style,
171                                    lyx::pos_type & i,
172                                    unsigned int & column, value_type const c);
173
174         ///
175         void validate(LaTeXFeatures & features,
176                       LyXLayout const & layout) const;
177
178         ///
179         Paragraph * getParFromID(int id) const;
180         ///
181         unsigned int id_;
182         ///
183         static unsigned int paragraph_id;
184         ///
185         ParagraphParameters params;
186
187 private:
188         /// erase at the given position. Returns true if it was actually erased
189         bool erasePos(lyx::pos_type pos);
190
191         /// match a string against a particular point in the paragraph
192         bool isTextAt(string const & str, lyx::pos_type pos) const;
193
194         /// for recording and looking up changes in revision tracking mode
195         boost::scoped_ptr<Changes> changes_;
196  
197         /// Who owns us?
198         Paragraph * owner_;
199         ///
200         TextContainer text;
201 };
202
203 #endif