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