]> git.lyx.org Git - lyx.git/blob - src/insets/insetspecialchar.C
Don't remove cell selections after fontchange.
[lyx.git] / src / insets / insetspecialchar.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1997 Asger Alstrup
7  *
8  * ====================================================== */
9
10 #include <config.h>
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 #include "insetspecialchar.h"
17 #include "debug.h"
18 #include "LaTeXFeatures.h"
19 #include "BufferView.h"
20 #include "Painter.h"
21 #include "font.h"
22 #include "lyxlex.h"
23 #include "lyxfont.h"
24
25 using std::ostream;
26 using std::max;
27
28 InsetSpecialChar::InsetSpecialChar(Kind k)
29         : kind_(k)
30 {}
31
32
33 InsetSpecialChar::Kind InsetSpecialChar::kind() const
34 {
35         return kind_;
36 }
37
38 int InsetSpecialChar::ascent(BufferView *, LyXFont const & font) const
39 {
40         return lyxfont::maxAscent(font);
41 }
42
43
44 int InsetSpecialChar::descent(BufferView *, LyXFont const & font) const
45 {
46         return lyxfont::maxDescent(font);
47 }
48
49
50 int InsetSpecialChar::width(BufferView *, LyXFont const & font) const
51 {
52         switch (kind_) {
53         case HYPHENATION:
54         {
55                 int w = lyxfont::width('-', font);
56                 if (w > 5) 
57                         w -= 2; // to make it look shorter
58                 return w;
59         }
60         case LIGATURE_BREAK:
61         {
62                 return lyxfont::width('|', font);
63         }
64         case END_OF_SENTENCE:
65         {
66                 return lyxfont::width('.', font);
67         }
68         case LDOTS:
69         {
70                 return lyxfont::width(". . .", font);
71         }
72         case MENU_SEPARATOR:
73         {
74                 return lyxfont::width(" x ", font);
75         }
76         case PROTECTED_SEPARATOR:
77         {
78                 return lyxfont::width('x', font);
79         }
80         
81         }
82         return 1; // To shut up gcc
83 }
84
85
86 void InsetSpecialChar::draw(BufferView * bv, LyXFont const & f,
87                             int baseline, float & x, bool) const
88 {
89         Painter & pain = bv->painter();
90         LyXFont font(f);
91
92         switch (kind_) {
93         case HYPHENATION:
94         {
95                 font.setColor(LColor::special);
96                 pain.text(int(x), baseline, "-", font);
97                 x += width(bv, font);
98                 break;
99         }
100         case LIGATURE_BREAK:
101         {
102                 font.setColor(LColor::special);
103                 pain.text(int(x), baseline, "|", font);
104                 x += width(bv, font);
105                 break;
106         }
107         case END_OF_SENTENCE:
108         {
109                 font.setColor(LColor::special);
110                 pain.text(int(x), baseline, ".", font);
111                 x += width(bv, font);
112                 break;
113         }
114         case LDOTS:
115         {
116                 font.setColor(LColor::special);
117                 pain.text(int(x), baseline, ". . .", font);
118                 x += width(bv, font);
119                 break;
120         }
121         case MENU_SEPARATOR:
122         {
123                 // A triangle the width and height of an 'x'
124                 int w = lyxfont::width('x', font);
125                 int ox = lyxfont::width(' ', font) + int(x);
126                 int h = lyxfont::ascent('x', font);
127                 int xp[4], yp[4];
128                 
129                 xp[0] = ox;     yp[0] = baseline;
130                 xp[1] = ox;     yp[1] = baseline - h;
131                 xp[2] = ox + w; yp[2] = baseline - h/2;
132                 xp[3] = ox;     yp[3] = baseline;
133                 
134                 pain.lines(xp, yp, 4, LColor::special);
135                 x += width(bv, font);
136                 break;
137         }
138         case PROTECTED_SEPARATOR:
139         {
140                 float w = width(bv, font);
141                 int h = lyxfont::ascent('x', font);
142                 int xp[4], yp[4];
143                 
144                 xp[0] = int(x);
145                 yp[0] = baseline - max(h / 4, 1);
146
147                 xp[1] = int(x);
148                 yp[1] = baseline;
149
150                 xp[2] = int(x + w);
151                 yp[2] = baseline;
152
153                 xp[3] = int(x + w);
154                 yp[3] = baseline - max(h / 4, 1);
155                 
156                 pain.lines(xp, yp, 4, LColor::special);
157                 x += w;
158                 break;
159         }
160         }
161 }
162
163
164 // In lyxf3 this will be just LaTeX
165 void InsetSpecialChar::write(Buffer const *, ostream & os) const
166 {
167         string command;
168         switch (kind_) {
169         case HYPHENATION:       
170                 command = "\\-";        
171                 break;
172         case LIGATURE_BREAK: 
173                 command = "\\textcompwordmark{}"; 
174                 break;
175         case END_OF_SENTENCE:   
176                 command = "\\@.";
177                 break;
178         case LDOTS:
179                 command = "\\ldots{}";  
180                 break;
181         case MENU_SEPARATOR:
182                 command = "\\menuseparator"; 
183                 break;
184         case PROTECTED_SEPARATOR:
185                 //command = "\\protected_separator";
186                 command = "~";
187                 break;
188         }
189         os << "\\SpecialChar " << command << "\n";
190 }
191
192
193 // This function will not be necessary when lyx3
194 void InsetSpecialChar::read(Buffer const *, LyXLex & lex)
195 {    
196         lex.nextToken();
197         string const command = lex.getString();
198
199         if (command == "\\-")
200                 kind_ = HYPHENATION;
201         else if (command == "\\textcompwordmark{}")
202                 kind_ = LIGATURE_BREAK;
203         else if (command == "\\@.")
204                 kind_ = END_OF_SENTENCE;
205         else if (command == "\\ldots{}")
206                 kind_ = LDOTS;
207         else if (command == "\\menuseparator")
208                 kind_ = MENU_SEPARATOR;
209         else if (command == "\\protected_separator"
210                  || command == "~")
211                 kind_ = PROTECTED_SEPARATOR;
212         else
213                 lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
214 }
215
216
217 int InsetSpecialChar::latex(Buffer const *, ostream & os, bool /*fragile*/,
218                             bool free_space) const
219 {
220         switch (kind_) {
221         case HYPHENATION:         
222                 os << "\\-";    
223                 break;
224         case LIGATURE_BREAK:
225                 os << "\\textcompwordmark{}";
226                 break;
227         case END_OF_SENTENCE:     
228                 os << "\\@.";   
229                 break;
230         case LDOTS:               
231                 os << "\\ldots{}";      
232                 break;
233         case MENU_SEPARATOR:      
234                 os << "\\lyxarrow{}"; 
235                 break;
236         case PROTECTED_SEPARATOR: 
237                 os << (free_space ? " " : "~"); 
238                 break;
239         }
240         return 0;
241 }
242
243
244 int InsetSpecialChar::ascii(Buffer const *, ostream & os, int) const
245 {
246         switch (kind_) {
247         case HYPHENATION:
248         case LIGATURE_BREAK:
249                 break;
250         case END_OF_SENTENCE:     
251                 os << ".";      
252                 break;
253         case LDOTS:               
254                 os << "...";    
255                 break;
256         case MENU_SEPARATOR:      
257                 os << "->";   
258                 break;
259         case PROTECTED_SEPARATOR: 
260                 os << " ";
261                 break;
262         }
263         return 0;
264 }
265
266
267 int InsetSpecialChar::linuxdoc(Buffer const *, ostream & os) const
268 {
269         switch (kind_) {
270         case HYPHENATION:
271         case LIGATURE_BREAK:
272                 break;
273         case END_OF_SENTENCE:
274                 os << ".";
275                 break;
276         case LDOTS:
277                 os << "...";    
278                 break;
279         case MENU_SEPARATOR:      
280                 os << "&lyxarrow;"; 
281                 break;
282         case PROTECTED_SEPARATOR:
283                 os << "&nbsp;";
284                 break;
285         }
286         return 0;
287 }
288
289
290 int InsetSpecialChar::docbook(Buffer const *, ostream & os) const
291 {
292         switch (kind_) {
293         case HYPHENATION:
294         case LIGATURE_BREAK:
295                 break;
296         case END_OF_SENTENCE:
297                 os << ".";
298                 break;
299         case LDOTS:
300                 os << "...";    
301                 break;
302         case MENU_SEPARATOR:
303                 os << "&lyxarrow;";
304                 break;
305         case PROTECTED_SEPARATOR:
306                 os << "&nbsp;";
307                 break;
308         }
309         return 0;
310 }
311
312
313 Inset * InsetSpecialChar::clone(Buffer const &, bool) const
314 {
315         return new InsetSpecialChar(kind_);
316 }
317
318
319 void InsetSpecialChar::validate(LaTeXFeatures & features) const
320 {
321         if (kind_ == MENU_SEPARATOR) {
322                 features.require("lyxarrow");
323         }
324 }
325
326
327 bool InsetSpecialChar::isChar() const
328 {
329         return true;
330 }
331
332
333 bool InsetSpecialChar::isLetter() const
334 {
335         return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK;
336 }
337
338
339 bool InsetSpecialChar::isSpace() const
340 {
341         return kind_ == PROTECTED_SEPARATOR;
342 }
343
344
345 bool InsetSpecialChar::isLineSeparator() const
346 {
347         return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR;
348 }