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"
21 #include "InsetIterator.h"
22 #include "InsetList.h"
24 #include "Paragraph.h"
25 #include "ParagraphList.h"
26 #include "TextClass.h"
28 #include "support/lstrings.h"
29 #include "support/docstream.h"
30 #include "support/convert.h"
39 int InsetBibitem::key_counter = 0;
42 docstring const key_prefix = from_ascii("key-");
45 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
46 : InsetCommand(p, "bibitem")
48 if (getParam("key").empty())
49 setParam("key", key_prefix + convert<docstring>(++key_counter));
53 CommandInfo const * InsetBibitem::findInfo(string const & /* cmdName */)
55 static const char * const paramnames[] = {"label", "key", ""};
56 static const bool isoptional[] = {true, false};
57 static const CommandInfo info = {2, paramnames, isoptional};
62 Inset * InsetBibitem::clone() const
64 InsetBibitem * b = new InsetBibitem(params());
65 b->autolabel_ = autolabel_;
70 void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
74 case LFUN_INSET_MODIFY: {
75 InsetCommandParams p(BIBITEM_CODE);
76 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
77 if (p.getCmdName().empty()) {
81 if (p["key"] != params()["key"])
82 cur.bv().buffer().changeRefsIfUnique(params()["key"],
88 InsetCommand::doDispatch(cur, cmd);
94 void InsetBibitem::read(Buffer const & buf, Lexer & lex)
96 InsetCommand::read(buf, lex);
98 if (support::prefixIs(getParam("key"), key_prefix)) {
99 int const key = convert<int>(getParam("key").substr(key_prefix.length()));
100 key_counter = max(key_counter, key);
105 docstring const InsetBibitem::getBibLabel() const
107 docstring const & label = getParam("label");
108 return label.empty() ? autolabel_ : label;
112 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
114 return getParam("key") + " [" + getBibLabel() + ']';
118 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
119 OutputParams const &) const
121 odocstringstream oss;
122 oss << '[' << getBibLabel() << "] ";
124 docstring const str = oss.str();
132 docstring const bibitemWidest(Buffer const & buffer)
136 InsetBibitem const * bitem = 0;
138 // FIXME: this font is used unitialized for now but should be set to
139 // a proportional font. Here is what Georg Baum has to say about it:
141 bibitemWidest() is supposed to find the bibitem with the widest label in the
142 output, because that is needed as an argument of the bibliography
143 environment to dtermine the correct indentation. To be 100% correct we
144 would need the metrics of the font that is used in the output, but usually
145 we don't have access to these.
146 In practice, any proportional font is probably good enough, since we don't
147 need to know the final with, we only need to know the which label is the
149 Unless there is an easy way to get the metrics of the output font I suggest
150 to use a hardcoded font like "Times" or so.
152 It is very important that the result of this function is the same both with
153 and without GUI. After thinking about this it is clear that no Font
154 metrics should be used here, since these come from the gui. If we can't
155 easily get the LaTeX font metrics we should make our own poor mans font
156 metrics replacement, e.g. by hardcoding the metrics of the standard TeX
160 ParagraphList::const_iterator it = buffer.paragraphs().begin();
161 ParagraphList::const_iterator end = buffer.paragraphs().end();
163 for (; it != end; ++it) {
164 if (it->insetList().empty())
166 Inset * inset = it->insetList().begin()->inset;
167 if (inset->lyxCode() != BIBITEM_CODE)
170 bitem = static_cast<InsetBibitem const *>(inset);
171 docstring const label = bitem->getBibLabel();
173 // FIXME: we can't be sure using the following that the GUI
174 // version and the command-line version will give the same
177 //int const wx = use_gui?
178 // theFontMetrics(font).width(label): label.size();
180 // So for now we just use the label size in order to be sure
181 // that GUI and no-GUI gives the same bibitem (even if that is
182 // potentially the wrong one.
183 int const wx = label.size();
189 if (bitem && !bitem->getBibLabel().empty())
190 return bitem->getBibLabel();
192 return from_ascii("99");
196 void InsetBibitem::fillWithBibKeys(Buffer const & buf,
197 BiblioInfo & keys, InsetIterator const & it) const
199 docstring const key = getParam("key");
200 BibTeXInfo keyvalmap;
201 keyvalmap[from_ascii("label")] = getParam("label");
202 DocIterator doc_it(it);
204 keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
205 keyvalmap.isBibTeX = false;
206 keys[key] = keyvalmap;
210 /// Update the counters of this inset and of its contents
211 void InsetBibitem::updateLabels(Buffer const &buf, ParIterator const &)
213 Counters & counters = buf.params().getTextClass().counters();
214 docstring const bibitem = from_ascii("bibitem");
215 if (counters.hasCounter(bibitem) && getParam("label").empty()) {
216 counters.step(bibitem);
217 autolabel_ = counters.theCounter(bibitem);
219 autolabel_ = from_ascii("??");