]> git.lyx.org Git - lyx.git/blob - src/insets/InsetIPA.cpp
Cmake tests: macro setmarkedtestlabel() worked only by chance
[lyx.git] / src / insets / InsetIPA.cpp
1 /**
2  * \file InsetIPA.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jürgen Spitzmüller
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10 #include "config.h"
11
12 #include "InsetIPA.h"
13
14 #include "Buffer.h"
15 #include "BufferParams.h"
16 #include "BufferView.h"
17 #include "Cursor.h"
18 #include "FuncRequest.h"
19 #include "FuncStatus.h"
20 #include "LaTeXFeatures.h"
21 #include "Lexer.h"
22 #include "MetricsInfo.h"
23 #include "OutputParams.h"
24 #include "RenderPreview.h"
25
26 #include "frontends/Painter.h"
27
28 #include "graphics/PreviewImage.h"
29
30 #include <sstream>
31
32 using namespace std;
33
34 namespace lyx {
35
36
37 InsetIPA::InsetIPA(Buffer * buf) 
38         : InsetText(buf),
39           preview_(new RenderPreview(this)), use_preview_(true)
40 {
41         setDrawFrame(true);
42         setFrameColor(Color_insetframe);
43 }
44
45
46 InsetIPA::~InsetIPA() 
47 {}
48
49
50 InsetIPA::InsetIPA(InsetIPA const & other)
51         : InsetText(other)
52 {
53         preview_.reset(new RenderPreview(*other.preview_, this));
54 }
55
56
57 InsetIPA & InsetIPA::operator=(InsetIPA const & other)
58 {
59         if (&other == this)
60                 return *this;
61
62         InsetText::operator=(other);
63         preview_.reset(new RenderPreview(*other.preview_, this));
64
65         return *this;
66 }
67
68
69 void InsetIPA::write(ostream & os) const
70 {
71         os << "IPA" << "\n";
72         text().write(os);
73 }
74
75
76 void InsetIPA::doDispatch(Cursor & cur, FuncRequest & cmd)
77 {
78         switch (cmd.action()) {
79         case LFUN_QUOTE_INSERT: {
80                 FuncRequest fr(LFUN_SELF_INSERT, "\"");
81                 InsetText::doDispatch(cur, fr);
82                 break;
83         }
84         default:
85                 InsetText::doDispatch(cur, cmd);
86                 break;
87         }
88
89 }
90
91
92 bool InsetIPA::getStatus(Cursor & cur, FuncRequest const & cmd,
93                 FuncStatus & flag) const
94 {
95         switch (cmd.action()) {
96         case LFUN_SCRIPT_INSERT: {
97                 if (cmd.argument() == "subscript") {
98                         flag.setEnabled(false);
99                         return true;
100                 }
101                 break;
102         }
103         case LFUN_IN_IPA:
104                 flag.setEnabled(true);
105                 return true;
106                 break;
107         default:
108                 break;
109         }
110         return InsetText::getStatus(cur, cmd, flag);
111 }
112
113
114 void InsetIPA::addPreview(DocIterator const & inset_pos,
115         graphics::PreviewLoader &) const
116 {
117         preparePreview(inset_pos);
118 }
119
120
121 void InsetIPA::preparePreview(DocIterator const & pos) const  
122 {
123         TexRow texrow;
124         odocstringstream str;  
125         otexstream os(str, texrow);
126         OutputParams runparams(&pos.buffer()->params().encoding());
127         latex(os, runparams);
128         docstring const snippet = str.str();
129         preview_->addPreview(snippet, *pos.buffer());  
130 }
131
132
133 bool InsetIPA::previewState(BufferView * bv) const
134 {
135         if (!editing(bv) && RenderPreview::previewText()) {
136                 graphics::PreviewImage const * pimage =
137                         preview_->getPreviewImage(bv->buffer());
138                 return pimage && pimage->image();
139         }
140         return false;
141 }
142
143
144 void InsetIPA::reloadPreview(DocIterator const & pos) const
145 {
146         preparePreview(pos);
147         preview_->startLoading(*pos.buffer());
148 }
149
150
151 void InsetIPA::draw(PainterInfo & pi, int x, int y) const
152 {
153         use_preview_ = previewState(pi.base.bv);
154
155         if (use_preview_) {
156                 preview_->draw(pi, x + TEXT_TO_INSET_OFFSET, y);
157                 setPosCache(pi, x, y);
158                 return;
159         }
160         InsetText::draw(pi, x, y);
161 }
162
163
164 void InsetIPA::edit(Cursor & cur, bool front, EntryDirection entry_from)
165 {
166         cur.push(*this);
167         InsetText::edit(cur, front, entry_from);
168 }
169
170
171 Inset * InsetIPA::editXY(Cursor & cur, int x, int y)
172 {
173         if (use_preview_) {
174                 edit(cur, true, ENTRY_DIRECTION_IGNORE);
175                 return this;
176         }
177         cur.push(*this);
178         return InsetText::editXY(cur, x, y);
179 }
180
181
182 void InsetIPA::metrics(MetricsInfo & mi, Dimension & dim) const
183 {
184         if (previewState(mi.base.bv)) {
185                 preview_->metrics(mi, dim);
186                 mi.base.textwidth += 2 * TEXT_TO_INSET_OFFSET;
187                 
188                 dim.wid = max(dim.wid, 4);
189                 dim.asc = max(dim.asc, 4);
190                 
191                 dim.asc += TEXT_TO_INSET_OFFSET;
192                 dim.des += TEXT_TO_INSET_OFFSET;
193                 dim.wid += TEXT_TO_INSET_OFFSET;
194                 dim_ = dim;
195                 dim.wid += TEXT_TO_INSET_OFFSET;
196                 // insert a one pixel gap
197                 dim.wid += 1;
198                 // Cache the inset dimension.
199                 setDimCache(mi, dim);
200                 Dimension dim_dummy;
201                 MetricsInfo mi_dummy = mi;
202                 InsetText::metrics(mi_dummy, dim_dummy);
203                 return;
204         }
205         InsetText::metrics(mi, dim);
206 }
207
208
209 bool InsetIPA::notifyCursorLeaves(Cursor const & old, Cursor & cur)
210 {
211         reloadPreview(old);
212         cur.screenUpdateFlags(Update::Force);
213         return InsetText::notifyCursorLeaves(old, cur);
214 }
215
216
217 void InsetIPA::validate(LaTeXFeatures & features) const
218 {
219         features.require("tipa");
220         features.require("tipx");
221
222         InsetText::validate(features);
223 }
224
225
226 void InsetIPA::latex(otexstream & os, OutputParams const & runparams_in) const
227 {
228         OutputParams runparams(runparams_in);
229         runparams.inIPA = true;
230         bool const multipar = (text().paragraphs().size() > 1);
231         // fontspec knows \textipa, but not the IPA environment
232         bool const nontexfonts = buffer_->params().useNonTeXFonts;
233         if (multipar && !nontexfonts)
234                 os << "\\begin{IPA}\n";
235         else
236                 os << "\\textipa{";
237         InsetText::latex(os, runparams);
238         if (multipar && !nontexfonts)
239                 os << "\n\\end{IPA}";
240         else
241                 os << "}";
242 }
243
244
245 docstring InsetIPA::xhtml(XHTMLStream & xs, OutputParams const & runparams_in) const
246 {
247         OutputParams runparams(runparams_in);
248         runparams.inIPA = true;
249         return InsetText::xhtml(xs, runparams);
250 }
251
252
253 bool InsetIPA::insetAllowed(InsetCode code) const
254 {
255         switch (code) {
256         // code that is allowed
257         case ERT_CODE:
258         case IPACHAR_CODE:
259         case IPADECO_CODE:
260         case SCRIPT_CODE:
261                 return true;
262         default:
263                 return false;
264         }
265 }
266
267
268 } // namespace lyx