]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetBibtex.cpp
Change string
[lyx.git] / src / insets / InsetBibtex.cpp
index b898efd814fb1bb59504470cc9572eb8c46df184..a74be8e1f0ac9f67d010cf8b827fc5eb4db82d05 100644 (file)
@@ -27,8 +27,8 @@
 #include "frontends/alert.h"
 
 #include "support/debug.h"
-#include "support/ExceptionMessage.h"
 #include "support/docstream.h"
+#include "support/ExceptionMessage.h"
 #include "support/filetools.h"
 #include "support/gettext.h"
 #include "support/lstrings.h"
@@ -36,7 +36,6 @@
 #include "support/Path.h"
 #include "support/textutils.h"
 
-#include <boost/tokenizer.hpp>
 #include <limits>
 
 using namespace std;
@@ -49,10 +48,29 @@ namespace os = support::os;
 
 
 InsetBibtex::InsetBibtex(InsetCommandParams const & p)
-       : InsetCommand(p, "bibtex")
+       : InsetCommand(p, "bibtex"), bibfiles_()
 {}
 
 
+void InsetBibtex::setBuffer(Buffer & 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);
+                       }               
+               }
+       }
+       Inset::setBuffer(buffer);
+}
+
+
 ParamInfo const & InsetBibtex::findInfo(string const & /* cmdName */)
 {
        static ParamInfo param_info_;
@@ -66,12 +84,6 @@ ParamInfo const & InsetBibtex::findInfo(string const & /* cmdName */)
 }
 
 
-Inset * InsetBibtex::clone() const
-{
-       return new InsetBibtex(*this);
-}
-
-
 void InsetBibtex::doDispatch(Cursor & cur, FuncRequest & cmd)
 {
        switch (cmd.action) {
@@ -93,49 +105,9 @@ void InsetBibtex::doDispatch(Cursor & cur, FuncRequest & cmd)
                        break;
                }
                //
-               InsetCommandParams orig = params();
-               // returned "embed" is composed of "true" or "false", which needs to be adjusted
-               string tmp;
-               string emb;
-               
-               string newBibfiles;
-               string newEmbedStatus;
-               
-               string bibfiles = to_utf8(p["bibfiles"]);
-               string embedStatus = to_utf8(p["embed"]);
-               
-               bibfiles = split(bibfiles, tmp, ',');
-               embedStatus = split(embedStatus, emb, ',');
-               while (!tmp.empty()) {
-                       EmbeddedFile file(changeExtension(tmp, "bib"), cur.buffer().filePath());
-                       if (!newBibfiles.empty())
-                               newBibfiles += ",";
-                       newBibfiles += tmp;
-                       if (!newEmbedStatus.empty())
-                               newEmbedStatus += ",";
-                       if (emb == "true")
-                               newEmbedStatus += file.inzipName();
-                       // Get next file name
-                       bibfiles = split(bibfiles, tmp, ',');
-                       embedStatus = split(embedStatus, emb, ',');
-               }
-               LYXERR(Debug::FILES, "Update parameters from " << p["bibfiles"]
-                       << " " << p["embed"] << " to " << newBibfiles << " "
-                       << newEmbedStatus);
-               p["bibfiles"] = from_utf8(newBibfiles);
-               p["embed"] = from_utf8(newEmbedStatus);
-               
-               setParams(p);
-               try {
-                       // test parameter and copy files
-                       getFiles(cur.buffer());
-               } catch (ExceptionMessage const & message) {
-                       Alert::error(message.title_, message.details_);
-                       // do not set parameter if an error happens
-                       setParams(orig);
-                       break;
-               }
-               cur.buffer().updateBibfilesCache();
+               createBibFiles(p["bibfiles"], p["embed"]);
+               updateParam();
+               buffer().updateBibfilesCache();
                break;
        }
 
@@ -189,9 +161,8 @@ int InsetBibtex::latex(odocstream & os, OutputParams const & runparams) const
        // use such filenames.)
        // Otherwise, store the (maybe absolute) path to the original,
        // unmangled database name.
-       EmbeddedFileList const bibs = getFiles(buffer());
-       EmbeddedFileList::const_iterator it = bibs.begin();
-       EmbeddedFileList::const_iterator it_end = bibs.end();
+       EmbeddedFileList::const_iterator it = bibfiles_.begin();
+       EmbeddedFileList::const_iterator it_end = bibfiles_.end();
        odocstringstream dbs;
        for (; it != it_end; ++it) {
                string utf8input = removeExtension(it->availableFile().absFilename());
@@ -224,7 +195,7 @@ int InsetBibtex::latex(odocstream & os, OutputParams const & runparams) const
                                                            from_utf8(database));
                }
 
-               if (it != bibs.begin())
+               if (it != bibfiles_.begin())
                        dbs << ',';
                // FIXME UNICODE
                dbs << from_utf8(latex_path(database));
@@ -293,7 +264,7 @@ int InsetBibtex::latex(odocstream & os, OutputParams const & runparams) const
                                              "BibTeX will be unable to find it."));
        }
 
-       if (!db_out.empty() && buffer().params().use_bibtopic){
+       if (!db_out.empty() && buffer().params().use_bibtopic) {
                os << "\\begin{btSect}{" << db_out << "}\n";
                docstring btprint = getParam("btprint");
                if (btprint.empty())
@@ -306,12 +277,7 @@ int InsetBibtex::latex(odocstream & os, OutputParams const & runparams) const
 
        // bibtotoc-Option
        if (!bibtotoc.empty() && !buffer().params().use_bibtopic) {
-               // maybe a problem when a textclass has no "art" as
-               // part of its name, because it's than book.
-               // For the "official" lyx-layouts it's no problem to support
-               // all well
-               if (!contains(buffer().params().textClass().name(),
-                             "art")) {
+               if (buffer().params().documentClass().hasLaTeXLayout("chapter")) {
                        if (buffer().params().sides == OneSide) {
                                // oneside
                                os << "\\clearpage";
@@ -319,14 +285,9 @@ int InsetBibtex::latex(odocstream & os, OutputParams const & runparams) const
                                // twoside
                                os << "\\cleardoublepage";
                        }
-
-                       // bookclass
                        os << "\\addcontentsline{toc}{chapter}{\\bibname}";
-
-               } else {
-                       // article class
+               } else if (buffer().params().documentClass().hasLaTeXLayout("section"))
                        os << "\\addcontentsline{toc}{section}{\\refname}";
-               }
        }
 
        if (!db_out.empty() && !buffer().params().use_bibtopic) {
@@ -343,46 +304,9 @@ int InsetBibtex::latex(odocstream & os, OutputParams const & runparams) const
 }
 
 
-EmbeddedFileList const InsetBibtex::getFiles(Buffer const & buffer) const
+EmbeddedFileList InsetBibtex::embeddedFiles() const
 {
-       FileName path(buffer.filePath());
-       PathChanger p(path);
-
-       EmbeddedFileList vec;
-
-       string tmp;
-       string emb;
-       // FIXME UNICODE
-       string bibfiles = to_utf8(getParam("bibfiles"));
-       string embedStatus = to_utf8(getParam("embed"));
-       bibfiles = split(bibfiles, tmp, ',');
-       embedStatus = split(embedStatus, emb, ',');
-       while (!tmp.empty()) {
-               if (!emb.empty()) {
-                       EmbeddedFile file(changeExtension(tmp, "bib"), buffer.filePath());
-                       // If the file structure is correct, this should not fail.
-                       file.setEmbed(true);
-                       file.enable(buffer.embedded(), &buffer);
-                       vec.push_back(file);
-               } else {
-                       // this includes the cases when the embed parameter is empty
-                       FileName const file = findtexfile(changeExtension(tmp, "bib"), "bib");
-
-                       // If we didn't find a matching file name just fail silently
-                       if (!file.empty()) {
-                               EmbeddedFile efile = EmbeddedFile(file.absFilename(), buffer.filePath());
-                               efile.setEmbed(false);
-                               efile.enable(buffer.embedded(), &buffer);
-                               vec.push_back(efile);
-                       }
-               }
-
-               // Get next file name
-               bibfiles = split(bibfiles, tmp, ',');
-               embedStatus = split(embedStatus, emb, ',');
-       }
-
-       return vec;
+       return bibfiles_;
 }
 
 namespace {
@@ -627,7 +551,7 @@ namespace {
 void InsetBibtex::fillWithBibKeys(BiblioInfo & keylist,
        InsetIterator const & /*di*/) const
 {
-       EmbeddedFileList const files = getFiles(buffer());
+       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
@@ -782,36 +706,35 @@ void InsetBibtex::fillWithBibKeys(BiblioInfo & keylist,
 
 bool InsetBibtex::addDatabase(string const & db)
 {
-       // FIXME UNICODE
-       string bibfiles(to_utf8(getParam("bibfiles")));
-       if (tokenPos(bibfiles, ',', db) == -1) {
-               if (!bibfiles.empty())
-                       bibfiles += ',';
-               setParam("bibfiles", from_utf8(bibfiles + db));
-               return true;
-       }
-       return false;
+       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;
 }
 
 
 bool InsetBibtex::delDatabase(string const & db)
 {
-       // FIXME UNICODE
-       string bibfiles(to_utf8(getParam("bibfiles")));
-       if (contains(bibfiles, db)) {
-               int const n = tokenPos(bibfiles, ',', db);
-               string bd = db;
-               if (n > 0) {
-                       // this is not the first database
-                       string tmp = ',' + bd;
-                       setParam("bibfiles", from_utf8(subst(bibfiles, tmp, string())));
-               } else if (n == 0)
-                       // this is the first (or only) database
-                       setParam("bibfiles", from_utf8(split(bibfiles, bd, ',')));
-               else
-                       return false;
-       }
-       return true;
+       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;
 }
 
 
@@ -822,35 +745,51 @@ void InsetBibtex::validate(LaTeXFeatures & features) const
 }
 
 
-void InsetBibtex::registerEmbeddedFiles(Buffer const & buffer, EmbeddedFileList & files) const
+void InsetBibtex::createBibFiles(docstring const & bibParam,
+       docstring const & embedParam) const
 {
-       EmbeddedFileList const dbs = getFiles(buffer);
-       for (vector<EmbeddedFile>::const_iterator it = dbs.begin();
-               it != dbs.end(); ++ it)
-               files.registerFile(*it, this, buffer);          
+       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);
+
+       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, ',');
+       }
 }
 
 
-void InsetBibtex::updateEmbeddedFile(Buffer const & buf, EmbeddedFile const & file)
+void InsetBibtex::updateParam()
 {
-       // look for the item and update status
        docstring bibfiles;
        docstring embed;
 
        bool first = true;
-       EmbeddedFileList dbs = getFiles(buf);
-       for (EmbeddedFileList::iterator it = dbs.begin();
-               it != dbs.end(); ++ it) {
-               // update from file
-               if (it->absFilename() == file.absFilename())
-                       it->setEmbed(file.embedded());
-               // write parameter string
+       for (EmbeddedFileList::iterator it = bibfiles_.begin();
+               it != bibfiles_.end(); ++it) {
                if (!first) {
                        bibfiles += ',';
                        embed += ',';
                } else
                        first = false;
-               bibfiles += from_utf8(it->outputFilename(buf.filePath()));
+               bibfiles += from_utf8(it->outputFilename(buffer().filePath()));
                if (it->embedded())
                        embed += from_utf8(it->inzipName());
        }
@@ -859,4 +798,28 @@ void InsetBibtex::updateEmbeddedFile(Buffer const & buf, EmbeddedFile const & fi
 }
 
 
+void InsetBibtex::registerEmbeddedFiles(EmbeddedFileList & files) const
+{
+       if (bibfiles_.empty())
+               createBibFiles(params()["bibfiles"], params()["embed"]);
+
+       EmbeddedFileList::const_iterator it = bibfiles_.begin();
+       EmbeddedFileList::const_iterator it_end = bibfiles_.end();
+       for (; it != it_end; ++it)
+               files.registerFile(*it, 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();
+}
+
+
 } // namespace lyx