I think we're nearing a solution.
You've got two parallel
representations of the parameters, one in the EmbeddedFileList and one
in the InsetCommandParams, and there is simply no way to guarantee that
they are synchronized and therefore that you don't over-write
information that was committed to one of them from elsewhere. For
example, you can do this:
setParam("bibfiles", bibfilelist);
but then what happens with the metaInfo? Nothing. Or you can do this:
setParams(p); // InsetCommandParams(p)
and again we're out of sync. You can override those methods, I suppose,
but then I can do this:
p_["bibfiles"] = bibfilelist;
What I was proposing was the use of EmbeddedFileList, and convert to
and from params ONLY during construction, and file export. There
should be no more conversion and synchronization between them, so less
confusion.
But the point is that you simply can't enforce this, not without a lot
more code, and maybe not at all. The failure to keep to this policy is
precisely the cause of the problems I have been trying to solve.
The problems I originally encountered were precisely in this area. Of
course, if one were extremely careful not to use the methods of setting
parameters, etc, that the InsetCommand infrastructure provides, then we
won't have these problems. But surely we will have these problems,
because all of that is so natural to do.
Exactly because we need more information, we need to code around the
structure with more information, that is EmbeddedFileList. Setting
params directly should be discouraged, at least in InsetBibtex.
Discouraged? How? My worry is that this is unmaintainable.
This doesn't mean you can't have the EmbeddedFile objects in the insets.
You can if you like. But what you cannot do is use them to represent the
parameter information. It would be trivial to add this sort of thing to
my patch: Give InsetBibtex an EmbeddedFileList, and then, whenever it is
needed, update it with information from the InsetCommandParams. But the
only difference between this approach and mine is that I don't keep this
list around but construct it from scratch when it's needed.
The problem is that EmbeddedFile(s) should be kept consistently, and
should not be created on the fly. Because params does not have all the
information EmbeddedFile needs, you will have to enable a file each
time, and you will have a hard choice of whether or not you need to
move files around. With a consistent EmbeddedFile object, you *know*
the embedded files is there, and whether or not it needs to be
updated.
Yes, I see this issue. So maybe you also want the EmbeddedFile object,
and we can do that.
Take my patch and add an EmbeddedFileList, but do NOT use it to
represent the parameters. Then we can restore a lot of the code you had,
but we just have to make sure that the EmbeddedFileList gets updated
from the parameters whenever it is used. So setBuffer() would look like
this:
void InsetBibtex::setBuffer(Buffer & buffer)
{
+ // FIXME We ought to have a buffer.
if (buffer_) {
+ updateEmbeddedFileList(); // new method
EmbeddedFileList::iterator it = bibfiles_.begin();
EmbeddedFileList::iterator it_end = bibfiles_.end();
for (; it != it_end; ++it) {
try {
*it = it->copyTo(&buffer);
} catch (ExceptionMessage const & message) {
Alert::error(message.title_, message.details_);
// failed to embed
it->setEmbed(false);
}
}
}
This is the best of both worlds, right? And we could even do better,
potentially, by allowing access to bibfiles_ only via a method that
would do the update for us. E.g.:
class BibFileList {
BibFileList(InsetBibtex const * inset) : owner_(inset) {}
EmbeddedFileList const & get() const { update(); return list_; }
EmbeddedFileList & get() { update(); return list_; }
private:
update() { //stuff to do with owner_ that updates the list }
InsetBibtex const * owner_;
EmbeddedFileList list_;
}
And now in InsetBibtex:
BibFileList bibfiles_;
whence setBuffer does:
EmbeddedFileList const & efl = bibfiles_.get();
etc.
If you're agreed, I can change the patch this way. The only task is to
write the update() method, really---we could just take over the old
createBibFiles, but that seems like overkill---and for me to undo some
other bits, like registerEmbeddedFile(). OK?
I knew we'd figure this out eventually.
rh