Remove updateInfo() calls in favor of doing the relevant work

in updateBuffer().

This is in response to a reported crash. See
	https://www.mail-archive.com/lyx-devel@lists.lyx.org/msg202217.html
Commit af381a2f addressed the crash, and is worth doing anyway. But
this also makes sense.

Also adds a flag to tell us whether we need to recalculate the
relevant information. In some cases, there is no need to do so
more than once. (Note that, with the existing code, we *never*
recalculate, which would have given rise to bugs.)
This commit is contained in:
Richard Heck 2017-10-03 17:28:35 -04:00
parent e68fd9ed03
commit 2e934fc5f8
3 changed files with 46 additions and 8 deletions

View File

@ -263,7 +263,6 @@ Inset * createInsetHelper(Buffer * buf, FuncRequest const & cmd)
case LFUN_INFO_INSERT: { case LFUN_INFO_INSERT: {
InsetInfo * inset = new InsetInfo(buf, to_utf8(cmd.argument())); InsetInfo * inset = new InsetInfo(buf, to_utf8(cmd.argument()));
inset->updateInfo();
return inset; return inset;
} }

View File

@ -92,7 +92,8 @@ NameTranslator const & nameTranslator()
InsetInfo::InsetInfo(Buffer * buf, string const & name) InsetInfo::InsetInfo(Buffer * buf, string const & name)
: InsetCollapsable(buf), type_(UNKNOWN_INFO), name_() : InsetCollapsable(buf), initialized_(false),
type_(UNKNOWN_INFO), name_()
{ {
setInfo(name); setInfo(name);
status_ = Collapsed; status_ = Collapsed;
@ -147,7 +148,6 @@ void InsetInfo::read(Lexer & lex)
_("Missing \\end_inset at this point."), _("Missing \\end_inset at this point."),
from_utf8(token)); from_utf8(token));
} }
updateInfo();
} }
@ -247,6 +247,7 @@ void InsetInfo::doDispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_INSET_MODIFY: case LFUN_INSET_MODIFY:
cur.recordUndo(); cur.recordUndo();
setInfo(to_utf8(cmd.argument())); setInfo(to_utf8(cmd.argument()));
initialized_ = false;
break; break;
case LFUN_INSET_COPY_AS: { case LFUN_INSET_COPY_AS: {
@ -278,7 +279,6 @@ void InsetInfo::setInfo(string const & name)
string type; string type;
name_ = trim(split(name, type, ' ')); name_ = trim(split(name, type, ' '));
type_ = nameTranslator().find(type); type_ = nameTranslator().find(type);
updateInfo();
} }
@ -295,16 +295,21 @@ void InsetInfo::setText(docstring const & str)
} }
void InsetInfo::updateInfo() void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) {
{
BufferParams const & bp = buffer().params(); BufferParams const & bp = buffer().params();
switch (type_) { switch (type_) {
case UNKNOWN_INFO: case UNKNOWN_INFO:
error("Unknown Info: %1$s"); error("Unknown Info: %1$s");
initialized_ = false;
break; break;
case SHORTCUT_INFO: case SHORTCUT_INFO:
case SHORTCUTS_INFO: { case SHORTCUTS_INFO: {
// only need to do this once.
if (initialized_)
break;
// and we will not keep trying if we fail
initialized_ = true;
FuncRequest const func = lyxaction.lookupFunc(name_); FuncRequest const func = lyxaction.lookupFunc(name_);
if (func.action() == LFUN_UNKNOWN_ACTION) { if (func.action() == LFUN_UNKNOWN_ACTION) {
error("Unknown action %1$s"); error("Unknown action %1$s");
@ -323,11 +328,15 @@ void InsetInfo::updateInfo()
break; break;
} }
case LYXRC_INFO: { case LYXRC_INFO: {
// this information could actually change, if the preferences are changed,
// so we will recalculate each time through.
ostringstream oss; ostringstream oss;
if (name_.empty()) { if (name_.empty()) {
setText(_("undefined")); setText(_("undefined"));
break; break;
} }
// FIXME this uses the serialization mechanism to get the info
// we want, which i guess works but is a bit strange.
lyxrc.write(oss, true, name_); lyxrc.write(oss, true, name_);
string result = oss.str(); string result = oss.str();
if (result.size() < 2) { if (result.size() < 2) {
@ -351,20 +360,33 @@ void InsetInfo::updateInfo()
break; break;
} }
case PACKAGE_INFO: case PACKAGE_INFO:
// only need to do this once.
if (initialized_)
break;
// check in packages.lst // check in packages.lst
setText(LaTeXFeatures::isAvailable(name_) ? _("yes") : _("no")); setText(LaTeXFeatures::isAvailable(name_) ? _("yes") : _("no"));
initialized_ = true;
break; break;
case TEXTCLASS_INFO: { case TEXTCLASS_INFO: {
// only need to do this once.
if (initialized_)
break;
// name_ is the class name // name_ is the class name
LayoutFileList const & list = LayoutFileList::get(); LayoutFileList const & list = LayoutFileList::get();
bool available = false; bool available = false;
if (list.haveClass(name_)) if (list.haveClass(name_))
available = list[name_].isTeXClassAvailable(); available = list[name_].isTeXClassAvailable();
setText(available ? _("yes") : _("no")); setText(available ? _("yes") : _("no"));
initialized_ = true;
break; break;
} }
case MENU_INFO: { case MENU_INFO: {
// only need to do this once.
if (initialized_)
break;
// and we will not keep trying if we fail
initialized_ = true;
docstring_list names; docstring_list names;
FuncRequest const func = lyxaction.lookupFunc(name_); FuncRequest const func = lyxaction.lookupFunc(name_);
if (func.action() == LFUN_UNKNOWN_ACTION) { if (func.action() == LFUN_UNKNOWN_ACTION) {
@ -406,6 +428,11 @@ void InsetInfo::updateInfo()
break; break;
} }
case ICON_INFO: { case ICON_INFO: {
// only need to do this once.
if (initialized_)
break;
// and we will not keep trying if we fail
initialized_ = true;
FuncRequest func = lyxaction.lookupFunc(name_); FuncRequest func = lyxaction.lookupFunc(name_);
docstring icon_name = frontend::Application::iconName(func, true); docstring icon_name = frontend::Application::iconName(func, true);
// FIXME: We should use the icon directly instead of // FIXME: We should use the icon directly instead of
@ -451,6 +478,7 @@ void InsetInfo::updateInfo()
break; break;
} }
case BUFFER_INFO: { case BUFFER_INFO: {
// this could all change, so we will recalculate each time
if (name_ == "name") { if (name_ == "name") {
setText(from_utf8(buffer().fileName().onlyFileName())); setText(from_utf8(buffer().fileName().onlyFileName()));
break; break;
@ -464,8 +492,12 @@ void InsetInfo::updateInfo()
break; break;
} }
////////////////////////////////////////////////////////////////
// everything that follows is for version control. // everything that follows is for version control.
// nothing that isn't version control should go below this line. // nothing that isn't version control should go below this line.
// this information could change, in principle, so we will
// recalculate each time through
if (!buffer().lyxvc().inUse()) { if (!buffer().lyxvc().inUse()) {
setText(_("No version control")); setText(_("No version control"));
break; break;
@ -489,10 +521,15 @@ void InsetInfo::updateInfo()
break; break;
} }
case LYX_INFO: case LYX_INFO:
// only need to do this once.
if (initialized_)
break;
if (name_ == "version") if (name_ == "version")
setText(from_ascii(lyx_version)); setText(from_ascii(lyx_version));
initialized_ = true;
break; break;
} }
InsetCollapsable::updateBuffer(it, utype);
} }

View File

@ -127,8 +127,8 @@ public:
void doDispatch(Cursor & cur, FuncRequest & cmd); void doDispatch(Cursor & cur, FuncRequest & cmd);
/// ///
void setInfo(std::string const & info); void setInfo(std::string const & info);
/// update info_ and text ///
void updateInfo(); void updateBuffer(ParIterator const & it, UpdateType utype);
/// ///
docstring toolTip(BufferView const & bv, int x, int y) const; docstring toolTip(BufferView const & bv, int x, int y) const;
/// ///
@ -148,6 +148,8 @@ private:
// make sure that the other version of setText is still available. // make sure that the other version of setText is still available.
using InsetCollapsable::setText; using InsetCollapsable::setText;
/// ///
bool initialized_;
///
info_type type_; info_type type_;
/// ///
std::string name_; std::string name_;