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"
24 #include "Paragraph.h"
25 #include "ParagraphList.h"
27 #include "support/lstrings.h"
28 #include "support/std_ostream.h"
29 #include "support/convert.h"
34 using support::prefixIs;
41 int InsetBibitem::key_counter = 0;
42 docstring const key_prefix = from_ascii("key-");
44 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
45 : InsetCommand(p, "bibitem")
47 if (getParam("key").empty())
48 setParam("key", key_prefix + convert<docstring>(++key_counter));
52 auto_ptr<Inset> InsetBibitem::doClone() const
54 auto_ptr<InsetBibitem> b(new InsetBibitem(params()));
55 b->autolabel_ = autolabel_;
56 return auto_ptr<Inset>(b);
60 void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
64 case LFUN_INSET_MODIFY: {
65 InsetCommandParams p("bibitem");
66 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
67 if (p.getCmdName().empty()) {
71 if (p["key"] != params()["key"])
72 cur.bv().buffer().changeRefsIfUnique(params()["key"],
73 p["key"], Inset::CITE_CODE);
78 InsetCommand::doDispatch(cur, cmd);
84 void InsetBibitem::read(Buffer const & buf, Lexer & lex)
86 InsetCommand::read(buf, lex);
88 if (prefixIs(getParam("key"), key_prefix)) {
89 int const key = convert<int>(getParam("key").substr(key_prefix.length()));
90 key_counter = max(key_counter, key);
95 docstring const InsetBibitem::getBibLabel() const
97 docstring const & label = getParam("label");
98 return label.empty() ? autolabel_ : label;
102 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
104 return getParam("key") + " [" + getBibLabel() + ']';
108 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
109 OutputParams const &) const
111 odocstringstream oss;
112 oss << '[' << getBibLabel() << "] ";
114 docstring const str = oss.str();
122 docstring const bibitemWidest(Buffer const & buffer)
126 InsetBibitem const * bitem = 0;
128 // FIXME: this font is used unitialized for now but should be set to
129 // a proportional font. Here is what Georg Baum has to say about it:
131 bibitemWidest() is supposed to find the bibitem with the widest label in the
132 output, because that is needed as an argument of the bibliography
133 environment to dtermine the correct indentation. To be 100% correct we
134 would need the metrics of the font that is used in the output, but usually
135 we don't have access to these.
136 In practice, any proportional font is probably good enough, since we don't
137 need to know the final with, we only need to know the which label is the
139 Unless there is an easy way to get the metrics of the output font I suggest
140 to use a hardcoded font like "Times" or so.
142 It is very important that the result of this function is the same both with
143 and without GUI. After thinking about this it is clear that no Font
144 metrics should be used here, since these come from the gui. If we can't
145 easily get the LaTeX font metrics we should make our own poor mans front
146 metrics replacement, e.g. by hardcoding the metrics of the standard TeX
151 ParagraphList::const_iterator it = buffer.paragraphs().begin();
152 ParagraphList::const_iterator end = buffer.paragraphs().end();
154 for (; it != end; ++it) {
156 docstring const label = it->bibitem()->getBibLabel();
158 // FIXME: we can't be sure using the following that the GUI
159 // version and the command-line version will give the same
162 //int const wx = use_gui?
163 // theFontMetrics(font).width(label): label.size();
165 // So for now we just use the label size in order to be sure
166 // that GUI and no-GUI gives the same bibitem (even if that is
167 // potentially the wrong one.
168 int const wx = label.size();
172 bitem = it->bibitem();
177 if (bitem && !bitem->getBibLabel().empty())
178 return bitem->getBibLabel();
180 return from_ascii("99");
184 void InsetBibitem::fillWithBibKeys(Buffer const & buf,
185 BiblioInfo & keys, InsetIterator const & it) const
187 docstring const key = getParam("key");
188 BibTeXInfo keyvalmap;
189 keyvalmap[from_ascii("label")] = getParam("label");
190 DocIterator doc_it(it);
192 keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
193 keyvalmap.isBibTeX = false;
194 keys[key] = keyvalmap;
198 /// Update the counters of this inset and of its contents
199 void InsetBibitem::updateLabels(Buffer const &buf, ParIterator const &)
201 Counters & counters = buf.params().getTextClass().counters();
202 docstring const bibitem = from_ascii("bibitem");
203 if (counters.hasCounter(bibitem) && getParam("label").empty()) {
204 counters.step(bibitem);
205 autolabel_ = counters.theCounter(bibitem);
207 autolabel_ = from_ascii("??");