]> git.lyx.org Git - lyx.git/blob - src/insets/InsetIPA.cpp
Change tracking cue for InsetCaption
[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 #include "texstream.h"
26
27 #include "frontends/Painter.h"
28
29 #include "graphics/PreviewImage.h"
30
31 #include <sstream>
32
33 using namespace std;
34
35 namespace lyx {
36
37
38 InsetIPA::InsetIPA(Buffer * buf) 
39         : InsetText(buf),
40           preview_(new RenderPreview(this))
41 {
42         setDrawFrame(true);
43         setFrameColor(Color_insetframe);
44 }
45
46
47 InsetIPA::~InsetIPA() 
48 {}
49
50
51 InsetIPA::InsetIPA(InsetIPA const & other)
52         : InsetText(other)
53 {
54         preview_.reset(new RenderPreview(*other.preview_, this));
55 }
56
57
58 InsetIPA & InsetIPA::operator=(InsetIPA const & other)
59 {
60         if (&other == this)
61                 return *this;
62
63         InsetText::operator=(other);
64         preview_.reset(new RenderPreview(*other.preview_, this));
65
66         return *this;
67 }
68
69
70 void InsetIPA::write(ostream & os) const
71 {
72         os << "IPA" << "\n";
73         text().write(os);
74 }
75
76
77 void InsetIPA::doDispatch(Cursor & cur, FuncRequest & cmd)
78 {
79         switch (cmd.action()) {
80         case LFUN_QUOTE_INSERT: {
81                 FuncRequest fr(LFUN_SELF_INSERT, "\"");
82                 InsetText::doDispatch(cur, fr);
83                 break;
84         }
85         default:
86                 InsetText::doDispatch(cur, cmd);
87                 break;
88         }
89
90 }
91
92
93 bool InsetIPA::getStatus(Cursor & cur, FuncRequest const & cmd,
94                 FuncStatus & flag) const
95 {
96         switch (cmd.action()) {
97         case LFUN_SCRIPT_INSERT: {
98                 if (cmd.argument() == "subscript") {
99                         flag.setEnabled(false);
100                         return true;
101                 }
102                 break;
103         }
104         case LFUN_IN_IPA:
105                 flag.setEnabled(true);
106                 return true;
107                 break;
108         default:
109                 break;
110         }
111         return InsetText::getStatus(cur, cmd, flag);
112 }
113
114
115 void InsetIPA::addPreview(DocIterator const & inset_pos,
116         graphics::PreviewLoader &) const
117 {
118         preparePreview(inset_pos);
119 }
120
121
122 void InsetIPA::preparePreview(DocIterator const & pos) const  
123 {
124         odocstringstream str;
125         otexstream os(str);
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         if (previewState(pi.base.bv)) {
154                 preview_->draw(pi, x, y);
155                 setPosCache(pi, x, y);
156                 return;
157         }
158         InsetText::draw(pi, x, y);
159 }
160
161
162 void InsetIPA::edit(Cursor & cur, bool front, EntryDirection entry_from)
163 {
164         cur.push(*this);
165         InsetText::edit(cur, front, entry_from);
166 }
167
168
169 Inset * InsetIPA::editXY(Cursor & cur, int x, int y)
170 {
171         if (previewState(&cur.bv())) {
172                 edit(cur, true, ENTRY_DIRECTION_IGNORE);
173                 return this;
174         }
175         cur.push(*this);
176         return InsetText::editXY(cur, x, y);
177 }
178
179
180 void InsetIPA::metrics(MetricsInfo & mi, Dimension & dim) const
181 {
182         if (previewState(mi.base.bv)) {
183                 preview_->metrics(mi, dim);
184
185                 dim.wid = max(dim.wid, 4);
186                 dim.asc = max(dim.asc, 4);
187
188                 dim.asc += TEXT_TO_INSET_OFFSET;
189                 dim.des += TEXT_TO_INSET_OFFSET;
190                 // insert a one pixel gap
191                 dim.wid += 1;
192                 // Cache the inset dimension.
193                 setDimCache(mi, dim);
194                 Dimension dim_dummy;
195                 MetricsInfo mi_dummy = mi;
196                 InsetText::metrics(mi_dummy, dim_dummy);
197                 return;
198         }
199         InsetText::metrics(mi, dim);
200 }
201
202
203 bool InsetIPA::notifyCursorLeaves(Cursor const & old, Cursor & cur)
204 {
205         reloadPreview(old);
206         cur.screenUpdateFlags(Update::Force);
207         return InsetText::notifyCursorLeaves(old, cur);
208 }
209
210
211 void InsetIPA::validate(LaTeXFeatures & features) const
212 {
213         features.require("tipa");
214         features.require("tipx");
215
216         InsetText::validate(features);
217 }
218
219
220 void InsetIPA::latex(otexstream & os, OutputParams const & runparams_in) const
221 {
222         OutputParams runparams(runparams_in);
223         runparams.inIPA = true;
224         bool const multipar = (text().paragraphs().size() > 1);
225         // fontspec knows \textipa, but not the IPA environment
226         bool const nontexfonts = buffer_->params().useNonTeXFonts;
227         if (multipar && !nontexfonts)
228                 os << "\\begin{IPA}\n";
229         else
230                 os << "\\textipa{";
231         InsetText::latex(os, runparams);
232         if (multipar && !nontexfonts)
233                 os << "\n\\end{IPA}";
234         else
235                 os << "}";
236 }
237
238
239 docstring InsetIPA::xhtml(XHTMLStream & xs, OutputParams const & runparams_in) const
240 {
241         OutputParams runparams(runparams_in);
242         runparams.inIPA = true;
243         return InsetText::xhtml(xs, runparams);
244 }
245
246
247 bool InsetIPA::insetAllowed(InsetCode code) const
248 {
249         switch (code) {
250         // code that is allowed
251         case ERT_CODE:
252         case IPACHAR_CODE:
253         case IPADECO_CODE:
254         case SCRIPT_CODE:
255                 return true;
256         default:
257                 return false;
258         }
259 }
260
261
262 } // namespace lyx