Fix crash in InsetInfo when bindings change

This is actually a generic InsetInfo issue:

1/ the contents of the inset is computed in updateBuffer, so that it
   is available for drawing but also for latex output (think batch
   export). When it is called, it deletes the existing inner paragraph
   and replaces it by a new one

2/ metrics build a new Row object that represents to paragraph

3/ draw() relies on this information

Now, imagine that updateBuffer() is called after metrics(). This can
happen for many reasons, and does happen here (display a shortcut info
and change the shortcut file from cua to emacs).

This problem has been here forever, but is only visible now that the
(experimental) bookmark display code needs to read the underlying
paragraph id.

The solution is to compute the inset contents at metrics time. This
is done by moving the relevant code to a new standalone build() method
that is called in metrics() but also in latex().
This commit is contained in:
Jean-Marc Lasgouttes 2022-03-10 12:19:44 +01:00
parent 498a5cd487
commit 12dfdbf0a3
2 changed files with 38 additions and 5 deletions

View File

@ -772,7 +772,31 @@ bool InsetInfo::forceLocalFontSwitch() const
}
void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype, bool const deleted) {
void InsetInfo::metrics(MetricsInfo & mi, Dimension & dim) const
{
const_cast<InsetInfo *>(this)->build();
InsetCollapsible::metrics(mi, dim);
}
void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype, bool const deleted)
{
// If the Buffer is a clone, then we neither need nor want to do any
// of what follows. We want, rather, just to inherit how things were
// in the original Buffer. This is especially important for VCS.
// Otherwise, we could in principle have different settings here
// than in the Buffer we were exporting.
if (buffer().isClone())
return;
BufferParams const & bp = buffer().params();
params_.lang = it.paragraph().getFontSettings(bp, it.pos()).language();
InsetCollapsible::updateBuffer(it, utype, deleted);
}
void InsetInfo::build()
{
// If the Buffer is a clone, then we neither need nor want to do any
// of what follows. We want, rather, just to inherit how things were
// in the original Buffer. This is especially important for VCS.
@ -781,8 +805,6 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype, bool cons
if (buffer().isClone())
return;
BufferParams const & bp = buffer().params();
params_.lang = it.paragraph().getFontSettings(bp, it.pos()).language();
Language const * tryguilang = languages.getFromCode(Messages::guiLanguage());
// Some info insets use the language of the GUI (if available)
Language const * guilang = tryguilang ? tryguilang : params_.lang;
@ -1106,7 +1128,7 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype, bool cons
else if (params_.name == "path")
setText(from_utf8(os::latex_path(buffer().filePath())), params_.lang);
else if (params_.name == "class")
setText(from_utf8(bp.documentClass().name()), params_.lang);
setText(from_utf8(buffer().params().documentClass().name()), params_.lang);
break;
}
case InsetInfoParams::VCS_INFO: {
@ -1194,7 +1216,13 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype, bool cons
// Just to do something with that string
LYXERR(Debug::INFO, "info inset text: " << gui);
InsetCollapsible::updateBuffer(it, utype, deleted);
}
void InsetInfo::latex(otexstream & os, OutputParams const & runparams) const
{
const_cast<InsetInfo *>(this)->build();
InsetCollapsible::latex(os, runparams);
}

View File

@ -203,6 +203,7 @@ public:
void setInfo(std::string const & info);
///
void updateBuffer(ParIterator const & it, UpdateType utype, bool const deleted = false) override;
void metrics(MetricsInfo & mi, Dimension & dim) const override;
///
docstring toolTip(BufferView const & bv, int x, int y) const override;
///
@ -212,6 +213,8 @@ public:
/// should paragraph indentation be omitted in any case?
bool neverIndent() const override { return true; }
///
void latex(otexstream &, OutputParams const &) const override;
///
InsetInfoParams params() const { return params_; }
private:
@ -225,6 +228,8 @@ private:
void setText(docstring const & str, Language const *);
// make sure that the other version of setText is still available.
using InsetCollapsible::setText;
/// Compute the information
void build();
///
bool initialized_;
///