[LyX/master] Properly show labels from broken references in Cross-references dialog

Jean-Marc Lasgouttes lasgouttes at lyx.org
Sat Feb 19 16:49:36 UTC 2022


commit df59649a18f19486dc06b3e921272cea6d4ee343
Author: Daniel Ramöller <d.lyx at web.de>
Date:   Wed Feb 16 14:57:06 2022 +0100

    Properly show labels from broken references in Cross-references dialog
    
    Fix for bug #12456.
    
    The labels are transmitted from Buffer to GuiRef by reference of refs_
    in the getLabelList function. Previously, only one string was
    transmitted. But I needed both the formatted string, e.g. "x enu:test"
    or "Missing: enu:test", as well as the plain label, e.g. "enu:test".
    The former is for the list of labels to choose from in GuiRef and the
    latter for the label as shown in the line edit that contains the plain
    label in order to create a new reference from it. Transmitting both is
    what the pair achieves.
---
 src/Buffer.cpp              |    4 ++--
 src/Buffer.h                |    4 ++--
 src/TocBackend.cpp          |    7 +++++--
 src/TocBackend.h            |    7 ++++++-
 src/frontends/qt/GuiRef.cpp |   33 ++++++++++++++++++++-------------
 src/frontends/qt/GuiRef.h   |    5 +++--
 src/insets/InsetRef.cpp     |    4 +++-
 7 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 729d7a6..0a1f851 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -2389,7 +2389,7 @@ void Buffer::validate(LaTeXFeatures & features) const
 }
 
 
-void Buffer::getLabelList(vector<docstring> & list) const
+void Buffer::getLabelList(vector<std::pair<docstring, docstring>> & list) const
 {
 	// If this is a child document, use the master's list instead.
 	if (parent()) {
@@ -2401,7 +2401,7 @@ void Buffer::getLabelList(vector<docstring> & list) const
 	shared_ptr<Toc> toc = d->toc_backend.toc("label");
 	for (auto const & tocit : *toc) {
 		if (tocit.depth() == 0)
-			list.push_back(tocit.str());
+			list.push_back(make_pair(tocit.str(), tocit.asString()));
 	}
 }
 
diff --git a/src/Buffer.h b/src/Buffer.h
index 0d79ffa..7f40351 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -521,8 +521,8 @@ public:
 	void invalidateCiteLabels() const;
 	///
 	bool citeLabelsValid() const;
-	///
-	void getLabelList(std::vector<docstring> &) const;
+	/// two strings: plain label name and label as gui string
+	void getLabelList(std::vector<std::pair<docstring, docstring>> &) const;
 
 	/// This removes the .aux and .bbl files from the temp dir.
 	void removeBiblioTempFiles() const;
diff --git a/src/TocBackend.cpp b/src/TocBackend.cpp
index b3a36f1..859e6e8 100644
--- a/src/TocBackend.cpp
+++ b/src/TocBackend.cpp
@@ -43,8 +43,8 @@ namespace lyx {
 ///////////////////////////////////////////////////////////////////////////
 
 TocItem::TocItem(DocIterator const & dit, int d, docstring const & s,
-                 bool output_active, FuncRequest const & action)
-	: dit_(dit), depth_(d), str_(s), output_(output_active),
+                 bool output_active, bool missing, FuncRequest const & action)
+	: dit_(dit), depth_(d), str_(s), output_(output_active), missing_(missing),
 	  action_(action)
 {
 }
@@ -65,6 +65,9 @@ docstring const TocItem::asString() const
 		prefix += cross;
 		prefix += thin;
 	}
+	if (missing_) {
+		prefix += _("MISSING: ");
+	}
 	return prefix + str_;
 }
 
diff --git a/src/TocBackend.h b/src/TocBackend.h
index b67ee60..c3a178d 100644
--- a/src/TocBackend.h
+++ b/src/TocBackend.h
@@ -55,12 +55,13 @@ class TocItem
 {
 public:
 	/// Default constructor for STL containers.
-	TocItem() : dit_(0), depth_(0), output_(false) {}
+	TocItem() : dit_(0), depth_(0), output_(false), missing_(false) {}
 	///
 	TocItem(DocIterator const & dit,
 		int depth,
 		docstring const & s,
 		bool output_active,
+		bool missing = false,
 		FuncRequest const & action = FuncRequest(LFUN_UNKNOWN_ACTION)
 		);
 	///
@@ -74,6 +75,8 @@ public:
 	///
 	bool isOutput() const { return output_; }
 	///
+	bool isMissing() const { return missing_; }
+	///
 	void setAction(FuncRequest const & a) { action_ = a; }
 
 	/// custom action, or the default one (paragraph-goto) if not customised
@@ -92,6 +95,8 @@ private:
 	docstring str_;
 	/// Is this item in a note, inactive branch, etc?
 	bool output_;
+	/// Is this item missing, e.g. missing label?
+	bool missing_;
 	/// Custom action
 	FuncRequest action_;
 };
diff --git a/src/frontends/qt/GuiRef.cpp b/src/frontends/qt/GuiRef.cpp
index 2836190..9cb9d81 100644
--- a/src/frontends/qt/GuiRef.cpp
+++ b/src/frontends/qt/GuiRef.cpp
@@ -202,7 +202,7 @@ void GuiRef::refHighlighted(QTreeWidgetItem * sel)
 	bool const cur_item_selected = sel->isSelected();
 
 	if (cur_item_selected)
-		referenceED->setText(sel->text(0));
+		referenceED->setText(sel->data(0, Qt::UserRole).toString());
 
 	if (at_ref_)
 		gotoRef();
@@ -236,7 +236,7 @@ void GuiRef::refSelected(QTreeWidgetItem * sel)
 	bool const cur_item_selected = sel->isSelected();
 
 	if (cur_item_selected)
-		referenceED->setText(sel->text(0));
+		referenceED->setText(sel->data(0, Qt::UserRole).toString());
 	// <enter> or double click, inserts ref and closes dialog
 	slotOK();
 }
@@ -439,13 +439,17 @@ void GuiRef::redoRefs()
 	// the first item inserted
 	QString const oldSelection(referenceED->text());
 
-	QStringList refsStrings;
+	QStringList refsNames;
+	QStringList refsAsStrings;
 	QStringList refsCategories;
-	vector<docstring>::const_iterator iter;
+	vector<std::pair<docstring, docstring>>::const_iterator iter;
 	bool noprefix = false;
 	for (iter = refs_.begin(); iter != refs_.end(); ++iter) {
-		QString const lab = toqstr(*iter);
-		refsStrings.append(lab);
+		// the plain label name
+		QString const lab = toqstr((*iter).first);
+		refsNames.append(lab);
+		// the label as gui string
+		refsAsStrings.append(toqstr((*iter).second));
 		if (groupCB->isChecked()) {
 			if (lab.contains(":")) {
 				QString const pref = lab.split(':')[0];
@@ -470,10 +474,10 @@ void GuiRef::redoRefs()
 					sortingCO->itemData(sortingCO->currentIndex()).toString()
 					: QString();
 	if (sort_method == "nocase")
-		sort(refsStrings.begin(), refsStrings.end(),
+		sort(refsNames.begin(), refsNames.end(),
 			  caseInsensitiveLessThan /*defined above*/);
 	else if (sort_method == "case")
-		sort(refsStrings.begin(), refsStrings.end());
+		sort(refsNames.begin(), refsNames.end());
 
 	if (groupCB->isChecked()) {
 		QList<QTreeWidgetItem *> refsCats;
@@ -481,14 +485,15 @@ void GuiRef::redoRefs()
 			QString const & cat = refsCategories.at(i);
 			QTreeWidgetItem * item = new QTreeWidgetItem(refsTW);
 			item->setText(0, cat);
-			for (int j = 0; j < refsStrings.size(); ++j) {
-				QString const & ref = refsStrings.at(j);
+			for (int j = 0; j < refsNames.size(); ++j) {
+				QString const & ref = refsNames.at(j);
 				if ((ref.startsWith(cat + QString(":")))
 				    || (cat == qt_("<No prefix>")
 				       && (!ref.mid(1).contains(":") || ref.left(1).contains(":")))) {
 						QTreeWidgetItem * child =
 							new QTreeWidgetItem(item);
-						child->setText(0, ref);
+						item->setText(0, refsAsStrings.at(j));
+						item->setData(0, Qt::UserRole, ref);
 						item->addChild(child);
 				}
 			}
@@ -497,9 +502,11 @@ void GuiRef::redoRefs()
 		refsTW->addTopLevelItems(refsCats);
 	} else {
 		QList<QTreeWidgetItem *> refsItems;
-		for (int i = 0; i < refsStrings.size(); ++i) {
+		for (int i = 0; i < refsNames.size(); ++i) {
 			QTreeWidgetItem * item = new QTreeWidgetItem(refsTW);
-			item->setText(0, refsStrings.at(i));
+			QString const & ref = refsNames.at(i);
+			item->setText(0, refsAsStrings.at(i));
+			item->setData(0, Qt::UserRole, ref);
 			refsItems.append(item);
 		}
 		refsTW->addTopLevelItems(refsItems);
diff --git a/src/frontends/qt/GuiRef.h b/src/frontends/qt/GuiRef.h
index 02ef307..4bd50e5 100644
--- a/src/frontends/qt/GuiRef.h
+++ b/src/frontends/qt/GuiRef.h
@@ -106,8 +106,9 @@ private:
 	int restored_buffer_;
 	/// store the last active buffer
 	int active_buffer_;
-	/// the references
-	std::vector<docstring> refs_;
+	/// the references as two strings: plain label name and label as gui string
+	/// FIXME: might be a good idea to use a custom struct
+	std::vector<std::pair<docstring, docstring>> refs_;
 };
 
 } // namespace frontend
diff --git a/src/insets/InsetRef.cpp b/src/insets/InsetRef.cpp
index 716f8a7..eab3e69 100644
--- a/src/insets/InsetRef.cpp
+++ b/src/insets/InsetRef.cpp
@@ -537,7 +537,9 @@ void InsetRef::addToToc(DocIterator const & cpit, bool output_active,
 	broken_ = true;
 	setBroken(broken_);
 	shared_ptr<Toc> toc = backend.toc("label");
-	toc->push_back(TocItem(cpit, 0, screenLabel(), output_active));
+	if (TocBackend::findItem(*toc, 0, label) == toc->end())
+		toc->push_back(TocItem(cpit, 0, label, output_active, true));
+	toc->push_back(TocItem(cpit, 1, screenLabel(), output_active));
 	shared_ptr<Toc> toc2 = backend.toc("brokenrefs");
 	toc2->push_back(TocItem(cpit, 0, screenLabel(), output_active));
 }


More information about the lyx-cvs mailing list