]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetBibitem.cpp
Fix text direction issue for InsetInfo in RTL context
[lyx.git] / src / insets / InsetBibitem.cpp
index 2840ad5c8fff621f51992f53c8595845513940d3..f9b244c4603f556d3a5c68af74a1c182f4830b22 100644 (file)
 
 #include "frontends/alert.h"
 
+#include "support/lassert.h"
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/docstream.h"
 #include "support/gettext.h"
 #include "support/lstrings.h"
+#include "support/mutex.h"
 
 using namespace std;
 using namespace lyx::support;
@@ -49,6 +51,7 @@ namespace lyx {
 
 
 int InsetBibitem::key_counter = 0;
+static Mutex counter_mutex;
 docstring const key_prefix = from_ascii("key-");
 
 
@@ -56,15 +59,21 @@ InsetBibitem::InsetBibitem(Buffer * buf, InsetCommandParams const & p)
        : InsetCommand(buf, p)
 {
        buffer().invalidateBibinfoCache();
-       if (getParam("key").empty())
+       if (getParam("key").empty()) {
+               Mutex::Locker lock(&counter_mutex);
                setParam("key", key_prefix + convert<docstring>(++key_counter));
+       }
 }
 
 
 InsetBibitem::~InsetBibitem()
 {
-       if (isBufferLoaded())
-               buffer().invalidateBibinfoCache();
+       if (isBufferLoaded()) {
+               /* We do not use buffer() because Coverity believes that this
+                * may throw an exception. Actually this code path is not
+                * taken when buffer_ == 0 */
+               buffer_->invalidateBibinfoCache();
+       }
 }
 
 
@@ -77,12 +86,10 @@ void InsetBibitem::initView()
 void InsetBibitem::updateCommand(docstring const & new_key, bool)
 {
        docstring key = new_key;
-
        vector<docstring> bibkeys = buffer().masterBibInfo().getKeys();
 
-       int i = 1;
-
        if (find(bibkeys.begin(), bibkeys.end(), key) != bibkeys.end()) {
+               int i = 1;
                // generate unique label
                key = new_key + '-' + convert<docstring>(i);
                while (find(bibkeys.begin(), bibkeys.end(), key) != bibkeys.end()) {
@@ -105,7 +112,9 @@ ParamInfo const & InsetBibitem::findInfo(string const & /* cmdName */)
                param_info_.add("label", ParamInfo::LATEX_OPTIONAL,
                                ParamInfo::HANDLING_LATEXIFY);
                param_info_.add("key", ParamInfo::LATEX_REQUIRED,
-                               ParamInfo::HANDLING_ESCAPE);
+                               ParamInfo::ParamHandling(ParamInfo::HANDLING_ESCAPE
+                                                        | ParamInfo::HANDLING_LTRIM));
+               param_info_.add("literal", ParamInfo::LYX_INTERNAL);
        }
        return param_info_;
 }
@@ -127,54 +136,24 @@ void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
 
                docstring const & old_key = params()["key"];
                docstring const & old_label = params()["label"];
+               docstring const & old_literal = params()["literal"];
                docstring label = p["label"];
-
-               // definitions for escaping
-               int previous;
-               static docstring const backslash = from_ascii("\\");
-               static docstring const lbrace = from_ascii("{");
-               static docstring const rbrace = from_ascii("}");
-               static char_type const chars_escape[6] = {
-                       '&', '_', '$', '%', '#', '^'};
-               static char_type const brackets_escape[2] = {'[', ']'};
-
-               if (!label.empty()) {
-                       // The characters in chars_name[] need to be changed to a command when
-                       // they are in the name field.
-                       for (int k = 0; k < 6; k++)
-                               for (size_t i = 0, pos;
-                                       (pos = label.find(chars_escape[k], i)) != string::npos;
-                                       i = pos + 2) {
-                                               if (pos == 0)
-                                                       previous = 0;
-                                               else
-                                                       previous = pos - 1;
-                                               // only if not already escaped
-                                               if (label[previous] != '\\')
-                                                       label.replace(pos, 1, backslash + chars_escape[k] + lbrace + rbrace);
-                               }
-                       // The characters '[' and ']' need to be put into braces
-                       for (int k = 0; k < 2; k++)
-                               for (size_t i = 0, pos;
-                                       (pos = label.find(brackets_escape[k], i)) != string::npos;
-                                       i = pos + 2) {
-                                               if (pos == 0)
-                                                       previous = 0;
-                                               else
-                                                       previous = pos - 1;
-                                               // only if not already escaped
-                                               if (label[previous] != '{')
-                                                       label.replace(pos, 1, lbrace + brackets_escape[k] + rbrace);
-                               }
-               }
+               docstring literal = p["literal"];
 
                if (old_label != label) {
                        p["label"] = label;
                        cur.forceBufferUpdate();
                        buffer().invalidateBibinfoCache();
                }
-
                setParam("label", p["label"]);
+
+               if (old_literal != literal) {
+                       p["literal"] = literal;
+                       cur.forceBufferUpdate();
+                       buffer().invalidateBibinfoCache();
+               }
+               setParam("literal", p["literal"]);
+
                if (p["key"] != old_key) {
                        updateCommand(p["key"]);
                        cur.bv().buffer().changeRefsIfUnique(old_key, params()["key"]);
@@ -197,6 +176,7 @@ void InsetBibitem::read(Lexer & lex)
 
        if (prefixIs(getParam("key"), key_prefix)) {
                int const key = convert<int>(getParam("key").substr(key_prefix.length()));
+               Mutex::Locker lock(&counter_mutex);
                key_counter = max(key_counter, key);
        }
 }
@@ -269,6 +249,7 @@ docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams)
        ParagraphList::const_iterator it = buffer.paragraphs().begin();
        ParagraphList::const_iterator end = buffer.paragraphs().end();
 
+       bool is_literal = false;
        for (; it != end; ++it) {
                if (it->insetList().empty())
                        continue;
@@ -294,20 +275,22 @@ docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams)
                if (wx > w) {
                        w = wx;
                        lbl = label;
+                       is_literal = (bitem->getParam("literal") == "true");
                }
        }
 
        if (!lbl.empty()) {
-               pair<docstring, docstring> latex_lbl =
-                       runparams.encoding->latexString(lbl, runparams.dryrun);
-               return latex_lbl.first;
+               InsetCommandParams p(BIBITEM_CODE);
+               if (is_literal)
+                       p["literal"] = from_ascii("true");
+               return p.prepareCommand(runparams, lbl, ParamInfo::HANDLING_LATEXIFY);
        }
 
        return from_ascii("99");
 }
 
 
-void InsetBibitem::collectBibKeys(InsetIterator const & it) const
+void InsetBibitem::collectBibKeys(InsetIterator const & it, FileNameList & /*checkedFiles*/) const
 {
        docstring const key = getParam("key");
        docstring const label = getParam("label");