2010-11-18 19:50:29 +00:00
|
|
|
/**
|
|
|
|
* \file InsetPreview.cpp
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Vincent van Ravesteijn
|
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "InsetPreview.h"
|
|
|
|
|
|
|
|
#include "Buffer.h"
|
|
|
|
#include "BufferParams.h"
|
|
|
|
#include "BufferView.h"
|
|
|
|
#include "Cursor.h"
|
2020-11-22 22:23:39 +00:00
|
|
|
#include "Dimension.h"
|
2010-11-18 19:50:29 +00:00
|
|
|
#include "MetricsInfo.h"
|
|
|
|
#include "RenderPreview.h"
|
2016-06-19 02:39:38 +00:00
|
|
|
#include "texstream.h"
|
2010-11-18 19:50:29 +00:00
|
|
|
|
|
|
|
#include "frontends/Painter.h"
|
|
|
|
|
|
|
|
#include "graphics/PreviewImage.h"
|
|
|
|
|
2015-06-14 16:10:29 +00:00
|
|
|
#include "mathed/InsetMathHull.h"
|
|
|
|
#include "mathed/MacroTable.h"
|
|
|
|
|
2010-11-18 19:50:29 +00:00
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
|
|
|
|
2016-02-03 13:50:00 +00:00
|
|
|
InsetPreview::InsetPreview(Buffer * buf)
|
|
|
|
: InsetText(buf), preview_(new RenderPreview(this))
|
2010-11-18 19:50:29 +00:00
|
|
|
{
|
|
|
|
setDrawFrame(true);
|
|
|
|
setFrameColor(Color_previewframe);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-02-03 13:50:00 +00:00
|
|
|
InsetPreview::~InsetPreview()
|
2010-11-18 19:50:29 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
InsetPreview::InsetPreview(InsetPreview const & other)
|
|
|
|
: InsetText(other)
|
|
|
|
{
|
|
|
|
preview_.reset(new RenderPreview(*other.preview_, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-11 09:16:09 +00:00
|
|
|
InsetPreview & InsetPreview::operator=(InsetPreview const & other)
|
|
|
|
{
|
|
|
|
if (&other == this)
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
InsetText::operator=(other);
|
|
|
|
preview_.reset(new RenderPreview(*other.preview_, this));
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-18 19:50:29 +00:00
|
|
|
void InsetPreview::write(ostream & os) const
|
|
|
|
{
|
|
|
|
os << "Preview" << "\n";
|
|
|
|
text().write(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetPreview::addPreview(DocIterator const & inset_pos,
|
|
|
|
graphics::PreviewLoader &) const
|
|
|
|
{
|
|
|
|
preparePreview(inset_pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-08 01:14:18 +00:00
|
|
|
MacroNameSet gatherMacroDefinitions(const Buffer* buffer, const Inset * inset)
|
2010-11-18 19:50:29 +00:00
|
|
|
{
|
2021-10-08 01:14:18 +00:00
|
|
|
// Collect macros for this inset.
|
|
|
|
// Not done yet: this function returns a list of macro *definitions*.
|
2015-06-14 16:10:29 +00:00
|
|
|
MacroNameSet macros;
|
2021-10-08 01:14:18 +00:00
|
|
|
buffer->listMacroNames(macros);
|
2015-06-14 16:10:29 +00:00
|
|
|
|
2021-10-08 01:14:18 +00:00
|
|
|
// Look for math insets and collect definitions for the used macros.
|
2015-06-14 16:10:29 +00:00
|
|
|
MacroNameSet defs;
|
2021-10-08 01:14:18 +00:00
|
|
|
DocIterator const dbeg = doc_iterator_begin(buffer, inset);
|
|
|
|
DocIterator dit = dbeg;
|
|
|
|
DocIterator const dend = doc_iterator_end(buffer, inset);
|
2015-06-14 16:10:29 +00:00
|
|
|
if (!dit.nextInset())
|
|
|
|
dit.forwardInset();
|
2021-10-08 01:14:18 +00:00
|
|
|
|
2015-06-14 16:10:29 +00:00
|
|
|
for (; dit != dend; dit.forwardInset()) {
|
|
|
|
InsetMath * im = dit.nextInset()->asInsetMath();
|
2019-09-12 02:13:25 +00:00
|
|
|
InsetMathHull * hull = im ? im->asHullInset() : nullptr;
|
2015-06-14 16:10:29 +00:00
|
|
|
if (!hull)
|
|
|
|
continue;
|
|
|
|
for (idx_type idx = 0; idx < hull->nargs(); ++idx)
|
2021-10-08 01:14:18 +00:00
|
|
|
hull->usedMacros(hull->cell(idx), dbeg, macros, defs);
|
2015-06-14 16:10:29 +00:00
|
|
|
}
|
2021-10-08 01:14:18 +00:00
|
|
|
|
|
|
|
return defs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetPreview::preparePreview(DocIterator const & pos) const
|
|
|
|
{
|
|
|
|
odocstringstream str;
|
|
|
|
otexstream os(str);
|
|
|
|
OutputParams runparams(&pos.buffer()->params().encoding());
|
|
|
|
latex(os, runparams);
|
|
|
|
|
|
|
|
MacroNameSet defs = gatherMacroDefinitions(pos.buffer(), this);
|
2015-06-14 16:10:29 +00:00
|
|
|
docstring macro_preamble;
|
2021-10-08 01:14:18 +00:00
|
|
|
for (const auto& def : defs)
|
|
|
|
macro_preamble.append(def);
|
2015-06-14 16:10:29 +00:00
|
|
|
|
|
|
|
docstring const snippet = macro_preamble + str.str();
|
2015-06-14 16:05:39 +00:00
|
|
|
preview_->addPreview(snippet, *pos.buffer());
|
2010-11-18 19:50:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetPreview::previewState(BufferView * bv) const
|
|
|
|
{
|
2014-05-20 10:19:26 +00:00
|
|
|
if (!editing(bv) && RenderPreview::previewText()) {
|
2010-11-18 19:50:29 +00:00
|
|
|
graphics::PreviewImage const * pimage =
|
|
|
|
preview_->getPreviewImage(bv->buffer());
|
|
|
|
return pimage && pimage->image();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetPreview::reloadPreview(DocIterator const & pos) const
|
|
|
|
{
|
|
|
|
preparePreview(pos);
|
|
|
|
preview_->startLoading(*pos.buffer());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetPreview::draw(PainterInfo & pi, int x, int y) const
|
|
|
|
{
|
2016-02-03 13:50:00 +00:00
|
|
|
if (previewState(pi.base.bv)) {
|
2010-11-18 19:50:29 +00:00
|
|
|
// one pixel gap in front
|
2016-07-21 18:16:27 +00:00
|
|
|
preview_->draw(pi, x + 1, y);
|
2016-02-03 13:50:00 +00:00
|
|
|
} else
|
|
|
|
InsetText::draw(pi, x, y);
|
2010-11-18 19:50:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetPreview::edit(Cursor & cur, bool front, EntryDirection entry_from)
|
|
|
|
{
|
|
|
|
cur.push(*this);
|
|
|
|
InsetText::edit(cur, front, entry_from);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Inset * InsetPreview::editXY(Cursor & cur, int x, int y)
|
|
|
|
{
|
2016-02-03 13:50:00 +00:00
|
|
|
if (previewState(&cur.bv())) {
|
2010-11-18 19:50:29 +00:00
|
|
|
edit(cur, true, ENTRY_DIRECTION_IGNORE);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
cur.push(*this);
|
|
|
|
return InsetText::editXY(cur, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetPreview::metrics(MetricsInfo & mi, Dimension & dim) const
|
|
|
|
{
|
|
|
|
if (previewState(mi.base.bv)) {
|
|
|
|
preview_->metrics(mi, dim);
|
2016-02-03 13:50:00 +00:00
|
|
|
|
2010-11-18 19:50:29 +00:00
|
|
|
dim.wid = max(dim.wid, 4);
|
|
|
|
dim.asc = max(dim.asc, 4);
|
2016-02-03 13:50:00 +00:00
|
|
|
|
2020-01-13 21:09:06 +00:00
|
|
|
dim.asc += topOffset(mi.base.bv);
|
|
|
|
dim.des += bottomOffset(mi.base.bv);
|
2010-11-18 19:50:29 +00:00
|
|
|
// insert a one pixel gap
|
|
|
|
dim.wid += 1;
|
|
|
|
Dimension dim_dummy;
|
|
|
|
MetricsInfo mi_dummy = mi;
|
|
|
|
InsetText::metrics(mi_dummy, dim_dummy);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
InsetText::metrics(mi, dim);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetPreview::notifyCursorLeaves(Cursor const & old, Cursor & cur)
|
|
|
|
{
|
|
|
|
reloadPreview(old);
|
|
|
|
cur.screenUpdateFlags(Update::Force);
|
|
|
|
return InsetText::notifyCursorLeaves(old, cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace lyx
|