Jean-Marc Lasgouttes wrote: > Very good. Let's start from there, then. > > --- src/insets/insetcommand.h (Revision 15150) > +++ src/insets/insetcommand.h (Arbeitskopie) > @@ -72,6 +72,8 @@ > p_.setContents(c); > } > /// > + void replaceContents(std::string const & from, std::string const & to); > + /// > > If you make this method virtual, then in replaceRefsIfUnique below you will > not have to test on lyxCode.
Ah, I see. That's was I was looking for, obviously. > +void InsetCitation::replaceContents(string const & from, string const & > to) +{ > + if (getContents() == from) > + setContents(to); > + else if (tokenPos(getContents(), ',', from) != -1) { > + vector<string> items = getVectorFromString(getContents()); > + replace(items.begin(), items.end(), from, to); > + setContents(getStringFromVector(items)); > + } > +} > > I would have thought that the 'else' part is enough. Is it necessary > to handle the case where there is no ','? I thought it is better to not go the complicated way if the inset contains only one item (which should be the common case). That's my real life thinking perhaps. I can delete the first statement if you wish. In theory, it should just work. > BOOST_ASSERT(code == InsetBase::CITE_CODE || code == InsetBase::REF_CODE); OK. > A question I had is "why is the IfUnique" part useful? What are the > use cases? Consider you copy a range of text containing labels in your document, which contains duplicate labels (because you have copied it from somewhere else in the document, for instance). If you rename the duplicated label now, all references would be renamed, too. The IfUnique part prevents this. I will present a solution which prevents this special case after this patch is in, but there are other such cases, and I feel really safer if we keep the unique check. > With a virtual replaceContents, there would be no need to test > lyxCode() == InsetBase::CITE_CODE. Yes, looks much nicer now. > We are progressing :) Well, you transform my code into something useful, as always. Is there still something missing? Thanks, Jürgen > JMarc
Index: src/insets/insetlabel.C =================================================================== --- src/insets/insetlabel.C (Revision 15150) +++ src/insets/insetlabel.C (Arbeitskopie) @@ -71,7 +71,7 @@ } if (p.getContents() != params().getContents()) cur.bv().buffer()->changeRefsIfUnique(params().getContents(), - p.getContents()); + p.getContents(), InsetBase::REF_CODE); setParams(p); break; } Index: src/insets/insetcommand.h =================================================================== --- src/insets/insetcommand.h (Revision 15150) +++ src/insets/insetcommand.h (Arbeitskopie) @@ -72,6 +72,8 @@ p_.setContents(c); } /// + virtual void replaceContents(std::string const & from, std::string const & to); + /// std::string const & getOptions() const { return p_.getOptions(); } /// std::string const & getSecOptions() const { return p_.getSecOptions(); } Index: src/insets/insetcite.h =================================================================== --- src/insets/insetcite.h (Revision 15150) +++ src/insets/insetcite.h (Arbeitskopie) @@ -43,6 +43,8 @@ OutputParams const &) const; /// void validate(LaTeXFeatures &) const; + /// + void replaceContents(std::string const & from, std::string const & to); private: virtual std::auto_ptr<InsetBase> doClone() const Index: src/insets/insetbibitem.C =================================================================== --- src/insets/insetbibitem.C (Revision 15150) +++ src/insets/insetbibitem.C (Arbeitskopie) @@ -61,10 +61,14 @@ case LFUN_INSET_MODIFY: { InsetCommandParams p; InsetCommandMailer::string2params("bibitem", cmd.argument, p); - if (!p.getCmdName().empty()) - setParams(p); - else + if (p.getCmdName().empty()) { cur.noUpdate(); + break; + } + if (p.getContents() != params().getContents()) + cur.bv().buffer()->changeRefsIfUnique(params().getContents(), + p.getContents(), InsetBase::CITE_CODE); + setParams(p); break; } Index: src/insets/insetcommand.C =================================================================== --- src/insets/insetcommand.C (Revision 15150) +++ src/insets/insetcommand.C (Arbeitskopie) @@ -156,6 +156,14 @@ } +void InsetCommand::replaceContents(std::string const & from, string const & to) +{ + if (getContents() != from) + return; + setContents(to); +} + + InsetCommandMailer::InsetCommandMailer(string const & name, InsetCommand & inset) : name_(name), inset_(inset) Index: src/insets/insetcite.C =================================================================== --- src/insets/insetcite.C (Revision 15150) +++ src/insets/insetcite.C (Arbeitskopie) @@ -28,14 +28,19 @@ #include <boost/filesystem/operations.hpp> +#include <algorithm> + using lyx::support::ascii_lowercase; using lyx::support::contains; using lyx::support::getVectorFromString; +using lyx::support::getStringFromVector; using lyx::support::ltrim; using lyx::support::rtrim; using lyx::support::split; +using lyx::support::tokenPos; using std::endl; +using std::replace; using std::string; using std::ostream; using std::vector; @@ -430,3 +435,16 @@ break; } } + + +void InsetCitation::replaceContents(string const & from, string const & to) +{ + if (getContents() == from) + setContents(to); + else if (tokenPos(getContents(), ',', from) != -1) { + vector<string> items = getVectorFromString(getContents()); + replace(items.begin(), items.end(), from, to); + setContents(getStringFromVector(items)); + } +} + Index: src/mathed/math_hullinset.C =================================================================== --- src/mathed/math_hullinset.C (Revision 15150) +++ src/mathed/math_hullinset.C (Arbeitskopie) @@ -1078,7 +1078,7 @@ numbered(r, true); string old = label(r); if (str != old) { - cur.bv().buffer()->changeRefsIfUnique(old, str); + cur.bv().buffer()->changeRefsIfUnique(old, str, InsetBase::REF_CODE); label(r, str); } break; Index: src/buffer.C =================================================================== --- src/buffer.C (Revision 15150) +++ src/buffer.C (Arbeitskopie) @@ -67,7 +67,7 @@ #include "support/lyxalgo.h" #include "support/filetools.h" #include "support/fs_extras.h" -# include "support/gzstream.h" +#include "support/gzstream.h" #include "support/lyxlib.h" #include "support/os.h" #include "support/path.h" @@ -1612,31 +1612,30 @@ } -void Buffer::changeRefsIfUnique(string const & from, string const & to) +void Buffer::changeRefsIfUnique(string const & from, string const & to, InsetBase::Code code) { + BOOST_ASSERT(code == InsetBase::CITE_CODE || InsetBase::REF_CODE); // Check if the label 'from' appears more than once vector<string> labels; - getLabelList(labels); + if (code == InsetBase::CITE_CODE) { + vector<pair<string, string> > keys; + fillWithBibKeys(keys); + vector<pair<string, string> >::const_iterator bit = keys.begin(); + vector<pair<string, string> >::const_iterator bend = keys.end(); + + for (; bit != bend; ++bit) + labels.push_back(bit->first); + } else + getLabelList(labels); + if (lyx::count(labels.begin(), labels.end(), from) > 1) return; - InsetBase::Code code = InsetBase::REF_CODE; - - ParIterator it = par_iterator_begin(); - ParIterator end = par_iterator_end(); - for ( ; it != end; ++it) { - bool changed_inset = false; - for (InsetList::iterator it2 = it->insetlist.begin(); - it2 != it->insetlist.end(); ++it2) { - if (it2->inset->lyxCode() == code) { - InsetCommand * inset = static_cast<InsetCommand *>(it2->inset); - if (inset->getContents() == from) { - inset->setContents(to); - //inset->setButtonLabel(); - changed_inset = true; - } - } + for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) { + if (it->lyxCode() == code) { + InsetCommand & inset = dynamic_cast<InsetCommand &>(*it); + inset.replaceContents(from, to); } } } Index: src/buffer.h =================================================================== --- src/buffer.h (Revision 15150) +++ src/buffer.h (Arbeitskopie) @@ -343,7 +343,7 @@ /// StableDocIterator getAnchor() const { return anchor_; } /// - void changeRefsIfUnique(std::string const & from, std::string const & to); + void changeRefsIfUnique(std::string const & from, std::string const & to, InsetBase::Code code); private: /** Inserts a file into a document