2 * \file InsetBibitem.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alejandro Aguilar Sierra
8 * Full author contact details are available in file CREDITS.
13 #include "InsetBibitem.h"
16 #include "BufferParams.h"
17 #include "BufferView.h"
19 #include "DispatchResult.h"
20 #include "FuncRequest.h"
22 #include "InsetIterator.h"
23 #include "InsetList.h"
25 #include "Paragraph.h"
26 #include "ParagraphList.h"
28 #include "support/lstrings.h"
29 #include "support/std_ostream.h"
30 #include "support/convert.h"
36 int InsetBibitem::key_counter = 0;
39 docstring const key_prefix = from_ascii("key-");
42 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
43 : InsetCommand(p, "bibitem")
45 if (getParam("key").empty())
46 setParam("key", key_prefix + convert<docstring>(++key_counter));
50 Inset * InsetBibitem::clone() const
52 InsetBibitem * b = new InsetBibitem(params());
53 b->autolabel_ = autolabel_;
58 void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
62 case LFUN_INSET_MODIFY: {
63 InsetCommandParams p(BIBITEM_CODE);
64 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
65 if (p.getCmdName().empty()) {
69 if (p["key"] != params()["key"])
70 cur.bv().buffer().changeRefsIfUnique(params()["key"],
76 InsetCommand::doDispatch(cur, cmd);
82 void InsetBibitem::read(Buffer const & buf, Lexer & lex)
84 InsetCommand::read(buf, lex);
86 if (support::prefixIs(getParam("key"), key_prefix)) {
87 int const key = convert<int>(getParam("key").substr(key_prefix.length()));
88 key_counter = std::max(key_counter, key);
93 docstring const InsetBibitem::getBibLabel() const
95 docstring const & label = getParam("label");
96 return label.empty() ? autolabel_ : label;
100 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
102 return getParam("key") + " [" + getBibLabel() + ']';
106 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
107 OutputParams const &) const
109 odocstringstream oss;
110 oss << '[' << getBibLabel() << "] ";
112 docstring const str = oss.str();
120 docstring const bibitemWidest(Buffer const & buffer)
124 InsetBibitem const * bitem = 0;
126 // FIXME: this font is used unitialized for now but should be set to
127 // a proportional font. Here is what Georg Baum has to say about it:
129 bibitemWidest() is supposed to find the bibitem with the widest label in the
130 output, because that is needed as an argument of the bibliography
131 environment to dtermine the correct indentation. To be 100% correct we
132 would need the metrics of the font that is used in the output, but usually
133 we don't have access to these.
134 In practice, any proportional font is probably good enough, since we don't
135 need to know the final with, we only need to know the which label is the
137 Unless there is an easy way to get the metrics of the output font I suggest
138 to use a hardcoded font like "Times" or so.
140 It is very important that the result of this function is the same both with
141 and without GUI. After thinking about this it is clear that no Font
142 metrics should be used here, since these come from the gui. If we can't
143 easily get the LaTeX font metrics we should make our own poor mans front
144 metrics replacement, e.g. by hardcoding the metrics of the standard TeX
149 ParagraphList::const_iterator it = buffer.paragraphs().begin();
150 ParagraphList::const_iterator end = buffer.paragraphs().end();
152 for (; it != end; ++it) {
153 if (it->insetList().empty())
155 Inset * inset = it->insetList().begin()->inset;
156 if (inset->lyxCode() != BIBITEM_CODE)
159 bitem = static_cast<InsetBibitem const *>(inset);
160 docstring const label = bitem->getBibLabel();
162 // FIXME: we can't be sure using the following that the GUI
163 // version and the command-line version will give the same
166 //int const wx = use_gui?
167 // theFontMetrics(font).width(label): label.size();
169 // So for now we just use the label size in order to be sure
170 // that GUI and no-GUI gives the same bibitem (even if that is
171 // potentially the wrong one.
172 int const wx = label.size();
178 if (bitem && !bitem->getBibLabel().empty())
179 return bitem->getBibLabel();
181 return from_ascii("99");
185 void InsetBibitem::fillWithBibKeys(Buffer const & buf,
186 BiblioInfo & keys, InsetIterator const & it) const
188 docstring const key = getParam("key");
189 BibTeXInfo keyvalmap;
190 keyvalmap[from_ascii("label")] = getParam("label");
191 DocIterator doc_it(it);
193 keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
194 keyvalmap.isBibTeX = false;
195 keys[key] = keyvalmap;
199 /// Update the counters of this inset and of its contents
200 void InsetBibitem::updateLabels(Buffer const &buf, ParIterator const &)
202 Counters & counters = buf.params().getTextClass().counters();
203 docstring const bibitem = from_ascii("bibitem");
204 if (counters.hasCounter(bibitem) && getParam("label").empty()) {
205 counters.step(bibitem);
206 autolabel_ = counters.theCounter(bibitem);
208 autolabel_ = from_ascii("??");