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"
37 int InsetBibitem::key_counter = 0;
40 docstring const key_prefix = from_ascii("key-");
43 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
44 : InsetCommand(p, "bibitem")
46 if (getParam("key").empty())
47 setParam("key", key_prefix + convert<docstring>(++key_counter));
51 CommandInfo const * InsetBibitem::findInfo(std::string const & /* cmdName */)
53 static const char * const paramnames[] = {"label", "key", ""};
54 static const bool isoptional[] = {true, false};
55 static const CommandInfo info = {2, paramnames, isoptional};
60 Inset * InsetBibitem::clone() const
62 InsetBibitem * b = new InsetBibitem(params());
63 b->autolabel_ = autolabel_;
68 void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
72 case LFUN_INSET_MODIFY: {
73 InsetCommandParams p(BIBITEM_CODE);
74 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
75 if (p.getCmdName().empty()) {
79 if (p["key"] != params()["key"])
80 cur.bv().buffer().changeRefsIfUnique(params()["key"],
86 InsetCommand::doDispatch(cur, cmd);
92 void InsetBibitem::read(Buffer const & buf, Lexer & lex)
94 InsetCommand::read(buf, lex);
96 if (support::prefixIs(getParam("key"), key_prefix)) {
97 int const key = convert<int>(getParam("key").substr(key_prefix.length()));
98 key_counter = std::max(key_counter, key);
103 docstring const InsetBibitem::getBibLabel() const
105 docstring const & label = getParam("label");
106 return label.empty() ? autolabel_ : label;
110 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
112 return getParam("key") + " [" + getBibLabel() + ']';
116 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
117 OutputParams const &) const
119 odocstringstream oss;
120 oss << '[' << getBibLabel() << "] ";
122 docstring const str = oss.str();
130 docstring const bibitemWidest(Buffer const & buffer)
134 InsetBibitem const * bitem = 0;
136 // FIXME: this font is used unitialized for now but should be set to
137 // a proportional font. Here is what Georg Baum has to say about it:
139 bibitemWidest() is supposed to find the bibitem with the widest label in the
140 output, because that is needed as an argument of the bibliography
141 environment to dtermine the correct indentation. To be 100% correct we
142 would need the metrics of the font that is used in the output, but usually
143 we don't have access to these.
144 In practice, any proportional font is probably good enough, since we don't
145 need to know the final with, we only need to know the which label is the
147 Unless there is an easy way to get the metrics of the output font I suggest
148 to use a hardcoded font like "Times" or so.
150 It is very important that the result of this function is the same both with
151 and without GUI. After thinking about this it is clear that no Font
152 metrics should be used here, since these come from the gui. If we can't
153 easily get the LaTeX font metrics we should make our own poor mans font
154 metrics replacement, e.g. by hardcoding the metrics of the standard TeX
158 ParagraphList::const_iterator it = buffer.paragraphs().begin();
159 ParagraphList::const_iterator end = buffer.paragraphs().end();
161 for (; it != end; ++it) {
162 if (it->insetList().empty())
164 Inset * inset = it->insetList().begin()->inset;
165 if (inset->lyxCode() != BIBITEM_CODE)
168 bitem = static_cast<InsetBibitem const *>(inset);
169 docstring const label = bitem->getBibLabel();
171 // FIXME: we can't be sure using the following that the GUI
172 // version and the command-line version will give the same
175 //int const wx = use_gui?
176 // theFontMetrics(font).width(label): label.size();
178 // So for now we just use the label size in order to be sure
179 // that GUI and no-GUI gives the same bibitem (even if that is
180 // potentially the wrong one.
181 int const wx = label.size();
187 if (bitem && !bitem->getBibLabel().empty())
188 return bitem->getBibLabel();
190 return from_ascii("99");
194 void InsetBibitem::fillWithBibKeys(Buffer const & buf,
195 BiblioInfo & keys, InsetIterator const & it) const
197 docstring const key = getParam("key");
198 BibTeXInfo keyvalmap;
199 keyvalmap[from_ascii("label")] = getParam("label");
200 DocIterator doc_it(it);
202 keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
203 keyvalmap.isBibTeX = false;
204 keys[key] = keyvalmap;
208 /// Update the counters of this inset and of its contents
209 void InsetBibitem::updateLabels(Buffer const &buf, ParIterator const &)
211 Counters & counters = buf.params().getTextClass().counters();
212 docstring const bibitem = from_ascii("bibitem");
213 if (counters.hasCounter(bibitem) && getParam("label").empty()) {
214 counters.step(bibitem);
215 autolabel_ = counters.theCounter(bibitem);
217 autolabel_ = from_ascii("??");