]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetBibtex.cpp
Get rid of Qt resources
[lyx.git] / src / insets / InsetBibtex.cpp
index d2e7284052dbf875ebfefe283a570d3ccb51e1b5..15953e1cded7dec4a6455e55c8c18e05df1e02ce 100644 (file)
 #include "PDFOptions.h"
 #include "texstream.h"
 #include "TextClass.h"
+#include "TocBackend.h"
 
 #include "frontends/alert.h"
 
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/docstream.h"
+#include "support/docstring_list.h"
 #include "support/ExceptionMessage.h"
 #include "support/FileNameList.h"
 #include "support/filetools.h"
@@ -71,6 +73,7 @@ ParamInfo const & InsetBibtex::findInfo(string const & /* cmdName */)
                param_info_.add("bibfiles", ParamInfo::LATEX_REQUIRED);
                param_info_.add("options", ParamInfo::LYX_INTERNAL);
                param_info_.add("encoding", ParamInfo::LYX_INTERNAL);
+               param_info_.add("file_encodings", ParamInfo::LYX_INTERNAL);
                param_info_.add("biblatexopts", ParamInfo::LATEX_OPTIONAL);
        }
        return param_info_;
@@ -82,7 +85,7 @@ void InsetBibtex::doDispatch(Cursor & cur, FuncRequest & cmd)
        switch (cmd.action()) {
 
        case LFUN_INSET_EDIT:
-               editDatabases();
+               editDatabases(cmd.argument());
                break;
 
        case LFUN_INSET_MODIFY: {
@@ -103,6 +106,7 @@ void InsetBibtex::doDispatch(Cursor & cur, FuncRequest & cmd)
 
                cur.recordUndo();
                setParams(p);
+               cur.buffer()->clearBibFileCache();
                cur.forceBufferUpdate();
                break;
        }
@@ -128,15 +132,15 @@ bool InsetBibtex::getStatus(Cursor & cur, FuncRequest const & cmd,
 }
 
 
-void InsetBibtex::editDatabases() const
+void InsetBibtex::editDatabases(docstring const & db) const
 {
        vector<docstring> bibfilelist = getVectorFromString(getParam("bibfiles"));
 
        if (bibfilelist.empty())
                return;
 
-       int nr_databases = bibfilelist.size();
-       if (nr_databases > 1) {
+       size_t nr_databases = bibfilelist.size();
+       if (nr_databases > 1 && db.empty()) {
                        docstring const engine = usingBiblatex() ? _("Biblatex") : _("BibTeX");
                        docstring message = bformat(_("The %1$s[[BibTeX/Biblatex]] inset includes %2$s databases.\n"
                                                       "If you proceed, all of them will be opened."),
@@ -151,7 +155,9 @@ void InsetBibtex::editDatabases() const
        vector<docstring>::const_iterator it = bibfilelist.begin();
        vector<docstring>::const_iterator en = bibfilelist.end();
        for (; it != en; ++it) {
-               FileName const bibfile = getBibTeXPath(*it, buffer());
+               if (!db.empty() && db != *it)
+                       continue;
+               FileName const bibfile = buffer().getBibfilePath(*it);
                theFormats().edit(buffer(), bibfile,
                     theFormats().getFormatFromFile(bibfile));
        }
@@ -229,8 +235,7 @@ docstring InsetBibtex::toolTip(BufferView const & /*bv*/, int /*x*/, int /*y*/)
                        tip += _("included in TOC");
                }
                if (!getParam("biblatexopts").empty()) {
-                       if (toc)
-                               tip += "<br />";
+                       tip += "<br />";
                        tip += _("Options: ") + getParam("biblatexopts");
                }
        }
@@ -261,6 +266,15 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
            && buffer().params().multibib == "child")
                return;
 
+       if (runparams.inDeletedInset) {
+               // We cannot strike-out bibligraphies,
+               // so we just output a note.
+               os << "\\textbf{"
+                  << buffer().B_("[BIBLIOGRAPHY DELETED!]")
+                  << "}";
+               return;
+       }
+
        string style = to_utf8(getParam("options")); // maybe empty! and with bibtotoc
        string bibtotoc;
        if (prefixIs(style, "bibtotoc")) {
@@ -288,8 +302,11 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
                os << "\n";
        } else {// using BibTeX
                // Database(s)
-               vector<docstring> const db_out =
+               vector<pair<docstring, string>> const dbs =
                        buffer().prepareBibFilePaths(runparams, getBibFiles(), false);
+               vector<docstring> db_out;
+               for (pair<docstring, string> const & db : dbs)
+                       db_out.push_back(db.first);
                // Style options
                if (style == "default")
                        style = buffer().masterParams().defaultBiblioStyle();
@@ -355,7 +372,8 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
                           << "\\end{btSect}\n";
                }
                // bibtotoc option
-               if (!bibtotoc.empty() && !buffer().masterParams().useBibtopic()) {
+               if (!bibtotoc.empty() && !buffer().masterParams().useBibtopic()
+                   && !buffer().masterParams().documentClass().bibInToc()) {
                        // set label for hyperref, see http://www.lyx.org/trac/ticket/6470
                        if (buffer().masterParams().pdfoptions().use_hyperref)
                                        os << "\\phantomsection";
@@ -383,29 +401,9 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
 }
 
 
-FileNamePairList InsetBibtex::getBibFiles() const
+docstring_list InsetBibtex::getBibFiles() const
 {
-       FileName path(buffer().filePath());
-       PathChanger p(path);
-
-       // We need to store both the real FileName and the way it is entered
-       // (with full path, rel path or as a single file name).
-       // The latter is needed for biblatex's central bibfile macro.
-       FileNamePairList vec;
-
-       vector<docstring> bibfilelist = getVectorFromString(getParam("bibfiles"));
-       vector<docstring>::const_iterator it = bibfilelist.begin();
-       vector<docstring>::const_iterator en = bibfilelist.end();
-       for (; it != en; ++it) {
-               FileName const file = getBibTeXPath(*it, buffer());
-
-               if (!file.empty())
-                       vec.push_back(make_pair(*it, file));
-               else
-                       LYXERR0("Couldn't find " + to_utf8(*it) + " in InsetBibtex::getBibFiles()!");
-       }
-
-       return vec;
+       return getVectorFromString(getParam("bibfiles"));
 }
 
 namespace {
@@ -676,11 +674,13 @@ void InsetBibtex::parseBibTeXFiles(FileNameList & checkedFiles) const
 
        BiblioInfo keylist;
 
-       FileNamePairList const files = getBibFiles();
-       FileNamePairList::const_iterator it = files.begin();
-       FileNamePairList::const_iterator en = files.end();
-       for (; it != en; ++ it) {
-               FileName const bibfile = it->second;
+       docstring_list const files = getBibFiles();
+       for (auto const & bf : files) {
+               FileName const bibfile = buffer().getBibfilePath(bf);
+               if (bibfile.empty()) {
+                       LYXERR0("Unable to find path for " << bf << "!");
+                       continue;
+               }
                if (find(checkedFiles.begin(), checkedFiles.end(), bibfile) != checkedFiles.end())
                        // already checked this one. Skip.
                        continue;
@@ -688,8 +688,11 @@ void InsetBibtex::parseBibTeXFiles(FileNameList & checkedFiles) const
                        // record that we check this.
                        checkedFiles.push_back(bibfile);
                string encoding = buffer().masterParams().encoding().iconvName();
-               string const ienc = to_ascii(params()["encoding"]);
-               if (!ienc.empty() && ienc != "default" && encodings.fromLyXName(ienc))
+               string ienc = buffer().masterParams().bibFileEncoding(to_utf8(bf));
+               if (ienc.empty() || ienc == "general")
+                       ienc = to_ascii(params()["encoding"]);
+
+               if (!ienc.empty() && ienc != "auto-legacy-plain" && ienc != "auto-legacy" && encodings.fromLyXName(ienc))
                        encoding = encodings.fromLyXName(ienc)->iconvName();
                ifdocstream ifs(bibfile.toFilesystemEncoding().c_str(),
                        ios_base::in, encoding);
@@ -698,7 +701,6 @@ void InsetBibtex::parseBibTeXFiles(FileNameList & checkedFiles) const
                VarMap strings;
 
                while (ifs) {
-
                        ifs.get(ch);
                        if (!ifs)
                                break;
@@ -857,18 +859,6 @@ void InsetBibtex::parseBibTeXFiles(FileNameList & checkedFiles) const
 }
 
 
-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(docstring const & db)
 {
        docstring bibfiles = getParam("bibfiles");
@@ -918,23 +908,72 @@ void InsetBibtex::validate(LaTeXFeatures & features) const
 }
 
 
-void InsetBibtex::updateBuffer(ParIterator const &, UpdateType)
+void InsetBibtex::updateBuffer(ParIterator const &, UpdateType, bool const /*deleted*/)
 {
        buffer().registerBibfiles(getBibFiles());
        // record encoding of bib files for biblatex
        string const enc = (params()["encoding"] == from_ascii("default")) ?
                                string() : to_ascii(params()["encoding"]);
+       bool invalidate = false;
        if (buffer().params().bibEncoding() != enc) {
                buffer().params().setBibEncoding(enc);
-               buffer().reloadBibInfoCache(true);
+               invalidate = true;
+       }
+       map<string, string> encs = getFileEncodings();
+       map<string, string>::const_iterator it = encs.begin();
+       for (; it != encs.end(); ++it) {
+               if (buffer().params().bibFileEncoding(it->first) != it->second) {
+                       buffer().params().setBibFileEncoding(it->first, it->second);
+                       invalidate = true;
+               }
+       }
+       if (invalidate)
+               buffer().invalidateBibinfoCache();
+}
+
+
+map<string, string> InsetBibtex::getFileEncodings() const
+{
+       vector<string> ps =
+               getVectorFromString(to_utf8(getParam("file_encodings")), "\t");
+       std::map<string, string> res;
+       for (string const & s: ps) {
+               string key;
+               string val = split(s, key, ' ');
+               res[key] = val;
        }
+       return res;
+}
+
+
+docstring InsetBibtex::getRefLabel() const
+{
+       if (buffer().masterParams().documentClass().hasLaTeXLayout("chapter"))
+               return buffer().B_("Bibliography");
+       return buffer().B_("References");
+}
+
+
+void InsetBibtex::addToToc(DocIterator const & cpit, bool output_active,
+                          UpdateType, TocBackend & backend) const
+{
+       if (!prefixIs(to_utf8(getParam("options")), "bibtotoc"))
+               return;
+
+       docstring const str = getRefLabel();
+       shared_ptr<Toc> toc = backend.toc("tableofcontents");
+       // Assign to appropriate level
+       int const item_depth =
+               (buffer().masterParams().documentClass().hasLaTeXLayout("chapter")) 
+                       ? 1 : 2;
+       toc->push_back(TocItem(cpit, item_depth, str, output_active));
 }
 
 
 int InsetBibtex::plaintext(odocstringstream & os,
        OutputParams const & op, size_t max_length) const
 {
-       docstring const reflabel = buffer().B_("References");
+       docstring const reflabel = getRefLabel();
 
        // We could output more information here, e.g., what databases are included
        // and information about options. But I don't necessarily see any reason to
@@ -973,7 +1012,7 @@ int InsetBibtex::plaintext(odocstringstream & os,
                refoutput += bibinfo.getInfo(entry.key(), buffer(), ci) + "\n\n";
        }
        os << refoutput;
-       return refoutput.size();
+       return int(refoutput.size());
 }