]> git.lyx.org Git - lyx.git/blob - src/mathed/formulamacro.C
make \newcommand{\bb}[1]{\mathbf{#1}} work for read/write/display.
[lyx.git] / src / mathed / formulamacro.C
1 /*
2  *  File:        formulamacro.C
3  *  Purpose:     Implementation of the formula macro LyX inset
4  *  Author:      André Pönitz, based on ideas of Alejandro Aguilar Sierra
5  *  Created:     March 2001
6  *  Description: Allows the edition of math macros inside Lyx. 
7  *
8  *  Copyright: 2001  The LyX Project
9  *
10  *   You are free to use and modify this code under the terms of
11  *   the GNU General Public Licence version 2 or later.
12  */
13
14 #include <config.h>
15
16 #ifdef __GNUG__
17 #pragma implementation
18 #endif
19
20 #include "formulamacro.h"
21 #include "commandtags.h"
22 #include "math_cursor.h"
23 #include "math_parser.h"
24 #include "math_macro.h"
25 #include "math_macrotable.h"
26 #include "math_support.h"
27 #include "math_mathmlstream.h"
28 #include "BufferView.h"
29 #include "gettext.h"
30 #include "Painter.h"
31 #include "font.h"
32 #include "support/lyxlib.h"
33 #include "support/LOstream.h"
34 #include "debug.h"
35 #include "lyxlex.h"
36 #include "lyxtext.h"
37 #include "lyxfont.h"
38
39 using std::ostream;
40
41 extern MathCursor * mathcursor;
42
43 InsetFormulaMacro::InsetFormulaMacro()
44 {
45         // inset name is inherited from Inset
46         setInsetName("unknown");
47 }
48
49
50 InsetFormulaMacro::InsetFormulaMacro(string nm, int na)
51 {
52         setInsetName(nm);
53         MathMacroTable::create(nm, na, string());
54 }
55
56
57 InsetFormulaMacro::InsetFormulaMacro(string const & s)
58 {
59         string name = mathed_parse_macro(s);
60         setInsetName(name);
61 }
62
63
64 Inset * InsetFormulaMacro::clone(Buffer const &, bool) const
65 {
66         return new InsetFormulaMacro(*this);
67 }
68
69
70 void InsetFormulaMacro::write(Buffer const *, ostream & os) const
71 {
72         os << "FormulaMacro ";
73         WriteStream wi(os, false);
74         par()->write(wi);
75 }
76
77
78 int InsetFormulaMacro::latex(Buffer const *, ostream & os, bool fragile, 
79                              bool /*free_spacing*/) const
80 {
81         WriteStream wi(os, fragile);
82         par()->write(wi);
83         return 2;
84 }
85
86
87 int InsetFormulaMacro::ascii(Buffer const *, ostream & os, int) const
88 {
89         WriteStream wi(os, false);
90         par()->write(wi);
91         return 0;
92 }
93
94
95 int InsetFormulaMacro::linuxdoc(Buffer const * buf, ostream & os) const
96 {
97         return ascii(buf, os, 0);
98 }
99
100
101 int InsetFormulaMacro::docbook(Buffer const * buf, ostream & os) const
102 {
103         return ascii(buf, os, 0);
104 }
105
106
107 void InsetFormulaMacro::read(Buffer const *, LyXLex & lex)
108 {
109         string name = mathed_parse_macro(lex);
110         setInsetName(name);
111         //lyxerr << "metrics disabled";
112         metrics();
113 }
114
115
116 string InsetFormulaMacro::prefix() const
117 {
118         return string(" ") + _("Macro: ") + getInsetName() + ": ";
119 }
120
121
122 int InsetFormulaMacro::ascent(BufferView *, LyXFont const &) const
123 {
124         return par()->ascent() + 5;
125 }
126
127
128 int InsetFormulaMacro::descent(BufferView *, LyXFont const &) const
129 {
130         return par()->descent() + 5;
131 }
132
133
134 int InsetFormulaMacro::width(BufferView * bv, LyXFont const & f) const
135 {
136         metrics(bv, f);
137         return 10 + lyxfont::width(prefix(), f) + par()->width();
138 }
139
140
141
142 UpdatableInset::RESULT
143 InsetFormulaMacro::localDispatch(BufferView * bv,
144                                  kb_action action, string const & arg)
145 {
146         RESULT result = DISPATCHED;
147         switch (action) {
148                 case LFUN_MATH_MACROARG: {
149                         int const i = lyx::atoi(arg);
150                         lyxerr << "inserting macro arg " << i << "\n";
151                         //if (i > 0 && i <= par()->numargs()) {
152                                 mathcursor->insert(MathAtom(new MathMacroArgument(i)));
153                                 updateLocal(bv, true);
154                         //} else {
155                         //      lyxerr << "not in range 0.." << par()->numargs() << "\n";
156                         //}
157                         break;
158                 }
159                 
160                 default: {
161                         result = InsetFormulaBase::localDispatch(bv, action, arg);
162                         // force redraw if anything happened
163                         if (result != UNDISPATCHED) {
164                                 bv->text->status(bv, LyXText::NEED_MORE_REFRESH);
165                                 bv->updateInset(this, false);
166                         }
167                 }
168         }
169         return result;
170 }
171
172
173 MathAtom const & InsetFormulaMacro::par() const
174 {
175         return MathMacroTable::provide(getInsetName());
176 }
177
178
179 MathAtom & InsetFormulaMacro::par()
180 {
181         return MathMacroTable::provide(getInsetName());
182 }
183
184
185 Inset::Code InsetFormulaMacro::lyxCode() const
186 {
187         return Inset::MATHMACRO_CODE;
188 }
189
190
191 MathInsetTypes InsetFormulaMacro::getType() const
192 {
193         return LM_OT_MACRO;
194 }
195
196
197 void InsetFormulaMacro::draw(BufferView * bv, LyXFont const & f,
198                              int y, float & x, bool /*cleared*/) const
199 {
200         Painter & pain = bv->painter();
201         LyXFont font(f);
202
203         // label
204         font.setColor(LColor::math);
205         
206         int const a = y - ascent(bv, font) + 1;
207         int const w = width(bv, font) - 2;
208         int const h = ascent(bv, font) + descent(bv, font) - 2;
209
210         // LColor::mathbg used to be "AntiqueWhite" but is "linen" now, too
211         pain.fillRectangle(int(x), a , w, h, LColor::mathmacrobg);
212         pain.rectangle(int(x), a, w, h, LColor::mathframe);
213
214         if (mathcursor &&
215                         const_cast<InsetFormulaBase const *>(mathcursor->formula()) == this)
216                 mathcursor->drawSelection(pain);
217
218         pain.text(int(x + 2), y, prefix(), font);
219         x += width(bv, font);
220
221         // formula
222         xo_ = int(x) - par()->width() - 5;
223         yo_ = y;
224         par()->draw(pain, xo_, yo_);
225 }
226