commit fbae68fec5cb09ee27c99b257eb7f5eb0350c6e0
Author: Juergen Spitzmueller <[email protected]>
Date:   Tue Aug 12 11:17:51 2025 +0200

    Fix xref target renaming with label lists (#13211)
---
 src/CutAndPaste.cpp       | 13 +++++++------
 src/insets/Inset.h        |  3 +++
 src/insets/InsetLabel.cpp |  4 ++--
 src/insets/InsetRef.cpp   | 32 ++++++++++++++++++++++++--------
 src/insets/InsetRef.h     |  6 +++++-
 5 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp
index b12fb15a7d..1349acec36 100644
--- a/src/CutAndPaste.cpp
+++ b/src/CutAndPaste.cpp
@@ -45,6 +45,7 @@
 #include "insets/InsetGraphicsParams.h"
 #include "insets/InsetInclude.h"
 #include "insets/InsetLabel.h"
+#include "insets/InsetRef.h"
 #include "insets/InsetTabular.h"
 
 #include "mathed/MathData.h"
@@ -342,9 +343,9 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList 
const & parlist,
                                for (InsetIterator itt = begin(in);
                                      itt != i_end; ++itt) {
                                        if (itt->lyxCode() == REF_CODE) {
-                                               InsetCommand * ref = 
itt->asInsetCommand();
-                                               if (ref->getParam("reference") 
== oldname)
-                                                       
ref->setParam("reference", newname);
+                                               InsetRef * ref = 
itt->asInsetRef();
+                                               if (ref->hasTarget(oldname))
+                                                       
ref->changeTarget(oldname, newname);
                                        } else if (itt->lyxCode() == 
MATH_REF_CODE) {
                                                InsetMathRef * mi = 
itt->asInsetMath()->asRefInset();
                                                // this is necessary to prevent 
an uninitialized
@@ -372,9 +373,9 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList 
const & parlist,
                        // adapt the references
                        for (InsetIterator itt = begin(in); itt != i_end; 
++itt) {
                                if (itt->lyxCode() == REF_CODE) {
-                                       InsetCommand & ref = 
static_cast<InsetCommand &>(*itt);
-                                       if (ref.getParam("reference") == 
oldname)
-                                               ref.setParam("reference", 
newname);
+                                       InsetRef & ref = static_cast<InsetRef 
&>(*itt);
+                                       if (ref.hasTarget(oldname))
+                                               ref.changeTarget(oldname, 
newname);
                                } else if (itt->lyxCode() == MATH_REF_CODE) {
                                        InsetMathRef * mi = 
itt->asInsetMath()->asRefInset();
                                        // this is necessary to prevent an 
uninitialized
diff --git a/src/insets/Inset.h b/src/insets/Inset.h
index b18f13fe34..5a47be6a7a 100644
--- a/src/insets/Inset.h
+++ b/src/insets/Inset.h
@@ -53,6 +53,7 @@ class InsetLayout;
 class InsetList;
 class InsetMath;
 class InsetNomencl;
+class InsetRef;
 class InsetTabular;
 class InsetText;
 class Language;
@@ -158,6 +159,8 @@ public:
        virtual InsetIndex const * asInsetIndex() const { return nullptr; }
        /// is this inset based on the InsetNomencl class?
        virtual InsetNomencl const * asInsetNomencl() const { return nullptr; }
+       /// is this inset based on the InsetIndex class?
+       virtual InsetRef * asInsetRef() { return nullptr; }
        /// is this inset based on the InsetGraphics class?
        virtual InsetGraphics * asInsetGraphics() { return nullptr; }
        /// is this inset based on the InsetGraphics class?
diff --git a/src/insets/InsetLabel.cpp b/src/insets/InsetLabel.cpp
index 4740e66bcf..d2057779dc 100644
--- a/src/insets/InsetLabel.cpp
+++ b/src/insets/InsetLabel.cpp
@@ -137,8 +137,8 @@ void InsetLabel::updateReferences(docstring const & 
old_label,
                                InsetMathRef * mi = 
p.first->asInsetMath()->asRefInset();
                                mi->changeTarget(new_label);
                        } else {
-                               InsetCommand * ref = p.first->asInsetCommand();
-                               ref->setParam("reference", new_label);
+                               InsetRef * ref = p.first->asInsetRef();
+                               ref->changeTarget(old_label, new_label);
                        }
                }
        }
diff --git a/src/insets/InsetRef.cpp b/src/insets/InsetRef.cpp
index 17c549f04f..4076d2aa20 100644
--- a/src/insets/InsetRef.cpp
+++ b/src/insets/InsetRef.cpp
@@ -99,18 +99,34 @@ docstring InsetRef::layoutName() const
 }
 
 
-void InsetRef::changeTarget(docstring const & new_label)
+bool InsetRef::hasTarget(docstring const & label) const
 {
+       vector<docstring> const labels = 
getVectorFromString(getParam("reference"));
+       return find(labels.begin(), labels.end(), label) != labels.end();
+}
+
+
+void InsetRef::changeTarget(docstring const & old_label, docstring const & 
new_label)
+{
+       // Subsitute old_label with new_label in the target list
+       vector<docstring> labels = getVectorFromString(getParam("reference"));
+       vector<docstring> newtargets;
+       for (docstring const & l : labels) {
+               if (l == old_label)
+                       newtargets.push_back(new_label);
+               else
+                       newtargets.push_back(l);
+       }
        // With change tracking, we insert a new ref
        // and delete the old one
-       if (buffer().masterParams().track_changes) {
+       if (isBufferValid() && buffer().masterParams().track_changes) {
                InsetCommandParams icp(REF_CODE, "ref");
-               icp["reference"] = new_label;
+               icp["reference"] = getStringFromVector(newtargets);
                string const data = InsetCommand::params2string(icp);
                lyx::dispatch(FuncRequest(LFUN_INSET_INSERT, data));
                lyx::dispatch(FuncRequest(LFUN_CHAR_DELETE_FORWARD));
        } else
-               setParam("reference", new_label);
+               setParam("reference", getStringFromVector(newtargets));
 }
 
 
@@ -137,11 +153,11 @@ void InsetRef::doDispatch(Cursor & cur, FuncRequest & cmd)
                else if (arg == "toggle-nolink")
                        pstring = "nolink";
                else if (arg == "changetarget") {
-                       string const oldtarget = cmd.getArg(2);
-                       string const newtarget = cmd.getArg(3);
+                       docstring const oldtarget = from_utf8(cmd.getArg(2));
+                       docstring const newtarget = from_utf8(cmd.getArg(3));
                        if (!oldtarget.empty() && !newtarget.empty()
-                           && getParam("reference") == from_utf8(oldtarget))
-                               changeTarget(from_utf8(newtarget));
+                           && hasTarget(oldtarget))
+                               changeTarget(oldtarget, newtarget);
                        cur.forceBufferUpdate();
                        return;
                }
diff --git a/src/insets/InsetRef.h b/src/insets/InsetRef.h
index 9b211d553b..2935507cc4 100644
--- a/src/insets/InsetRef.h
+++ b/src/insets/InsetRef.h
@@ -35,7 +35,9 @@ public:
        InsetRef(Buffer * buffer, InsetCommandParams const &);
 
        ///
-       void changeTarget(docstring const & new_label);
+       bool hasTarget(docstring const & label) const;
+       ///
+       void changeTarget(docstring const & old_label, docstring const & 
new_label);
 
        /// \name Public functions inherited from Inset class
        //@{
@@ -103,6 +105,8 @@ public:
        static docstring getFormattedCmd(docstring const & ref, 
std::vector<docstring> & label,
                        docstring & prefix, std::string const & xref_package,
                        bool use_caps = false, bool use_range = false);
+       ///
+       InsetRef * asInsetRef() override { return this; }
 
 protected:
        ///
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to