]> git.lyx.org Git - lyx.git/blob - src/paragraph_funcs.C
fix crash
[lyx.git] / src / paragraph_funcs.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2001 The LyX Team. 
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #include "paragraph_funcs.h"
14 #include "buffer.h"
15 #include "ParagraphParameters.h"
16 #include "lyxtextclasslist.h"
17 #include "debug.h"
18
19 using lyx::pos_type;
20 //using lyx::layout_type;
21 using std::endl;
22
23
24 void breakParagraph(BufferParams const & bparams,
25                     Paragraph * par,
26                     pos_type pos,
27                     int flag)
28 {
29         // create a new paragraph
30         Paragraph * tmp = new Paragraph(par);
31         // without doing that we get a crash when typing <Return> at the
32         // end of a paragraph
33         tmp->layout(bparams.getLyXTextClass().defaultLayout());
34         // remember to set the inset_owner
35         tmp->setInsetOwner(par->inInset());
36         
37         // this is an idea for a more userfriendly layout handling, I will
38         // see what the users say
39         
40         // layout stays the same with latex-environments
41         if (flag) {
42                 tmp->layout(par->layout());
43                 tmp->setLabelWidthString(par->params().labelWidthString());
44         }
45
46         bool isempty = (par->layout()->keepempty && par->empty());
47         
48         if (!isempty && (par->size() > pos || par->empty() || flag == 2)) {
49                 tmp->layout(par->layout());
50                 tmp->params().align(par->params().align());
51                 tmp->setLabelWidthString(par->params().labelWidthString());
52                 
53                 tmp->params().lineBottom(par->params().lineBottom());
54                 par->params().lineBottom(false);
55                 tmp->params().pagebreakBottom(par->params().pagebreakBottom());
56                 par->params().pagebreakBottom(false);
57                 tmp->params().spaceBottom(par->params().spaceBottom());
58                 par->params().spaceBottom(VSpace(VSpace::NONE));
59                 
60                 tmp->params().depth(par->params().depth());
61                 tmp->params().noindent(par->params().noindent());
62                 
63                 // copy everything behind the break-position
64                 // to the new paragraph
65                 pos_type pos_end = par->size() - 1;
66                 pos_type i = pos;
67                 pos_type j = pos;
68                 for (; i <= pos_end; ++i) {
69                         par->cutIntoMinibuffer(bparams, i);
70                         if (tmp->insertFromMinibuffer(j - pos))
71                                 ++j;
72                 }
73                 for (i = pos_end; i >= pos; --i) {
74                         par->erase(i);
75                 }
76         }
77         
78         // just an idea of me
79         if (!pos) {
80                 tmp->params().lineTop(par->params().lineTop());
81                 tmp->params().pagebreakTop(par->params().pagebreakTop());
82                 tmp->params().spaceTop(par->params().spaceTop());
83                 tmp->bibkey = par->bibkey;
84
85                 par->bibkey = 0;
86                 par->params().clear();
87
88                 par->layout(bparams.getLyXTextClass().defaultLayout());
89                 
90                 // layout stays the same with latex-environments
91                 if (flag) {
92                         par->layout(tmp->layout());
93                         par->setLabelWidthString(tmp->params().labelWidthString());
94                         par->params().depth(tmp->params().depth());
95                 }
96         }
97 }
98
99
100 void breakParagraphConservative(BufferParams const & bparams,
101                                 Paragraph * par,
102                                 pos_type pos)
103 {
104         // create a new paragraph
105         Paragraph * tmp = new Paragraph(par);
106         tmp->makeSameLayout(par);
107
108         // When can pos > Last()?
109         // I guess pos == Last() is possible.
110         if (par->size() > pos) {
111                 // copy everything behind the break-position to the new
112                 // paragraph
113                 pos_type pos_end = par->size() - 1;
114
115                 for (pos_type i = pos, j = pos; i <= pos_end; ++i) {
116                         par->cutIntoMinibuffer(bparams, i);
117                         if (tmp->insertFromMinibuffer(j - pos))
118                                 ++j;
119                 }
120                 
121                 for (pos_type k = pos_end; k >= pos; --k) {
122                         par->erase(k);
123                 }
124         }
125 }
126
127
128 #if 0
129 // Be carefull, this does not make any check at all.
130 // This method has wrong name, it combined this par with the next par.
131 // In that sense it is the reverse of break paragraph. (Lgb)
132 void pasteParagraph(BufferParams const & bparams,
133                     Paragraph * par)
134 {
135         // copy the next paragraph to this one
136         Paragraph * the_next = par->next();
137
138         // first the DTP-stuff
139         par->params().lineBottom(the_next->params().lineBottom());
140         par->params().spaceBottom(the_next->params().spaceBottom());
141         par->params().pagebreakBottom(the_next->params().pagebreakBottom());
142
143         pos_type pos_end = the_next->size() - 1;
144         pos_type pos_insert = par->size();
145
146         // ok, now copy the paragraph
147         for (pos_type i = 0, j = 0; i <= pos_end; ++i) {
148                 the_next->cutIntoMinibuffer(bparams, i);
149                 if (par->insertFromMinibuffer(pos_insert + j))
150                         ++j;
151         }
152
153         // delete the next paragraph
154         Paragraph * ppar = the_next->previous();
155         Paragraph * npar = the_next->next();
156         delete the_next;
157         ppar->next(npar);
158 }
159
160
161 Paragraph * depthHook(Paragraph * par, Paragraph::depth_type depth)
162 {
163         Paragraph * newpar = par;
164
165         do {
166                 newpar = newpar->previous();
167         } while (newpar && newpar->getDepth() > depth);
168
169         if (!newpar) {
170                 if (par->previous() || par->getDepth())
171                         lyxerr << "Error (depthHook): "
172                                << "no hook." << endl;
173                 newpar = par;
174         }
175         return newpar;
176 }
177
178
179 Paragraph * outerHook(Paragraph * par) 
180 {
181         if (!par->getDepth())
182                 return 0;
183         return depthHook(par, Paragraph::depth_type(par->getDepth() - 1));
184 }
185
186
187 bool isFirstInSequence(Paragraph * par)
188 {
189         Paragraph const * dhook = depthHook(par, par->getDepth());
190         return (dhook == par
191                 || dhook->getLayout() != par->getLayout()
192                 || dhook->getDepth() != par->getDepth());
193 }
194
195
196 int getEndLabel(Paragraph * para, BufferParams const & bparams)
197 {
198         Paragraph * par = para;
199         while (par) {
200                 Paragraph::depth_type par_depth = par->getDepth();
201                 layout_type layout = par->getLayout();
202                 int const endlabeltype =
203                         textclasslist.Style(bparams.textclass,
204                                             layout).endlabeltype;
205                 if (endlabeltype != END_LABEL_NO_LABEL) {
206                         if (!para->next())
207                                 return endlabeltype;
208
209                         Paragraph::depth_type const next_depth =
210                                 para->next()->getDepth();
211                         if (par_depth > next_depth ||
212                             (par_depth == next_depth
213                              && layout != para->next()->getLayout()))
214                                 return endlabeltype;
215                         break;
216                 }
217                 if (par_depth == 0)
218                         break;
219                 par = outerHook(par);
220         }
221         return END_LABEL_NO_LABEL;
222 }
223 #endif