]> git.lyx.org Git - lyx.git/blob - src/insets/insetcommand.C
some small updates to Painter, and make the new painter the default.
[lyx.git] / src / insets / insetcommand.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1995 Matthias Ettrich
7  *          Copyright 1995-1999 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "insetcommand.h"
18 #ifndef USE_PAINTER
19 #include "lyxdraw.h"
20 #endif
21 #include "debug.h"
22 #include "Painter.h"
23
24 InsetCommand::InsetCommand()
25 {
26 }
27
28
29 InsetCommand::InsetCommand(string const & cmd, string const & arg, 
30                            string const & opt)
31         : command(cmd), options(opt), contents(arg)
32 {
33 }
34
35
36 #ifdef USE_PAINTER
37 int InsetCommand::ascent(Painter &, LyXFont const & font) const
38 {
39         LyXFont f = font;
40         f.decSize();
41         return f.maxAscent() + 3;
42 }
43 #else
44 int InsetCommand::Ascent(LyXFont const & font) const
45 {
46         LyXFont f = font;
47         f.decSize();
48         return f.maxAscent() + 3;
49 }
50 #endif
51
52
53 #ifdef USE_PAINTER
54 int InsetCommand::descent(Painter &, LyXFont const & font) const
55 {
56         LyXFont f = font;
57         f.decSize();
58         return f.maxDescent() + 3;
59 }
60 #else
61 int InsetCommand::Descent(LyXFont const & font) const
62 {
63         LyXFont f = font;
64         f.decSize();
65         return f.maxDescent() + 3;
66 }
67 #endif
68
69
70 #ifdef USE_PAINTER
71 int InsetCommand::width(Painter &, LyXFont const & font) const
72 {
73         LyXFont f = font;
74         f.decSize();
75         string s = getScreenLabel();
76         return 10 + f.stringWidth(s);
77 }
78 #else
79 int InsetCommand::Width(LyXFont const & font) const
80 {
81         LyXFont f = font;
82         f.decSize();
83         string s = getScreenLabel();
84         return 10 + f.stringWidth(s);
85 }
86 #endif
87
88
89 #ifdef USE_PAINTER
90 void InsetCommand::draw(Painter & pain, LyXFont const & font,
91                         int baseline, float & x) const
92 {
93         // Draw it as a box with the LaTeX text
94         x += 3;
95
96         pain.fillRectangle(int(x), baseline - ascent(pain, font) + 1,
97                            width(pain, font) - 6,
98                            ascent(pain, font) + descent(pain, font) - 2,
99                            LColor::insetbg);
100         // Tell whether this slows down the drawing  (ale)
101         // lets draw editable and non-editable insets differently
102         if (Editable()) {
103                 int y = baseline - ascent(pain, font) + 1;
104                 int w = width(pain, font) - 6;
105                 int h = ascent(pain, font) + descent(pain, font) - 2;
106                 pain.rectangle(int(x), y, w, h, LColor::insetframe);
107         } else {
108                 
109                 pain.rectangle(int(x), baseline - ascent(pain, font) + 1,
110                                width(pain, font) - 6,
111                                ascent(pain, font) + descent(pain, font) - 2,
112                                LColor::insetframe); 
113         }
114         string s = getScreenLabel();
115         LyXFont f(font);
116         f.decSize();
117         f.setColor(LColor::none);
118         f.setLatex(LyXFont::OFF);
119         pain.text(int(x + 2), baseline, s, f);
120         
121         x +=  width(pain, font) - 3;
122 }
123 #else
124 void InsetCommand::Draw(LyXFont font, LyXScreen & scr,
125                       int baseline, float & x)
126 {
127         // Draw it as a box with the LaTeX text
128         x += 3;
129
130         scr.fillRectangle(gc_lighted,
131                           int(x), baseline - Ascent(font) + 1,
132                           Width(font) - 6,
133                           Ascent(font) + Descent(font)-2);
134         // Tell whether this slows down the drawing  (ale)
135         // lets draw editable and non-editable insets differently
136         if (Editable()) {
137                 int y = baseline - Ascent(font)+1, w = Width(font)-6,
138                         h = (Ascent(font)+Descent(font)-2);
139                 scr.drawFrame(FL_UP_FRAME, int(x), y, w, h, FL_BLACK, -1);
140         } else {
141                 scr.drawRectangle(gc_note_frame,
142                                   int(x), baseline - Ascent(font)+1,
143                                   Width(font)-6,
144                                   Ascent(font)+Descent(font)-2); 
145         }
146         string s = getScreenLabel();
147         LyXFont f = font;
148         f.decSize();
149         f.setColor(LyXFont::NONE);
150         f.setLatex(LyXFont::OFF);
151         scr.drawString(f, s, baseline, int(x+2));
152
153         x +=  Width(font) - 3;
154 }
155 #endif
156
157
158 // In lyxf3 this will be just LaTeX
159 void InsetCommand::Write(ostream & os)
160 {
161         os << "LatexCommand " << getCommand() << "\n";
162 }
163
164
165 void InsetCommand::scanCommand(string const & cmd)
166 {
167         string tcommand, toptions, tcontents;
168
169         if (cmd.empty()) return;
170
171         enum { WS, Command, Option, Content } state = WS;
172         
173         // Used to handle things like \command[foo[bar]]{foo{bar}}
174         int nestdepth = 0;
175
176         for (string::size_type i = 0; i < cmd.length(); ++i) {
177                 char c = cmd[i];
178                 if ((state == Command && c == ' ') ||
179                     (state == Command && c == '[') ||
180                     (state == Command && c == '{')) {
181                         state = WS;
182                 }
183                 if ((state == Option  && c == ']') ||
184                     (state == Content && c == '}')) {
185                         if (nestdepth == 0) {
186                                 state = WS;
187                         } else {
188                                 --nestdepth;
189                         }
190                 }
191                 if ((state == Option  && c == '[') ||
192                     (state == Content && c == '{')) {
193                         ++nestdepth;
194                 }
195                 switch (state) {
196                 case Command:   tcommand += c; break;
197                 case Option:    toptions += c; break;
198                 case Content:   tcontents += c; break;
199                 case WS:
200                         if (c == '\\') {
201                                 state = Command;
202                         } else if (c == '[') {
203                                 state = Option;
204                                 nestdepth = 0; // Just to be sure
205                         } else if (c == '{') {
206                                 state = Content;
207                                 nestdepth = 0; // Just to be sure
208                         }
209                         break;
210                 }
211         }
212
213         // Don't mess with this.
214         if (!tcommand.empty()) command = tcommand;
215         if (!toptions.empty()) options = toptions;
216         if (!tcontents.empty()) setContents(tcontents); 
217                         // setContents is overloaded in InsetInclude
218
219         if (lyxerr.debugging(Debug::PARSER))
220                 lyxerr << "Command <" <<  cmd
221                        << "> == <" << getCommand()
222                        << "> == <" << getCmdName()
223                        << '|' << getContents()
224                        << '|' << getOptions() << '>' << endl;
225 }
226
227
228 // This function will not be necessary when lyx3
229 void InsetCommand::Read(LyXLex & lex)
230 {    
231         if (lex.EatLine()) {
232                 string t = lex.GetString();
233                 scanCommand(t);
234         } else
235                 lex.printError("InsetCommand: Parse error: `$$Token'");
236 }
237
238
239 int InsetCommand::Latex(ostream & os, signed char /*fragile*/)
240 {
241         os << getCommand();
242         return 0;
243 }
244
245
246 int InsetCommand::Latex(string & file, signed char /*fragile*/)
247 {
248         file += getCommand();
249         return 0;
250 }
251
252
253 int InsetCommand::Linuxdoc(string &/*file*/)
254 {
255         return 0;
256 }
257
258
259 int InsetCommand::DocBook(string &/*file*/)
260 {
261         return 0;
262 }
263
264
265 Inset * InsetCommand::Clone() const
266 {
267         return new InsetCommand(command, contents, options);
268 }
269
270
271 string InsetCommand::getCommand() const
272 {       
273         string s;
274         if (!command.empty()) s += "\\"+command;
275         if (!options.empty()) s += "["+options+']';
276         s += "{"+contents+'}';
277         return s;
278 }