]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ControlMath.C
fix crash due to invalidated iterator
[lyx.git] / src / frontends / controllers / ControlMath.C
1 /**
2  * \file ControlMath.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "ControlMath.h"
14 #include "debug.h"
15 #include "funcrequest.h"
16
17 #include "support/lyxalgo.h" // sorted
18 #include "support/lstrings.h"
19 #include "support/filetools.h"
20
21 #include <functional>
22
23 using std::string;
24
25 namespace lyx {
26
27 using support::compare;
28 using support::LibFileSearch;
29 using support::subst;
30
31 namespace frontend {
32
33 ControlMath::ControlMath(Dialog & dialog)
34         : Dialog::Controller(dialog)
35 {}
36
37
38 void ControlMath::dispatchFunc(kb_action action, string const & arg) const
39 {
40         kernel().dispatch(FuncRequest(action, arg));
41 }
42
43
44 void ControlMath::dispatchInsert(string const & name) const
45 {
46         dispatchFunc(LFUN_INSERT_MATH, '\\' + name);
47 }
48
49
50 void ControlMath::dispatchSubscript() const
51 {
52         dispatchFunc(LFUN_INSERT_MATH, "_");
53         dispatchFunc(LFUN_DOWN);
54 }
55
56
57 void ControlMath::dispatchSuperscript() const
58 {
59         dispatchFunc(LFUN_INSERT_MATH, "^");
60         dispatchFunc(LFUN_UP);
61 }
62
63
64 void ControlMath::dispatchCubeRoot() const
65 {
66         dispatchFunc(LFUN_INSERT_MATH, "\\root");
67         dispatchFunc(LFUN_SELFINSERT, "3");
68         dispatchFunc(LFUN_RIGHT);
69 }
70
71
72 void ControlMath::dispatchMatrix(string const & str) const
73 {
74         dispatchFunc(LFUN_INSERT_MATRIX, str);
75 }
76
77
78 void ControlMath::dispatchDelim(string const & str) const
79 {
80         dispatchFunc(LFUN_MATH_DELIM, str);
81 }
82
83
84 void ControlMath::dispatchToggleDisplay() const
85 {
86         dispatchFunc(LFUN_MATH_DISPLAY);
87 }
88
89
90 void ControlMath::showDialog(string const & name) const
91 {
92         dispatchFunc(LFUN_DIALOG_SHOW, name);
93 }
94
95
96 char const * function_names[] = {
97         "arccos", "arcsin", "arctan", "arg", "bmod",
98         "cos", "cosh", "cot", "coth", "csc", "deg",
99         "det", "dim", "exp", "gcd", "hom", "inf", "ker",
100         "lg", "lim", "liminf", "limsup", "ln", "log",
101         "max", "min", "sec", "sin", "sinh", "sup",
102         "tan", "tanh", "Pr", ""
103 };
104
105 int const nr_function_names = sizeof(function_names) / sizeof(char const *) - 1;
106
107 char const * latex_dots[] = {
108         "ldots", "cdots", "vdots", "ddots", ""
109 };
110
111 int const nr_latex_dots = sizeof(latex_dots) / sizeof(char const *) - 1;
112
113 char const * latex_deco[] = {
114         "widehat", "widetilde", "overbrace", "overleftarrow", "overrightarrow",
115         "overline", "underbrace", "underline", "underleftarrow", "underrightarrow",
116         "underleftrightarrow", "overleftrightarrow",
117         "hat", "acute", "bar", "dot",
118         "check", "grave", "vec", "ddot",
119         "breve", "tilde", ""
120 };
121
122 int const nr_latex_deco = sizeof(latex_deco) / sizeof(char const *) - 1;
123
124 char const * latex_arrow[] = {
125         "downarrow", "leftarrow", "Downarrow", "Leftarrow",
126         "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
127         "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
128         "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
129         "leftharpoondown", "rightharpoondown", "mapsto",
130         "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
131         "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
132         "nwarrow", "nearrow", "swarrow", "searrow",  "",
133 };
134
135 int const nr_latex_arrow = sizeof(latex_arrow) / sizeof(char const *);
136
137 char const * latex_bop[] = {
138         "pm", "cap", "diamond", "oplus",
139         "mp", "cup", "bigtriangleup", "ominus",
140         "times", "uplus", "bigtriangledown", "otimes",
141         "div", "sqcap", "triangleright", "oslash",
142         "cdot", "sqcup", "triangleleft", "odot",
143         "star", "vee", "amalg", "bigcirc",
144         "setminus", "wedge", "dagger", "circ",
145         "bullet", "wr", "ddagger", ""
146 };
147
148 int const nr_latex_bop = sizeof(latex_bop) / sizeof(char const *);
149
150 char const * latex_brel[] = {
151         "leq", "geq", "equiv", "models",
152         "prec", "succ", "sim", "perp",
153         "preceq", "succeq", "simeq", "mid",
154         "ll", "gg", "asymp", "parallel",
155         "subset", "supset", "approx", "smile",
156         "subseteq", "supseteq", "cong", "frown",
157         "sqsubseteq", "sqsupseteq", "doteq", "neq",
158         "in", "ni", "propto", "notin",
159         "vdash", "dashv", "bowtie", ""
160 };
161
162 int const nr_latex_brel = sizeof(latex_brel) / sizeof(char const *);
163
164 char const * latex_greek[] = {
165         "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
166         "Sigma", "Upsilon", "Phi", "Psi", "Omega",
167         "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
168         "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
169         "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
170         "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
171 };
172
173 int const nr_latex_greek = sizeof(latex_greek) / sizeof(char const *);
174
175 char const * latex_misc[] = {
176         "nabla", "partial", "infty", "prime", "ell",
177         "emptyset", "exists", "forall", "imath",  "jmath",
178         "Re", "Im", "aleph", "wp", "hbar",
179         "angle", "top", "bot", "Vert", "neg",
180         "flat", "natural", "sharp", "surd", "triangle",
181         "diamondsuit", "heartsuit", "clubsuit", "spadesuit",
182         "textrm \\AA", "textrm \\O", "mathcircumflex", "_",
183         "mathrm T",
184         "mathbb N", "mathbb Z", "mathbb Q",
185         "mathbb R", "mathbb C", "mathbb H",
186         "mathcal F", "mathcal L",
187         "mathcal H", "mathcal O", ""
188 };
189
190 int const nr_latex_misc = sizeof(latex_misc) / sizeof(char const *);
191
192 char const * latex_varsz[] = {
193         "sum", "int", "oint",
194         "prod", "coprod", "bigsqcup",
195         "bigotimes", "bigodot", "bigoplus",
196         "bigcap", "bigcup", "biguplus",
197         "bigvee", "bigwedge", ""
198 };
199
200 int const nr_latex_varsz = sizeof(latex_varsz) / sizeof(char const *);
201
202 char const * latex_ams_misc[] = {
203         "digamma", "varkappa", "beth", "daleth", "gimel",
204         "ulcorner", "urcorner", "llcorner", "lrcorner",
205         "hbar", "hslash", "vartriangle",
206         "triangledown", "square", "lozenge",
207         "circledS", "angle", "measuredangle",
208         "nexists", "mho", "Finv",
209         "Game", "Bbbk", "backprime",
210         "varnothing", "blacktriangle", "blacktriangledown",
211         "blacksquare", "blacklozenge", "bigstar",
212         "sphericalangle", "complement", "eth",
213         "diagup", "diagdown", ""
214 };
215
216 int const nr_latex_ams_misc = sizeof(latex_ams_misc) / sizeof(char const *);
217
218 char const * latex_ams_arrows[] = {
219         "dashrightarrow", "dashleftarrow", "leftleftarrows",
220         "leftrightarrows", "Lleftarrow", "twoheadleftarrow",
221         "leftarrowtail", "looparrowleft", "leftrightharpoons",
222         "curvearrowleft", "circlearrowleft", "Lsh",
223         "upuparrows", "upharpoonleft", "downharpoonleft",
224         "multimap", "leftrightsquigarrow", "rightrightarrows",
225         "rightleftarrows", "rightrightarrows", "rightleftarrows",
226         "twoheadrightarrow", "rightarrowtail", "looparrowright",
227         "rightleftharpoons", "curvearrowright", "circlearrowright",
228         "Rsh", "downdownarrows", "upharpoonright",
229         "downharpoonright", "rightsquigarrow",
230         "nleftarrow", "nrightarrow", "nLeftarrow",
231         "nRightarrow", "nleftrightarrow", "nLeftrightarrow", ""
232 };
233
234 int const nr_latex_ams_arrows = sizeof(latex_ams_arrows) / sizeof(char const *);
235
236 char const * latex_ams_rel[] = {
237         "leqq", "leqslant", "eqslantless", "eqslantgtr", "gtrsim", "gtrapprox",
238         "lesssim", "lessapprox", "approxeq", "gtrdot", "ggg", "gtrless",
239         "lessdot", "lll", "lessgtr", "gtreqless", "gtreqqless", "eqcirc",
240         "lesseqgtr", "lesseqqgtr", "doteqdot", "circeq", "triangleq", "thicksim",
241         "risingdotseq", "fallingdotseq", "backsim", "thickapprox", "supseteqq", "Supset",
242         "backsimeq", "subseteqq", "Subset", "sqsupset", "succcurlyeq", "curlyeqsucc",
243         "sqsubset", "preccurlyeq", "curlyeqprec", "succsim", "succapprox", "vartriangleright",
244         "precsim", "precapprox", "vartriangleleft", "trianglerighteq", "Vdash", "shortmid",
245         "trianglelefteq", "vDash", "Vvdash", "shortparallel", "between", "pitchfork",
246         "smallsmile", "smallfrown", "bumpeq", "varpropto", "blacktriangleleft", "therefore",
247         "Bumpeq", "geqq", "geqslant", "backepsilon", "blacktriangleright", "because", ""
248 };
249
250 int const nr_latex_ams_rel = sizeof(latex_ams_rel) / sizeof(char const *);
251
252 char const * latex_ams_nrel[] = {
253         "nless", "nleq", "nleqslant", "ngeqslant", "ngeqq", "gneq",
254         "nleqq", "lneq", "lneqq", "gneqq", "gvertneqq", "gnsim",
255         "lvertneqq", "lnsim", "lnapprox", "gnapprox", "nsucc", "nsucceq",
256         "nprec", "npreceq", "precnsim","succnsim", "succnapprox", "ncong",
257         "precnapprox", "nsim", "nshortmid", "nshortparallel", "nparallel", "nvDash",
258
259         "nmid", "nvdash", "nvDash", "nVDash", "ntriangleright", "ntrianglerighteq",
260         "ntriangleleft", "ntrianglelefteq", "nsubseteq", "nsupseteq", "nsupseteqq", "supsetneq",
261         "subsetneq", "varsubsetneq", "subsetneqq", "varsupsetneq", "supsetneqq", "varsupsetneqq",
262         "varsubsetneqq", "ngtr", "ngeq", "", "", ""
263 };
264
265 int const nr_latex_ams_nrel = sizeof(latex_ams_nrel) / sizeof(char const *);
266
267
268 char const * latex_ams_ops[] = {
269         "dotplus", "smallsetminus", "Cap",
270         "Cup", "barwedge", "veebar",
271         "doublebarwedge", "boxminus", "boxtimes",
272         "boxdot", "boxplus", "divideontimes",
273         "ltimes", "rtimes", "leftthreetimes",
274         "rightthreetimes", "curlywedge", "curlyvee",
275         "circleddash", "circledast", "circledcirc",
276         "centerdot", "intercal", ""
277 };
278
279 int const nr_latex_ams_ops = sizeof(latex_ams_ops) / sizeof(char const *);
280
281
282 namespace {
283
284 struct XPMmap {
285         char const * key;
286         char const * value;
287 };
288
289
290 bool operator<(XPMmap const & lhs, XPMmap const & rhs)
291 {
292                 return compare(lhs.key, rhs.key) < 0;
293 }
294
295
296 class CompareKey : public std::unary_function<XPMmap, bool> {
297 public:
298         CompareKey(string const & name) : name_(name) {}
299         bool operator()(XPMmap const & other) const {
300                 return other.key == name_;
301         }
302 private:
303         string const name_;
304 };
305
306
307 XPMmap sorted_xpm_map[] = {
308         { "Bumpeq", "bumpeq2" },
309         { "Cap", "cap2" },
310         { "Cup", "cup2" },
311         { "Delta", "delta2" },
312         { "Downarrow", "downarrow2" },
313         { "Gamma", "gamma2" },
314         { "Lambda", "lambda2" },
315         { "Leftarrow", "leftarrow2" },
316         { "Leftrightarrow", "leftrightarrow2" },
317         { "Longleftarrow", "longleftarrow2" },
318         { "Longleftrightarrow", "longleftrightarrow2" },
319         { "Longrightarrow", "longrightarrow2" },
320         { "Omega", "omega2" },
321         { "Phi", "phi2" },
322         { "Pi", "pi2" },
323         { "Psi", "psi2" },
324         { "Rightarrow", "rightarrow2" },
325         { "Sigma", "sigma2" },
326         { "Subset", "subset2" },
327         { "Supset", "supset2" },
328         { "Theta", "theta2" },
329         { "Uparrow", "uparrow2" },
330         { "Updownarrow", "updownarrow2" },
331         { "Upsilon", "upsilon2" },
332         { "Vdash", "vdash3" },
333         { "Xi", "xi2" },
334         { "nLeftarrow", "nleftarrow2" },
335         { "nLeftrightarrow", "nleftrightarrow2" },
336         { "nRightarrow", "nrightarrow2" },
337         { "nVDash", "nvdash3" },
338         { "nvDash", "nvdash2" },
339         { "textrm \\AA", "textrm_AA"},
340         { "textrm \\O", "textrm_Oe"},
341         { "vDash", "vdash2" }
342 };
343
344 size_t const nr_sorted_xpm_map = sizeof(sorted_xpm_map) / sizeof(XPMmap);
345
346 } // namespace anon
347
348
349 string const find_xpm(string const & name)
350 {
351         XPMmap const * const begin = sorted_xpm_map;
352         XPMmap const * const end = begin + nr_sorted_xpm_map;
353         BOOST_ASSERT(sorted(begin, end));
354
355         XPMmap const * const it =
356                 std::find_if(begin, end, CompareKey(name));
357
358         string xpm_name;
359         if (it != end)
360                 xpm_name = it->value;
361         else {
362                 xpm_name = subst(name, "_", "underscore");
363                 xpm_name = subst(xpm_name, ' ', '_');
364
365                 // This way we can have "math-delim { }" on the toolbar.
366                 xpm_name = subst(xpm_name, "(", "lparen");
367                 xpm_name = subst(xpm_name, ")", "rparen");
368                 xpm_name = subst(xpm_name, "[", "lbracket");
369                 xpm_name = subst(xpm_name, "]", "rbracket");
370                 xpm_name = subst(xpm_name, "{", "lbrace");
371                 xpm_name = subst(xpm_name, "}", "rbrace");
372                 xpm_name = subst(xpm_name, "|", "bars");
373         }
374
375         lyxerr[Debug::GUI] << "find_xpm(" << name << ")\n"
376                            << "Looking for math XPM called \""
377                            << xpm_name << '"' << std::endl;
378
379         return LibFileSearch("images/math/", xpm_name, "xpm");
380 }
381
382 } // namespace frontend
383 } // namespace lyx