]> git.lyx.org Git - lyx.git/blob - src/insets/InsetIPA.cpp
e1f57299145376fc64ed89b04cc816d93a888e95
[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 void InsetIPA::write(ostream & os) const
58 {
59         os << "IPA" << "\n";
60         text().write(os);
61 }
62
63
64 void InsetIPA::doDispatch(Cursor & cur, FuncRequest & cmd)
65 {
66         switch (cmd.action()) {
67         case LFUN_QUOTE_INSERT: {
68                 FuncRequest fr(LFUN_SELF_INSERT, "\"");
69                 InsetText::doDispatch(cur, fr);
70                 break;
71         }
72         default:
73                 InsetText::doDispatch(cur, cmd);
74                 break;
75         }
76
77 }
78
79
80 bool InsetIPA::getStatus(Cursor & cur, FuncRequest const & cmd,
81                 FuncStatus & flag) const
82 {
83         switch (cmd.action()) {
84         case LFUN_SCRIPT_INSERT: {
85                 if (cmd.argument() == "subscript") {
86                         flag.setEnabled(false);
87                         return true;
88                 }
89                 break;
90         }
91         case LFUN_IN_IPA:
92                 flag.setEnabled(true);
93                 return true;
94                 break;
95         default:
96                 break;
97         }
98         return InsetText::getStatus(cur, cmd, flag);
99 }
100
101
102 void InsetIPA::addPreview(DocIterator const & inset_pos,
103         graphics::PreviewLoader &) const
104 {
105         preparePreview(inset_pos);
106 }
107
108
109 void InsetIPA::preparePreview(DocIterator const & pos) const  
110 {
111         TexRow texrow;
112         odocstringstream str;  
113         otexstream os(str, texrow);
114         OutputParams runparams(&pos.buffer()->params().encoding());
115         latex(os, runparams);
116         docstring const snippet = str.str();
117         preview_->addPreview(snippet, *pos.buffer());  
118 }
119
120
121 bool InsetIPA::previewState(BufferView * bv) const
122 {
123         if (!editing(bv) && RenderPreview::previewText()) {
124                 graphics::PreviewImage const * pimage =
125                         preview_->getPreviewImage(bv->buffer());
126                 return pimage && pimage->image();
127         }
128         return false;
129 }
130
131
132 void InsetIPA::reloadPreview(DocIterator const & pos) const
133 {
134         preparePreview(pos);
135         preview_->startLoading(*pos.buffer());
136 }
137
138
139 void InsetIPA::draw(PainterInfo & pi, int x, int y) const
140 {
141         use_preview_ = previewState(pi.base.bv);
142
143         if (use_preview_) {
144                 preview_->draw(pi, x + TEXT_TO_INSET_OFFSET, y);
145                 setPosCache(pi, x, y);
146                 return;
147         }
148         InsetText::draw(pi, x, y);
149 }
150
151
152 void InsetIPA::edit(Cursor & cur, bool front, EntryDirection entry_from)
153 {
154         cur.push(*this);
155         InsetText::edit(cur, front, entry_from);
156 }
157
158
159 Inset * InsetIPA::editXY(Cursor & cur, int x, int y)
160 {
161         if (use_preview_) {
162                 edit(cur, true, ENTRY_DIRECTION_IGNORE);
163                 return this;
164         }
165         cur.push(*this);
166         return InsetText::editXY(cur, x, y);
167 }
168
169
170 void InsetIPA::metrics(MetricsInfo & mi, Dimension & dim) const
171 {
172         if (previewState(mi.base.bv)) {
173                 preview_->metrics(mi, dim);
174                 mi.base.textwidth += 2 * TEXT_TO_INSET_OFFSET;
175                 
176                 dim.wid = max(dim.wid, 4);
177                 dim.asc = max(dim.asc, 4);
178                 
179                 dim.asc += TEXT_TO_INSET_OFFSET;
180                 dim.des += TEXT_TO_INSET_OFFSET;
181                 dim.wid += TEXT_TO_INSET_OFFSET;
182                 dim_ = dim;
183                 dim.wid += TEXT_TO_INSET_OFFSET;
184                 // insert a one pixel gap
185                 dim.wid += 1;
186                 // Cache the inset dimension.
187                 setDimCache(mi, dim);
188                 Dimension dim_dummy;
189                 MetricsInfo mi_dummy = mi;
190                 InsetText::metrics(mi_dummy, dim_dummy);
191                 return;
192         }
193         InsetText::metrics(mi, dim);
194 }
195
196
197 bool InsetIPA::notifyCursorLeaves(Cursor const & old, Cursor & cur)
198 {
199         reloadPreview(old);
200         cur.screenUpdateFlags(Update::Force);
201         return InsetText::notifyCursorLeaves(old, cur);
202 }
203
204
205 void InsetIPA::validate(LaTeXFeatures & features) const
206 {
207         features.require("tipa");
208         features.require("tipx");
209
210         InsetText::validate(features);
211 }
212
213
214 void InsetIPA::latex(otexstream & os, OutputParams const & runparams_in) const
215 {
216         OutputParams runparams(runparams_in);
217         runparams.inIPA = true;
218         bool const multipar = (text().paragraphs().size() > 1);
219         // fontspec knows \textipa, but not the IPA environment
220         bool const nontexfonts = buffer_->params().useNonTeXFonts;
221         if (multipar && !nontexfonts)
222                 os << "\\begin{IPA}\n";
223         else
224                 os << "\\textipa{";
225         InsetText::latex(os, runparams);
226         if (multipar && !nontexfonts)
227                 os << "\n\\end{IPA}";
228         else
229                 os << "}";
230 }
231
232
233 docstring InsetIPA::xhtml(XHTMLStream & xs, OutputParams const & runparams_in) const
234 {
235         OutputParams runparams(runparams_in);
236         runparams.inIPA = true;
237         return InsetText::xhtml(xs, runparams);
238 }
239
240
241 bool InsetIPA::insetAllowed(InsetCode code) const
242 {
243         switch (code) {
244         // code that is allowed
245         case ERT_CODE:
246         case IPACHAR_CODE:
247         case IPADECO_CODE:
248         case SCRIPT_CODE:
249                 return true;
250         default:
251                 return false;
252         }
253 }
254
255
256 } // namespace lyx