Jean-Marc Lasgouttes wrote: > Juergen> I thought it is better to not go the complicated way if the > Juergen> inset contains only one item (which should be the common > Juergen> case). That's my real life thinking perhaps. I can delete the > Juergen> first statement if you wish. In theory, it should just work. > > I'd prefer that indeed. > > Real life speed is probably comparable (and the difference will be > smaller with the insetcommand code that has been posted recently).
OK. Changed. > I'd rather do > + if (getContents() == from) > + setContents(to); > but it is not very important. Changed. > + BOOST_ASSERT(code == InsetBase::CITE_CODE || InsetBase::REF_CODE); > > This is wrong. Oops. That wasn't intended. > > > + for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) { > + if (it->lyxCode() == code) { > + InsetCommand & inset = dynamic_cast<InsetCommand > &>(*it); > > Do we use dynamic_cast yet? Lars? Yes, we use them in buffer.C in several places (fillwithBibKeys, for instance). Attached another version. I have noted a final drawback now, though: The refs are not changed in the master/child documents. It would be easy to go to the master by adding something like in fillWithBibKeys: /// if this is a child document and the parent is already loaded /// use the parent's list instead [ale990412] Buffer const * tmp = getMasterBuffer(); BOOST_ASSERT(tmp); if (tmp != this) { tmp->changeRefsIfUnique(from, to, code); return; } However, insetIterator does not enter child documents. The solution for fillWithBibKeys, getLabelList etc. are methods in insetinclude. I do not like this and I'm reluctant to adding another funtion there for the sake of changeRefsIfUnique. Isn't it possible to make insetInterator enter the included documents? Jürgen > JMarc
Index: src/insets/insetlabel.C =================================================================== --- src/insets/insetlabel.C (Revision 15173) +++ 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 15173) +++ 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 15173) +++ 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 15173) +++ 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 15173) +++ src/insets/insetcommand.C (Arbeitskopie) @@ -156,6 +156,13 @@ } +void InsetCommand::replaceContents(std::string const & from, string const & to) +{ + if (getContents() == from) + setContents(to); +} + + InsetCommandMailer::InsetCommandMailer(string const & name, InsetCommand & inset) : name_(name), inset_(inset) Index: src/insets/insetcite.C =================================================================== --- src/insets/insetcite.C (Revision 15173) +++ 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,14 @@ break; } } + + +void InsetCitation::replaceContents(string const & from, string const & to) +{ + 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 15173) +++ 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 15173) +++ 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 || 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 15173) +++ 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