The attached patch further disentangles InsetBibtex from the EmbeddedFiles architecture, and it solves the problem mentioned in an earlier note with GuiBibtex, along the lines mentioned there.
As also said elsewhere, if we want to fiddle with how the parameters in InsetBibtex are represented, we can do that, but the solution should be general. Representing some of the parameters one way, using an EmbeddedFile, and some of them another way (using, I guess, InsetCommandParams) does not seem optimal, if for know other reason than that the code assumes you can set things by doing e.g. setParam("bibfile", bibname), and it's hard to see how to keep that sync'd with some other representation without totally reimplementing setParam, and a handful of other things, too.
Now that trunk works, I'm going to try to do some actual work. rh
Index: src/insets/InsetBibtex.h =================================================================== --- src/insets/InsetBibtex.h (revision 23995) +++ src/insets/InsetBibtex.h (working copy) @@ -12,14 +12,17 @@ #ifndef INSET_BIBTEX_H #define INSET_BIBTEX_H -#include <map> -#include "InsetCommand.h" #include "BiblioInfo.h" #include "EmbeddedFiles.h" +#include "InsetCommand.h" +#include "support/docstring.h" +#include "support/FileName.h" + +#include <vector> + namespace lyx { - /** Used to insert BibTeX's information */ class InsetBibtex : public InsetCommand { @@ -27,7 +30,7 @@ /// InsetBibtex(InsetCommandParams const &); /// - void setBuffer(Buffer & buffer); + virtual void setBuffer(Buffer & buffer); /// docstring screenLabel() const; /// @@ -40,13 +43,13 @@ int latex(odocstream &, OutputParams const &) const; /// void fillWithBibKeys(BiblioInfo &, InsetIterator const &) const; + /// + std::vector<support::FileName> const getFiles() const; /// - EmbeddedFileList embeddedFiles() const; + bool addDatabase(docstring const &); /// - bool addDatabase(std::string const &); + bool delDatabase(docstring const &); /// - bool delDatabase(std::string const &); - /// void validate(LaTeXFeatures &) const; /// static ParamInfo const & findInfo(std::string const &); @@ -55,21 +58,29 @@ /// static bool isCompatibleCommand(std::string const & s) { return s == "bibtex"; } - /// create bibfiles_ from params bibfiles and embed - /** - \param bibfiles comma separated bib files - \param embed comma separated embed status - */ - void createBibFiles(docstring const & bibfiles, docstring const & embed) const; - /// update bibfiles and embed from bibfiles_ - void updateParam(); + /// + static support::FileName + getBibTeXPath(docstring const & filename, Buffer const & buf); private: /// + struct Data { + docstring bibfile; + docstring embfile; + Data(docstring const & b, docstring const & e) + : bibfile(b), embfile(e) {} + }; + /// + typedef std::vector<Data> ParamData; + typedef ParamData::const_iterator ParamDataCit; + typedef ParamData::iterator ParamDataIt; + /// + ParamData makeParamStruct() const; + /// + void writeParamStruct(ParamData const & data); + /// void registerEmbeddedFiles(EmbeddedFileList &) const; /// void updateEmbeddedFile(EmbeddedFile const & file); - /// embedded bib files - mutable EmbeddedFileList bibfiles_; /// void doDispatch(Cursor & cur, FuncRequest & cmd); /// Index: src/insets/InsetBibtex.cpp =================================================================== --- src/insets/InsetBibtex.cpp (revision 23995) +++ src/insets/InsetBibtex.cpp (working copy) @@ -48,22 +48,33 @@ InsetBibtex::InsetBibtex(InsetCommandParams const & p) - : InsetCommand(p, "bibtex"), bibfiles_() + : InsetCommand(p, "bibtex") {} void InsetBibtex::setBuffer(Buffer & buffer) { + // FIXME We ought to have a buffer. if (buffer_) { - 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); + EmbeddedFileList & efl = buffer_->embeddedFiles(); + vector<FileName> const files = getFiles(); + vector<FileName>::const_iterator fit = files.begin(); + vector<FileName>::const_iterator fen = files.end(); + for (; fit != fen; ++fit) { + EmbeddedFile * efp = efl.findFile(fit->absFilename()); + if (!efp) { + Alert::error(_("Embedding error"), + bformat(_("Failed to find and therefore to copy %1$s"), + from_utf8(fit->absFilename()))); + } else { + try { + updateEmbeddedFile(efp->copyTo(&buffer)); + } catch (ExceptionMessage const & message) { + Alert::error(message.title_, message.details_); + // failed to embed + efp->setEmbed(false); + updateEmbeddedFile(*efp); + } } } } @@ -105,9 +116,7 @@ break; } // - createBibFiles(p["bibfiles"], p["embed"]); - updateParam(); - setParam("options", p["options"]); + setParams(p); buffer().updateBibfilesCache(); break; } @@ -162,15 +171,19 @@ // use such filenames.) // Otherwise, store the (maybe absolute) path to the original, // unmangled database name. - EmbeddedFileList::const_iterator it = bibfiles_.begin(); - EmbeddedFileList::const_iterator it_end = bibfiles_.end(); + + ParamData data = makeParamStruct(); + + ParamDataCit it = data.begin(); + ParamDataCit en = data.end(); odocstringstream dbs; - for (; it != it_end; ++it) { - string utf8input = removeExtension(it->availableFile().absFilename()); + for (; it != en; ++it) { + docstring const input = trim(it->bibfile); + // FIXME UNICODE + string utf8input(to_utf8(input)); string database = normalizeName(buffer(), runparams, utf8input, ".bib"); - FileName const try_in_file = - makeAbsPath(database + ".bib", buffer().filePath()); + FileName const try_in_file(makeAbsPath(database + ".bib", buffer().filePath())); bool const not_from_texmf = try_in_file.isReadableFile(); if (!runparams.inComment && !runparams.dryrun && !runparams.nice && @@ -196,7 +209,7 @@ from_utf8(database)); } - if (it != bibfiles_.begin()) + if (it != data.begin()) dbs << ','; // FIXME UNICODE dbs << from_utf8(latex_path(database)); @@ -305,11 +318,6 @@ } -EmbeddedFileList InsetBibtex::embeddedFiles() const -{ - return bibfiles_; -} - namespace { // methods for parsing bibtex files @@ -552,30 +560,32 @@ void InsetBibtex::fillWithBibKeys(BiblioInfo & keylist, InsetIterator const & /*di*/) const { - EmbeddedFileList const files = embeddedFiles(); - for (vector<EmbeddedFile>::const_iterator it = files.begin(); - it != files.end(); ++ it) { - // This bibtex parser is a first step to parse bibtex files - // more precisely. - // - // - it reads the whole bibtex entry and does a syntax check - // (matching delimiters, missing commas,... - // - it recovers from errors starting with the next @-character - // - it reads @string definitions and replaces them in the - // field values. - // - it accepts more characters in keys or value names than - // bibtex does. - // - // Officially bibtex does only support ASCII, but in practice - // you can use the encoding of the main document as long as - // some elements like keys and names are pure ASCII. Therefore - // we convert the file from the buffer encoding. - // We don't restrict keys to ASCII in LyX, since our own - // InsetBibitem can generate non-ASCII keys, and nonstandard - // 8bit clean bibtex forks exist. - - idocfstream ifs(it->availableFile().toFilesystemEncoding().c_str(), - ios_base::in, buffer().params().encoding().iconvName()); + // This bibtex parser is a first step to parse bibtex files + // more precisely. + // + // - it reads the whole bibtex entry and does a syntax check + // (matching delimiters, missing commas,... + // - it recovers from errors starting with the next @-character + // - it reads @string definitions and replaces them in the + // field values. + // - it accepts more characters in keys or value names than + // bibtex does. + // + // Officially bibtex does only support ASCII, but in practice + // you can use the encoding of the main document as long as + // some elements like keys and names are pure ASCII. Therefore + // we convert the file from the buffer encoding. + // We don't restrict keys to ASCII in LyX, since our own + // InsetBibitem can generate non-ASCII keys, and nonstandard + // 8bit clean bibtex forks exist. + + vector<FileName> const files = getFiles(); + vector<FileName>::const_iterator it = files.begin(); + vector<FileName>::const_iterator en = files.end(); + for (; it != en; ++ it) { + idocfstream ifs(it->toFilesystemEncoding().c_str(), + std::ios_base::in, + buffer().params().encoding().iconvName()); char_type ch; VarMap strings; @@ -704,124 +714,180 @@ } +// look up the path to the file using TeX +FileName InsetBibtex::getBibTeXPath(docstring const & filename, Buffer const & buf) +{ + string texfile = changeExtension(to_utf8(filename), "bib"); + // note that, if the filename can be found directly from the path, + // findtexfile will just return a FileName object for that path. + FileName file(findtexfile(texfile, "bib")); + if (file.empty()) + file = FileName(makeAbsPath(texfile, buf.filePath())); + return file; +} -bool InsetBibtex::addDatabase(string const & db) + +InsetBibtex::ParamData InsetBibtex::makeParamStruct() const { - EmbeddedFile file(changeExtension(db, "bib"), buffer().filePath()); - - // only compare filename - EmbeddedFileList::iterator it = bibfiles_.begin(); - EmbeddedFileList::iterator it_end = bibfiles_.end(); - for (; it != it_end; ++it) - if (it->absFilename() == file.absFilename()) - return false; - - bibfiles_.push_back(file); - updateParam(); - return true; + docstring bibfiles = getParam("bibfiles"); + docstring embfiles = getParam("embed"); + docstring bibfile; + docstring embfile; + + ParamData retval; + char_type comma(','); + bibfiles = split(bibfiles, bibfile, comma); + embfiles = split(embfiles, embfile, comma); + while (!bibfile.empty()) { + retval.push_back(Data(bibfile, embfile)); + bibfiles = split(bibfiles, bibfile, comma); + embfiles = split(embfiles, embfile, comma); + } + return retval; } -bool InsetBibtex::delDatabase(string const & db) +void InsetBibtex::writeParamStruct(InsetBibtex::ParamData const & data) { - EmbeddedFile file(changeExtension(db, "bib"), buffer().filePath()); - - // only compare filename - EmbeddedFileList::iterator it = bibfiles_.begin(); - EmbeddedFileList::iterator it_end = bibfiles_.end(); - for (; it != it_end; ++it) - if (it->absFilename() == file.absFilename()) { - bibfiles_.erase(it); - updateParam(); - return true; - } - return false; + docstring newbibfiles; + docstring newembfiles; + bool first = true; + char_type comma(','); + + ParamDataCit it = data.begin(); + ParamDataCit en = data.end(); + for (; it != en; ++it) { + if (!first) { + newbibfiles = newbibfiles + comma; + newembfiles = newembfiles + comma; + } else + first = false; + newbibfiles = newbibfiles + it->bibfile; + newembfiles = newembfiles + it->embfile; + } + setParam("bibfiles", newbibfiles); + setParam("embed", newembfiles); } -void InsetBibtex::validate(LaTeXFeatures & features) const +bool InsetBibtex::addDatabase(docstring const & db) { - if (features.bufferParams().use_bibtopic) - features.require("bibtopic"); + // look for the item and update status + ParamData data = makeParamStruct(); + + ParamDataCit it = data.begin(); + ParamDataCit en = data.end(); + for (; it != en; ++it) + if (db == it->bibfile) + return false; + + FileName const texPath = getBibTeXPath(db, buffer()); + string const inzipName = + EmbeddedFile::calcInzipName(texPath.absFilename(), buffer().filePath()); + data.push_back(Data(db, from_utf8(inzipName))); + + writeParamStruct(data); + buffer().updateBibfilesCache(); + return true; } -void InsetBibtex::createBibFiles(docstring const & bibParam, - docstring const & embedParam) const +bool InsetBibtex::delDatabase(docstring const & db) { - bibfiles_.clear(); - - string tmp; - string emb; - - string bibfiles = to_utf8(bibParam); - string embedStatus = to_utf8(embedParam); - - LYXERR(Debug::FILES, "Create bib files from parameters " - << bibfiles << " and " << embedStatus); + // look for the item and update status + ParamData data = makeParamStruct(); - bibfiles = split(bibfiles, tmp, ','); - embedStatus = split(embedStatus, emb, ','); - - while (!tmp.empty()) { - EmbeddedFile file(changeExtension(tmp, "bib"), buffer().filePath()); - - file.setInzipName(emb); - file.setEmbed(!emb.empty()); - file.enable(buffer().embedded(), &buffer(), false); - bibfiles_.push_back(file); - // Get next file name - bibfiles = split(bibfiles, tmp, ','); - embedStatus = split(embedStatus, emb, ','); + bool found = false; + + ParamDataIt it = data.begin(); + ParamDataIt en = data.end(); + for (; it != en; ++it) { + if (db == it->bibfile) { + data.erase(it); + found = true; + break; + } } + + if (!found) + return false; + + writeParamStruct(data); + buffer().updateBibfilesCache(); + return true; } -void InsetBibtex::updateParam() +void InsetBibtex::validate(LaTeXFeatures & features) const { - docstring bibfiles; - docstring embed; + if (features.bufferParams().use_bibtopic) + features.require("bibtopic"); +} - bool first = true; - EmbeddedFileList::iterator it = bibfiles_.begin(); - EmbeddedFileList::iterator en = bibfiles_.end(); +vector<FileName> const InsetBibtex::getFiles() const +{ + FileName path(buffer().filePath()); + // change the path temporarily + support::PathChanger p(path); + vector<FileName> vec; + ParamData data = makeParamStruct(); + + ParamDataCit it = data.begin(); + ParamDataCit en = data.end(); for (; it != en; ++it) { - if (!first) { - bibfiles += ','; - embed += ','; - } else - first = false; - bibfiles += from_utf8(it->outputFilename(buffer().filePath())); - if (it->embedded()) - embed += from_utf8(it->inzipName()); + FileName file = getBibTeXPath(it->bibfile, buffer()); + LYXERR(Debug::LATEX, "Bibfile: " << file << endl); + + // If we didn't find a matching file name just fail silently + if (!file.empty()) + vec.push_back(file); } - setParam("bibfiles", bibfiles); - setParam("embed", embed); + + return vec; } void InsetBibtex::registerEmbeddedFiles(EmbeddedFileList & files) const { - if (bibfiles_.empty()) - createBibFiles(params()["bibfiles"], params()["embed"]); + LYXERR(Debug::FILES, "Create bib files from parameters " + << getParam("bibfiles") << " and " << getParam("embed") << std:: endl); - EmbeddedFileList::const_iterator it = bibfiles_.begin(); - EmbeddedFileList::const_iterator it_end = bibfiles_.end(); - for (; it != it_end; ++it) - files.registerFile(*it, this, buffer()); + ParamData data = makeParamStruct(); + ParamDataCit it = data.begin(); + ParamDataCit en = data.end(); + for (; it != en; ++it) { + FileName bibfile = getBibTeXPath(it->bibfile, buffer()); + files.registerFile(bibfile.absFilename(), to_utf8(it->embfile), + !it->embfile.empty(), this, buffer()); + } } void InsetBibtex::updateEmbeddedFile(EmbeddedFile const & file) { - // look for the item and update status - for (EmbeddedFileList::iterator it = bibfiles_.begin(); - it != bibfiles_.end(); ++it) - if (it->absFilename() == file.absFilename()) - *it = file; - - updateParam(); + docstring newembfiles; + bool found = false; + bool first = true; + char_type comma(','); + + ParamData data = makeParamStruct(); + ParamDataCit it = data.begin(); + ParamDataCit en = data.end(); + for (; it != en; ++it) { + if (!first) + newembfiles = newembfiles + comma; + else + first = false; + string pathToBib(getBibTeXPath(it->bibfile, buffer()).absFilename()); + if (!found && pathToBib == file.absFilename()) { + //found it, we'll suppose + newembfiles = newembfiles + from_utf8(file.inzipName()); + found = true; + } else // just copy the old value + newembfiles = newembfiles + it->embfile; + } + setParam("embed", newembfiles); } Index: src/EmbeddedFiles.h =================================================================== --- src/EmbeddedFiles.h (revision 23995) +++ src/EmbeddedFiles.h (working copy) @@ -94,8 +94,12 @@ class EmbeddedFile : public support::DocFileName { public: + /// EmbeddedFile(std::string const & file = std::string(), std::string const & buffer_path = std::string()); + /// + EmbeddedFile(std::string const & file, std::string const & inzipName, + bool embed, Buffer const & buf); /// set filename and inzipName. /** @@ -170,13 +174,14 @@ bool isReadableFile() const; /// Calculate checksum of availableFile unsigned long checksum() const; - - // calculate inzip_name_ from filename + /// move an embedded disk file with an existing inzip_name_ to + /// a calculated inzip_name_, if they differ. + void syncInzipFile(std::string const & buffer_path); + /// calculate inzip_name_ from filename std::string calcInzipName(std::string const & buffer_path); - // move an embedded disk file with an existing inzip_name_ to - // a calculated inzip_name_, if they differ. - void syncInzipFile(std::string const & buffer_path); - + /// + static std::string + calcInzipName(std::string const & file, std::string const & path); private: /// filename in zip file std::string inzip_name_; @@ -209,7 +214,15 @@ */ void registerFile(EmbeddedFile const & file, Inset const * inset, Buffer const & buffer); + /// + void registerFile(std::string const & file, std::string const & inzipName, + bool embed, Inset const * inset, Buffer const & buf); + /// returns a pointer to the Embedded file representing this object, + /// or null if not found. The filename should be absolute. + EmbeddedFile const * findFile(std::string const & filename) const; + EmbeddedFile * findFile(std::string const & filename); + /// validate embedded fies after a file is read. void validate(Buffer const & buffer); Index: src/EmbeddedFiles.cpp =================================================================== --- src/EmbeddedFiles.cpp (revision 23995) +++ src/EmbeddedFiles.cpp (working copy) @@ -54,6 +54,16 @@ } +EmbeddedFile::EmbeddedFile(std::string const & file, + std::string const & inzipName, bool embed, Buffer const & buf) + : DocFileName("", false), inzip_name_(inzipName), inset_list_() +{ + DocFileName::set(file, buf.filePath()); + setEmbed(embed); + enable(buf.embedded(), &buf, false); +} + + void EmbeddedFile::set(std::string const & filename, std::string const & buffer_path) { DocFileName::set(filename, buffer_path); @@ -368,11 +378,14 @@ const std::string driveName = "LyX.Embed.Drive"; const std::string spaceName = "LyX.Embed.Space"; -std::string EmbeddedFile::calcInzipName(std::string const & buffer_path) + +// static +std::string EmbeddedFile::calcInzipName( + std::string const & file, std::string const & buffer_path) { - string inzipName = to_utf8(makeRelPath(from_utf8(absFilename()), + string inzipName = to_utf8(makeRelPath(from_utf8(file), from_utf8(buffer_path))); - + if (FileName(inzipName).isAbsolute()) inzipName = absDirName + '/' + inzipName; @@ -386,10 +399,15 @@ // to avoid name conflict between $docu_path/file and $temp_path/file // embedded files are in a subdirectory of $temp_path. inzipName = embDirName + '/' + inzipName; - return inzipName; + return inzipName; } +std::string EmbeddedFile::calcInzipName(std::string const & buffer_path) +{ + return calcInzipName(absFilename(), buffer_path); +} + void EmbeddedFile::syncInzipFile(std::string const & buffer_path) { BOOST_ASSERT(enabled()); @@ -488,35 +506,67 @@ } +void EmbeddedFileList::registerFile(std::string const & file, + std::string const & inzipName, bool embed, Inset const * inset, + Buffer const & buf) +{ + EmbeddedFile ef(file, inzipName, embed, buf); + registerFile(ef, inset, buf); +} + + void EmbeddedFileList::registerFile(EmbeddedFile const & file, Inset const * inset, Buffer const & buffer) { BOOST_ASSERT(!buffer.embedded() || file.enabled()); - // try to find this file from the list - std::vector<EmbeddedFile>::iterator it = begin(); - std::vector<EmbeddedFile>::iterator it_end = end(); - for (; it != it_end; ++it) - if (it->absFilename() == file.absFilename()) { - if (it->embedded() != file.embedded()) { + string newfile = file.absFilename(); + EmbeddedFile * efp = findFile(newfile); + if (efp) { + if (efp->embedded() != file.embedded()) { Alert::error(_("Wrong embedding status."), bformat(_("File %1$s is included in more than one insets, " "but with different embedding status. Assuming embedding status."), - from_utf8(it->outputFilename()))); - it->setEmbed(true); + from_utf8(efp->outputFilename()))); + efp->setEmbed(true); // update the inset with this embedding status. - const_cast<Inset*>(inset)->updateEmbeddedFile(*it); + const_cast<Inset*>(inset)->updateEmbeddedFile(*efp); } - it->addInset(inset); + efp->addInset(inset); return; } // file.clearInsets(); push_back(file); back().addInset(inset); + return; } +EmbeddedFile const * EmbeddedFileList::findFile(std::string const & filename) const +{ + // try to find this file from the list + std::vector<EmbeddedFile>::const_iterator it = begin(); + std::vector<EmbeddedFile>::const_iterator it_end = end(); + for (; it != it_end; ++it) + if (it->absFilename() == filename) + return &*it; + return 0; +} + + +EmbeddedFile * EmbeddedFileList::findFile(std::string const & filename) +{ + // try to find this file from the list + std::vector<EmbeddedFile>::iterator it = begin(); + std::vector<EmbeddedFile>::iterator it_end = end(); + for (; it != it_end; ++it) + if (it->absFilename() == filename) + return &*it; + return 0; +} + + void EmbeddedFileList::validate(Buffer const & buffer) { clear(); Index: src/Buffer.h =================================================================== --- src/Buffer.h (revision 23995) +++ src/Buffer.h (working copy) @@ -304,10 +304,10 @@ /// Update the cache with all bibfiles in use (including bibfiles /// of loaded child documents). - void updateBibfilesCache() const; + void updateBibfilesCache(); /// Return the cache with all bibfiles in use (including bibfiles /// of loaded child documents). - EmbeddedFileList const & getBibfilesCache() const; + std::vector<support::FileName> const & getBibfilesCache() const; /// void getLabelList(std::vector<docstring> &) const; Index: src/Buffer.cpp =================================================================== --- src/Buffer.cpp (revision 23995) +++ src/Buffer.cpp (working copy) @@ -206,7 +206,7 @@ /// A cache for the bibfiles (including bibfiles of loaded child /// documents), needed for appropriate update of natbib labels. - mutable EmbeddedFileList bibfilesCache_; + mutable vector<FileName> bibfilesCache_; mutable RefCache ref_cache_; @@ -1392,11 +1392,12 @@ } -void Buffer::updateBibfilesCache() const +void Buffer::updateBibfilesCache() { // If this is a child document, use the parent's cache instead. if (d->parent_buffer) { - d->parent_buffer->updateBibfilesCache(); + Buffer * parent = const_cast<Buffer *>(d->parent_buffer); + parent->updateBibfilesCache(); return; } @@ -1405,25 +1406,24 @@ if (it->lyxCode() == BIBTEX_CODE) { InsetBibtex const & inset = static_cast<InsetBibtex const &>(*it); - EmbeddedFileList const bibfiles = inset.embeddedFiles(); + vector<FileName> const bibfiles = inset.getFiles(); d->bibfilesCache_.insert(d->bibfilesCache_.end(), bibfiles.begin(), bibfiles.end()); } else if (it->lyxCode() == INCLUDE_CODE) { - InsetInclude & inset = - static_cast<InsetInclude &>(*it); + InsetInclude & inset = static_cast<InsetInclude &>(*it); inset.updateBibfilesCache(); - EmbeddedFileList const & bibfiles = - inset.getBibfilesCache(*this); + vector<FileName> const & bibfiles = inset.getBibfilesCache(*this); d->bibfilesCache_.insert(d->bibfilesCache_.end(), bibfiles.begin(), bibfiles.end()); } } + embeddedFiles().enable(embedded(), *this, false); } -EmbeddedFileList const & Buffer::getBibfilesCache() const +vector<FileName> const & Buffer::getBibfilesCache() const { // If this is a child document, use the parent's cache instead. if (d->parent_buffer) Index: src/frontends/qt4/GuiBibtex.cpp =================================================================== --- src/frontends/qt4/GuiBibtex.cpp (revision 23995) +++ src/frontends/qt4/GuiBibtex.cpp (working copy) @@ -27,6 +27,8 @@ #include "frontends/alert.h" +#include "insets/InsetBibtex.h" + #include "support/debug.h" #include "support/ExceptionMessage.h" #include "support/FileFilterList.h" @@ -367,20 +369,14 @@ dbs += ','; emb += ','; } - QString filename = databaseLW->item(i)->text(); - dbs += qstring_to_ucs4(filename); - try { - EmbeddedFile file(fromqstr(changeExtension(filename, "bib")), - buf.filePath()); - file.setEmbed(databaseLW->item(i)->checkState() == Qt::Checked); - // move file around if needed, an exception may be raised. - file.enable(buf.embedded(), &buf, true); - // if things are OK..., - if (file.embedded()) - emb += from_utf8(file.inzipName()); - } catch (ExceptionMessage const & message) { - Alert::error(message.title_, message.details_); - // failed to embed + QString bibfile = databaseLW->item(i)->text(); + docstring bibfiled = qstring_to_ucs4(bibfile); + dbs += bibfiled; + if (databaseLW->item(i)->checkState() == Qt::Checked) { + FileName bibfilepath = InsetBibtex::getBibTeXPath(bibfiled, buf); + string inzipName = + EmbeddedFile::calcInzipName(bibfilepath.absFilename(), buf.filePath()); + emb += from_utf8(inzipName); } } Index: src/BufferView.cpp =================================================================== --- src/BufferView.cpp (revision 23995) +++ src/BufferView.cpp (working copy) @@ -1248,7 +1248,7 @@ InsetBibtex * inset = getInsetByCode<InsetBibtex>(tmpcur, BIBTEX_CODE); if (inset) { - if (inset->addDatabase(to_utf8(cmd.argument()))) + if (inset->addDatabase(cmd.argument())) buffer_.updateBibfilesCache(); } break; @@ -1260,7 +1260,7 @@ InsetBibtex * inset = getInsetByCode<InsetBibtex>(tmpcur, BIBTEX_CODE); if (inset) { - if (inset->delDatabase(to_utf8(cmd.argument()))) + if (inset->delDatabase(cmd.argument())) buffer_.updateBibfilesCache(); } break; Index: src/insets/InsetCitation.cpp =================================================================== --- src/insets/InsetCitation.cpp (revision 23999) +++ src/insets/InsetCitation.cpp (working copy) @@ -142,15 +142,15 @@ static CachedMap cached_keys; // and cache the timestamp of the bibliography files. - static map<EmbeddedFile, time_t> bibfileStatus; + static map<FileName, time_t> bibfileStatus; BiblioInfo biblist; - EmbeddedFileList const & bibfilesCache = buffer.getBibfilesCache(); + vector<FileName> const & bibfilesCache = buffer.getBibfilesCache(); // compare the cached timestamps with the actual ones. bool changed = false; - EmbeddedFileList::const_iterator ei = bibfilesCache.begin(); - EmbeddedFileList::const_iterator en = bibfilesCache.end(); + vector<FileName>::const_iterator ei = bibfilesCache.begin(); + vector<FileName>::const_iterator en = bibfilesCache.end(); for (; ei != en; ++ ei) { time_t lastw = ei->lastModified(); if (lastw != bibfileStatus[*ei]) { Index: src/insets/InsetInclude.cpp =================================================================== --- src/insets/InsetInclude.cpp (revision 23998) +++ src/insets/InsetInclude.cpp (working copy) @@ -726,17 +726,17 @@ } -EmbeddedFileList const & -InsetInclude::getBibfilesCache(Buffer const & buffer) const +vector<FileName> const & + InsetInclude::getBibfilesCache(Buffer const & buffer) const { Buffer * const tmp = getChildBuffer(buffer, params()); if (tmp) { tmp->setParent(0); - EmbeddedFileList const & cache = tmp->getBibfilesCache(); + vector<FileName> const & cache = tmp->getBibfilesCache(); tmp->setParent(&buffer); return cache; } - static EmbeddedFileList const empty; + static vector<FileName> const empty; return empty; } Index: src/insets/InsetInclude.h =================================================================== --- src/insets/InsetInclude.h (revision 23995) +++ src/insets/InsetInclude.h (working copy) @@ -68,7 +68,7 @@ * Return an empty vector if the child doc is not loaded. * \param buffer the Buffer containing this inset. */ - EmbeddedFileList const & + std::vector<support::FileName> const & getBibfilesCache(Buffer const & buffer) const; /// EDITABLE editable() const { return IS_EDITABLE; }