2 * \file InsetPreview.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Vincent van Ravesteijn
8 * Full author contact details are available in file CREDITS.
12 #include "InsetPreview.h"
15 #include "BufferParams.h"
16 #include "BufferView.h"
18 #include "Dimension.h"
19 #include "MetricsInfo.h"
20 #include "RenderPreview.h"
21 #include "texstream.h"
23 #include "frontends/Painter.h"
25 #include "graphics/PreviewImage.h"
27 #include "mathed/InsetMathHull.h"
28 #include "mathed/MacroTable.h"
37 InsetPreview::InsetPreview(Buffer * buf)
38 : InsetText(buf), preview_(new RenderPreview(this))
41 setFrameColor(Color_previewframe);
45 InsetPreview::~InsetPreview()
49 InsetPreview::InsetPreview(InsetPreview const & other)
52 preview_.reset(new RenderPreview(*other.preview_, this));
56 InsetPreview & InsetPreview::operator=(InsetPreview const & other)
61 InsetText::operator=(other);
62 preview_.reset(new RenderPreview(*other.preview_, this));
68 void InsetPreview::write(ostream & os) const
70 os << "Preview" << "\n";
75 void InsetPreview::addPreview(DocIterator const & inset_pos,
76 graphics::PreviewLoader &) const
78 preparePreview(inset_pos);
82 MacroNameSet gatherMacroDefinitions(const Buffer* buffer, const Inset * inset)
84 // Collect macros for this inset.
85 // Not done yet: this function returns a list of macro *definitions*.
87 buffer->listMacroNames(macros);
89 // Look for math insets and collect definitions for the used macros.
91 DocIterator const dbeg = doc_iterator_begin(buffer, inset);
92 DocIterator dit = dbeg;
93 DocIterator const dend = doc_iterator_end(buffer, inset);
97 for (; dit != dend; dit.forwardInset()) {
98 InsetMath * im = dit.nextInset()->asInsetMath();
99 InsetMathHull * hull = im ? im->asHullInset() : nullptr;
102 for (idx_type idx = 0; idx < hull->nargs(); ++idx)
103 hull->usedMacros(hull->cell(idx), dbeg, macros, defs);
110 docstring insetToLaTeXSnippet(const Buffer* buffer, const Inset * inset)
112 odocstringstream str;
114 OutputParams runparams(&buffer->params().encoding());
115 inset->latex(os, runparams);
117 MacroNameSet defs = gatherMacroDefinitions(buffer, inset);
118 docstring macro_preamble;
119 for (const auto& def : defs)
120 macro_preamble.append(def);
122 return macro_preamble + str.str();
126 void InsetPreview::preparePreview(DocIterator const & pos) const
128 docstring const snippet = insetToLaTeXSnippet(pos.buffer(), this);
129 preview_->addPreview(snippet, *pos.buffer());
133 bool InsetPreview::previewState(BufferView * bv) const
135 if (!editing(bv) && RenderPreview::previewText()) {
136 graphics::PreviewImage const * pimage =
137 preview_->getPreviewImage(bv->buffer());
138 return pimage && pimage->image();
144 void InsetPreview::reloadPreview(DocIterator const & pos) const
147 preview_->startLoading(*pos.buffer());
151 void InsetPreview::draw(PainterInfo & pi, int x, int y) const
153 if (previewState(pi.base.bv)) {
154 // one pixel gap in front
155 preview_->draw(pi, x + 1, y);
157 InsetText::draw(pi, x, y);
161 void InsetPreview::edit(Cursor & cur, bool front, EntryDirection entry_from)
164 InsetText::edit(cur, front, entry_from);
168 Inset * InsetPreview::editXY(Cursor & cur, int x, int y)
170 if (previewState(&cur.bv())) {
171 edit(cur, true, ENTRY_DIRECTION_IGNORE);
175 return InsetText::editXY(cur, x, y);
179 void InsetPreview::metrics(MetricsInfo & mi, Dimension & dim) const
181 if (previewState(mi.base.bv)) {
182 preview_->metrics(mi, dim);
184 dim.wid = max(dim.wid, 4);
185 dim.asc = max(dim.asc, 4);
187 dim.asc += topOffset(mi.base.bv);
188 dim.des += bottomOffset(mi.base.bv);
189 // insert a one pixel gap
192 MetricsInfo mi_dummy = mi;
193 InsetText::metrics(mi_dummy, dim_dummy);
196 InsetText::metrics(mi, dim);
200 bool InsetPreview::notifyCursorLeaves(Cursor const & old, Cursor & cur)
203 cur.screenUpdateFlags(Update::Force);
204 return InsetText::notifyCursorLeaves(old, cur);