Display equation/theorem numbers in insert cross reference dialog.

Fixes bug #11466,
This commit is contained in:
Alexander Dunlap 2023-07-26 13:35:42 -04:00 committed by Richard Kimberly Heck
parent 7f4c4cd548
commit c609e9cbcf
13 changed files with 95 additions and 46 deletions

View File

@ -2422,7 +2422,7 @@ void Buffer::validate(LaTeXFeatures & features) const
} }
void Buffer::getLabelList(vector<std::pair<docstring, docstring>> & list) const void Buffer::getLabelList(vector<std::tuple<docstring, docstring, docstring>> & list) const
{ {
// If this is a child document, use the master's list instead. // If this is a child document, use the master's list instead.
if (parent()) { if (parent()) {
@ -2433,8 +2433,9 @@ void Buffer::getLabelList(vector<std::pair<docstring, docstring>> & list) const
list.clear(); list.clear();
shared_ptr<Toc> toc = d->toc_backend.toc("label"); shared_ptr<Toc> toc = d->toc_backend.toc("label");
for (auto const & tocit : *toc) { for (auto const & tocit : *toc) {
if (tocit.depth() == 0) if (tocit.depth() == 0) {
list.push_back(make_pair(tocit.str(), tocit.asString())); list.push_back(make_tuple(tocit.str(), tocit.asString(),tocit.prettyStr()));
}
} }
} }

View File

@ -534,8 +534,9 @@ public:
void invalidateCiteLabels() const; void invalidateCiteLabels() const;
/// ///
bool citeLabelsValid() const; bool citeLabelsValid() const;
/// two strings: plain label name and label as gui string /// three strings: plain label name, label as gui string, and
void getLabelList(std::vector<std::pair<docstring, docstring>> &) const; /// dereferenced label name
void getLabelList(std::vector<std::tuple<docstring, docstring, docstring>> &) const;
/// This removes the .aux and .bbl files from the temp dir. /// This removes the .aux and .bbl files from the temp dir.
void removeBiblioTempFiles() const; void removeBiblioTempFiles() const;

View File

@ -42,9 +42,10 @@ Counter::Counter()
Counter::Counter(docstring const & mc, docstring const & ls, Counter::Counter(docstring const & mc, docstring const & ls,
docstring const & lsa, docstring const & guiname) docstring const & lsa, docstring const & prettyformat,
docstring const & guiname)
: initial_value_(0), saved_value_(0), parent_(mc), labelstring_(ls), : initial_value_(0), saved_value_(0), parent_(mc), labelstring_(ls),
labelstringappendix_(lsa), guiname_(guiname) labelstringappendix_(lsa), prettyformat_(prettyformat), guiname_(guiname)
{ {
reset(); reset();
} }
@ -130,6 +131,12 @@ bool Counter::read(Lexer & lex)
getout = true; getout = true;
break; break;
} }
if (prettyformat_ == "") { // fall back on GuiName if PrettyFormat is empty
if (guiname_ == "")
prettyformat_ = from_ascii("##");
else
prettyformat_ = "## (" + guiname_ + " counter)";
}
} }
// Here if have a full counter if getout == true // Here if have a full counter if getout == true
@ -220,6 +227,7 @@ void Counters::newCounter(docstring const & newc,
docstring const & parentc, docstring const & parentc,
docstring const & ls, docstring const & ls,
docstring const & lsa, docstring const & lsa,
docstring const & prettyformat,
docstring const & guiname) docstring const & guiname)
{ {
if (!parentc.empty() && !hasCounter(parentc)) { if (!parentc.empty() && !hasCounter(parentc)) {
@ -228,7 +236,7 @@ void Counters::newCounter(docstring const & newc,
<< endl; << endl;
return; return;
} }
counterList_[newc] = Counter(parentc, ls, lsa, guiname); counterList_[newc] = Counter(parentc, ls, lsa, prettyformat, guiname);
} }
@ -344,7 +352,7 @@ void Counters::stepParent(docstring const & ctr, UpdateType utype)
} }
void Counters::step(docstring const & ctr, UpdateType utype) void Counters::step(docstring const & ctr, UpdateType /* deleted */)
{ {
CounterList::iterator it = counterList_.find(ctr); CounterList::iterator it = counterList_.find(ctr);
if (it == counterList_.end()) { if (it == counterList_.end()) {
@ -354,11 +362,9 @@ void Counters::step(docstring const & ctr, UpdateType utype)
} }
it->second.step(); it->second.step();
if (utype == OutputUpdate) {
LBUFERR(!counter_stack_.empty()); LBUFERR(!counter_stack_.empty());
counter_stack_.pop_back(); counter_stack_.pop_back();
counter_stack_.push_back(ctr); counter_stack_.push_back(ctr);
}
resetChildren(ctr); resetChildren(ctr);
} }

View File

@ -35,7 +35,8 @@ public:
Counter(); Counter();
/// ///
Counter(docstring const & mc, docstring const & ls, Counter(docstring const & mc, docstring const & ls,
docstring const & lsa, docstring const & guiname); docstring const & lsa, docstring const & prettyformat,
docstring const & guiname);
/// \return true on success /// \return true on success
bool read(Lexer & lex); bool read(Lexer & lex);
/// ///
@ -129,6 +130,7 @@ public:
docstring const & parentc, docstring const & parentc,
docstring const & ls, docstring const & ls,
docstring const & lsa, docstring const & lsa,
docstring const & prettyformat,
docstring const & guiname); docstring const & guiname);
/// Checks whether the given counter exists. /// Checks whether the given counter exists.
bool hasCounter(docstring const & c) const; bool hasCounter(docstring const & c) const;

View File

@ -1624,11 +1624,13 @@ bool TextClass::readFloat(Lexer & lexrc)
// each float has its own counter // each float has its own counter
counters_.newCounter(from_ascii(type), from_ascii(within), counters_.newCounter(from_ascii(type), from_ascii(within),
docstring(), docstring(), docstring(), docstring(),
bformat(_("%1$s ##"), _(name)),
bformat(_("%1$s (Float)"), _(name))); bformat(_("%1$s (Float)"), _(name)));
// also define sub-float counters // also define sub-float counters
docstring const subtype = "sub-" + from_ascii(type); docstring const subtype = "sub-" + from_ascii(type);
counters_.newCounter(subtype, from_ascii(type), counters_.newCounter(subtype, from_ascii(type),
"\\alph{" + subtype + "}", docstring(), "\\alph{" + subtype + "}", docstring(),
bformat(_("Sub-%1$s ##"), _(name)),
bformat(_("Sub-%1$s (Float)"), _(name))); bformat(_("Sub-%1$s (Float)"), _(name)));
} }
return getout; return getout;

View File

@ -73,6 +73,10 @@ public:
/// ///
void str(docstring const & s) { str_ = s; } void str(docstring const & s) { str_ = s; }
/// ///
docstring const & prettyStr() const { return pretty_str_; }
///
void prettyStr (docstring const & s) { pretty_str_ = s; }
///
bool isOutput() const { return output_; } bool isOutput() const { return output_; }
/// ///
bool isMissing() const { return missing_; } bool isMissing() const { return missing_; }
@ -93,6 +97,8 @@ private:
int depth_; int depth_;
/// Full item string /// Full item string
docstring str_; docstring str_;
/// Dereferenced name, for labels (e.g. Label 5.2 instead of lem:foobar)
docstring pretty_str_;
/// Is this item in a note, inactive branch, etc? /// Is this item in a note, inactive branch, etc?
bool output_; bool output_;
/// Is this item missing, e.g. missing label? /// Is this item missing, e.g. missing label?

View File

@ -73,9 +73,6 @@ GuiRef::GuiRef(GuiView & lv)
buttonBox->button(QDialogButtonBox::Reset)->setText(qt_("&Update")); buttonBox->button(QDialogButtonBox::Reset)->setText(qt_("&Update"));
buttonBox->button(QDialogButtonBox::Reset)->setToolTip(qt_("Update the label list")); buttonBox->button(QDialogButtonBox::Reset)->setToolTip(qt_("Update the label list"));
refsTW->setColumnCount(1);
refsTW->header()->setVisible(false);
connect(this, SIGNAL(rejected()), this, SLOT(dialogRejected())); connect(this, SIGNAL(rejected()), this, SLOT(dialogRejected()));
connect(typeCO, SIGNAL(activated(int)), connect(typeCO, SIGNAL(activated(int)),
@ -423,9 +420,9 @@ void GuiRef::gotoRef()
at_ref_ = !at_ref_; at_ref_ = !at_ref_;
} }
inline bool caseInsensitiveLessThanVec(QPair<QString, QString> const & s1, QPair<QString, QString> const & s2) inline bool caseInsensitiveLessThanVec(std::tuple<QString, QString, QString> const & s1, std::tuple<QString, QString, QString> const & s2)
{ {
return s1.first.toLower() < s2.first.toLower(); return std::get<0>(s1).toLower() < std::get<0>(s2).toLower();
} }
inline bool caseInsensitiveLessThan(QString const & s1, QString const & s2) inline bool caseInsensitiveLessThan(QString const & s1, QString const & s2)
@ -448,17 +445,19 @@ void GuiRef::redoRefs()
// the first item inserted // the first item inserted
QString const oldSelection(referenceED->text()); QString const oldSelection(referenceED->text());
// Plain label and GUI string. This might get resorted below // Plain label, GUI string, and dereferenced string.
QVector<QPair<QString, QString>> refsNames; // This might get resorted below
QVector<std::tuple<QString, QString,QString>> refsNames;
// List of categories (prefixes) // List of categories (prefixes)
QStringList refsCategories; QStringList refsCategories;
// Do we have a prefix-less label at all? // Do we have a prefix-less label at all?
bool noprefix = false; bool noprefix = false;
vector<std::pair<docstring, docstring>>::const_iterator iter; vector<std::tuple<docstring, docstring,docstring>>::const_iterator iter;
for (iter = refs_.begin(); iter != refs_.end(); ++iter) { for (iter = refs_.begin(); iter != refs_.end(); ++iter) {
// first: plain label name, second: gui name // first: plain label name, second: gui name, third: pretty name
QString const lab = toqstr((*iter).first); QString const lab = toqstr(std::get<0>(*iter));
refsNames.append({lab, toqstr((*iter).second)}); refsNames.append({lab, toqstr(std::get<1>(*iter)),
toqstr(std::get<2>(*iter))});
if (groupCB->isChecked()) { if (groupCB->isChecked()) {
if (lab.contains(":")) { if (lab.contains(":")) {
QString const pref = lab.split(':')[0]; QString const pref = lab.split(':')[0];
@ -473,7 +472,7 @@ void GuiRef::redoRefs()
noprefix = true; noprefix = true;
} }
} }
// sort categories case-intensively // sort categories case-insensitively
sort(refsCategories.begin(), refsCategories.end(), sort(refsCategories.begin(), refsCategories.end(),
caseInsensitiveLessThan /*defined above*/); caseInsensitiveLessThan /*defined above*/);
if (noprefix) if (noprefix)
@ -496,15 +495,17 @@ void GuiRef::redoRefs()
QTreeWidgetItem * item = new QTreeWidgetItem(refsTW); QTreeWidgetItem * item = new QTreeWidgetItem(refsTW);
item->setText(0, cat); item->setText(0, cat);
for (int j = 0; j < refsNames.size(); ++j) { for (int j = 0; j < refsNames.size(); ++j) {
QString const ref = refsNames.at(j).first; QString const ref = std::get<0>(refsNames.at(j));
if ((ref.startsWith(cat + QString(":"))) if ((ref.startsWith(cat + QString(":")))
|| (cat == qt_("<No prefix>") || (cat == qt_("<No prefix>")
&& (!ref.mid(1).contains(":") || ref.left(1).contains(":")))) { && (!ref.mid(1).contains(":") || ref.left(1).contains(":")))) {
QTreeWidgetItem * child = QTreeWidgetItem * child =
new QTreeWidgetItem(item); new QTreeWidgetItem(item);
QString const val = refsNames.at(j).second; QString const val = std::get<1>(refsNames.at(j));
QString const pretty = std::get<2>(refsNames.at(j));
child->setText(0, val); child->setText(0, val);
child->setData(0, Qt::UserRole, ref); child->setData(0, Qt::UserRole, ref);
child->setText(1, pretty);
item->addChild(child); item->addChild(child);
} }
} }
@ -515,10 +516,12 @@ void GuiRef::redoRefs()
QList<QTreeWidgetItem *> refsItems; QList<QTreeWidgetItem *> refsItems;
for (int i = 0; i < refsNames.size(); ++i) { for (int i = 0; i < refsNames.size(); ++i) {
QTreeWidgetItem * item = new QTreeWidgetItem(refsTW); QTreeWidgetItem * item = new QTreeWidgetItem(refsTW);
QString const ref = refsNames.at(i).first; QString const ref = std::get<0>(refsNames.at(i));
QString const val = refsNames.at(i).second; QString const val = std::get<1>(refsNames.at(i));
QString const pretty = std::get<2>(refsNames.at(i));
item->setText(0, val); item->setText(0, val);
item->setData(0, Qt::UserRole, ref); item->setData(0, Qt::UserRole, ref);
item->setText(1, pretty);
refsItems.append(item); refsItems.append(item);
} }
refsTW->addTopLevelItems(refsItems); refsTW->addTopLevelItems(refsItems);
@ -605,6 +608,7 @@ void GuiRef::filterLabels()
(*it)->setHidden( (*it)->setHidden(
(*it)->childCount() == 0 (*it)->childCount() == 0
&& !(*it)->text(0).contains(filter_->text(), cs) && !(*it)->text(0).contains(filter_->text(), cs)
&& !(*it)->text(1).contains(filter_->text(), cs)
); );
++it; ++it;
} }

View File

@ -106,9 +106,10 @@ private:
int restored_buffer_; int restored_buffer_;
/// store the last active buffer /// store the last active buffer
int active_buffer_; int active_buffer_;
/// the references as two strings: plain label name and label as gui string /// the references as three strings: plain label name, label as gui
/// string, and pretty dereferenced name ("Lemma 3")
/// FIXME: might be a good idea to use a custom struct /// FIXME: might be a good idea to use a custom struct
std::vector<std::pair<docstring, docstring>> refs_; std::vector<std::tuple<docstring, docstring, docstring>> refs_;
}; };
} // namespace frontend } // namespace frontend

View File

@ -19,9 +19,23 @@
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0"> <item row="2" column="0">
<widget class="QTreeWidget" name="refsTW"> <widget class="QTreeWidget" name="refsTW">
<property name="columnCount">
<number>2</number>
</property>
<attribute name="headerDefaultSectionSize">
<number>200</number>
</attribute>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
<column> <column>
<property name="text"> <property name="text">
<string>1</string> <string>Label</string>
</property>
</column>
<column>
<property name="text">
<string>Reference counter value</string>
</property> </property>
</column> </column>
</widget> </widget>

View File

@ -164,6 +164,7 @@ void InsetFlex::updateBuffer(ParIterator const & it, UpdateType utype, bool cons
docstring const eqlabel = deleted ? from_ascii("#") docstring const eqlabel = deleted ? from_ascii("#")
: cnts.theCounter(equation, it->getParLanguage(bp)->code()); : cnts.theCounter(equation, it->getParLanguage(bp)->code());
cnts.newCounter(equation, parentequation, cnts.newCounter(equation, parentequation,
eqlabel + from_ascii("\\alph{equation}"),
eqlabel + from_ascii("\\alph{equation}"), eqlabel + from_ascii("\\alph{equation}"),
eqlabel + from_ascii("\\alph{equation}"), eqlabel + from_ascii("\\alph{equation}"),
cnts.guiName(parentequation)); cnts.guiName(parentequation));

View File

@ -156,7 +156,7 @@ docstring InsetLabel::screenLabel() const
} }
void InsetLabel::updateBuffer(ParIterator const & it, UpdateType utype, bool const /*deleted*/) void InsetLabel::updateBuffer(ParIterator const & it, UpdateType, bool const /*deleted*/)
{ {
docstring const & label = getParam("name"); docstring const & label = getParam("name");
@ -184,20 +184,25 @@ void InsetLabel::updateBuffer(ParIterator const & it, UpdateType utype, bool con
buffer().setInsetLabel(label, this, active); buffer().setInsetLabel(label, this, active);
screen_label_ = label; screen_label_ = label;
if (utype == OutputUpdate) {
// save info on the active counter // save info on the active counter
Counters const & cnts = Counters & cnts =
buffer().masterBuffer()->params().documentClass().counters(); buffer().masterBuffer()->params().documentClass().counters();
active_counter_ = cnts.currentCounter(); active_counter_ = cnts.currentCounter();
Language const * lang = it->getParLanguage(buffer().params()); Language const * lang = it->getParLanguage(buffer().params());
if (lang && !active_counter_.empty()) { if (lang && !active_counter_.empty()) {
if (active_counter_ != from_ascii("equation")) {
counter_value_ = cnts.theCounter(active_counter_, lang->code()); counter_value_ = cnts.theCounter(active_counter_, lang->code());
pretty_counter_ = cnts.prettyCounter(active_counter_, lang->code()); pretty_counter_ = cnts.prettyCounter(active_counter_, lang->code());
} else {
// For equations, the counter value and pretty counter
// value will be set by the parent InsetMathHull.
counter_value_ = from_ascii("#");
pretty_counter_ = from_ascii("");
}
} else { } else {
counter_value_ = from_ascii("#"); counter_value_ = from_ascii("#");
pretty_counter_ = from_ascii("#"); pretty_counter_ = from_ascii("#");
} }
}
} }
@ -212,7 +217,9 @@ void InsetLabel::addToToc(DocIterator const & cpit, bool output_active,
// We put both active and inactive labels to the outliner // We put both active and inactive labels to the outliner
shared_ptr<Toc> toc = backend.toc("label"); shared_ptr<Toc> toc = backend.toc("label");
toc->push_back(TocItem(cpit, 0, screen_label_, output_active)); TocItem toc_item = TocItem(cpit, 0, screen_label_, output_active);
toc_item.prettyStr(pretty_counter_);
toc->push_back(toc_item);
// The refs get assigned only to the active label. If no active one exists, // The refs get assigned only to the active label. If no active one exists,
// assign the (BROKEN) refs to the first inactive one. // assign the (BROKEN) refs to the first inactive one.
if (buffer().insetLabel(label, true) == this || !buffer().activeLabel(label)) { if (buffer().insetLabel(label, true) == this || !buffer().activeLabel(label)) {

View File

@ -30,6 +30,8 @@ public:
/// ///
docstring const & prettyCounter() const { return pretty_counter_; } docstring const & prettyCounter() const { return pretty_counter_; }
/// ///
void setPrettyCounter(docstring pc) { pretty_counter_ = pc; }
///
int rowFlags() const override { return CanBreakBefore | CanBreakAfter; } int rowFlags() const override { return CanBreakBefore | CanBreakAfter; }
/// Updates only the label string, doesn't handle undo nor references. /// Updates only the label string, doesn't handle undo nor references.
void updateLabel(docstring const & new_label, bool const active = true); void updateLabel(docstring const & new_label, bool const active = true);

View File

@ -313,8 +313,10 @@ void InsetMathHull::addToToc(DocIterator const & pit, bool output_active,
for (row_type row = 0; row != nrows(); ++row) { for (row_type row = 0; row != nrows(); ++row) {
if (!numbered(row)) if (!numbered(row))
continue; continue;
if (label_[row]) if (label_[row]) {
label_[row]->setPrettyCounter(_("Equation ") + numbers_[row]);
label_[row]->addToToc(pit, output_active, utype, backend); label_[row]->addToToc(pit, output_active, utype, backend);
}
docstring label = nicelabel(row); docstring label = nicelabel(row);
if (first == last) if (first == last)
// this is the only equation // this is the only equation