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"
35 using namespace lyx::support;
40 int InsetBibitem::key_counter = 0;
43 docstring const key_prefix = from_ascii("key-");
46 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
47 : InsetCommand(p, "bibitem")
49 if (getParam("key").empty())
50 setParam("key", key_prefix + convert<docstring>(++key_counter));
54 CommandInfo const * InsetBibitem::findInfo(string const & /* cmdName */)
56 static const char * const paramnames[] = {"label", "key", ""};
57 static const bool isoptional[] = {true, false};
58 static const CommandInfo info = {2, paramnames, isoptional};
63 Inset * InsetBibitem::clone() const
65 InsetBibitem * b = new InsetBibitem(params());
66 b->autolabel_ = autolabel_;
71 void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
75 case LFUN_INSET_MODIFY: {
76 InsetCommandParams p(BIBITEM_CODE);
77 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
78 if (p.getCmdName().empty()) {
82 if (p["key"] != params()["key"])
83 cur.bv().buffer().changeRefsIfUnique(params()["key"],
89 InsetCommand::doDispatch(cur, cmd);
95 void InsetBibitem::read(Buffer const & buf, Lexer & lex)
97 InsetCommand::read(buf, lex);
99 if (prefixIs(getParam("key"), key_prefix)) {
100 int const key = convert<int>(getParam("key").substr(key_prefix.length()));
101 key_counter = max(key_counter, key);
106 docstring const InsetBibitem::getBibLabel() const
108 docstring const & label = getParam("label");
109 return label.empty() ? autolabel_ : label;
113 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
115 return getParam("key") + " [" + getBibLabel() + ']';
119 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
120 OutputParams const &) const
122 odocstringstream oss;
123 oss << '[' << getBibLabel() << "] ";
125 docstring const str = oss.str();
133 docstring const bibitemWidest(Buffer const & buffer)
137 InsetBibitem const * bitem = 0;
139 // FIXME: this font is used unitialized for now but should be set to
140 // a proportional font. Here is what Georg Baum has to say about it:
142 bibitemWidest() is supposed to find the bibitem with the widest label in the
143 output, because that is needed as an argument of the bibliography
144 environment to dtermine the correct indentation. To be 100% correct we
145 would need the metrics of the font that is used in the output, but usually
146 we don't have access to these.
147 In practice, any proportional font is probably good enough, since we don't
148 need to know the final with, we only need to know the which label is the
150 Unless there is an easy way to get the metrics of the output font I suggest
151 to use a hardcoded font like "Times" or so.
153 It is very important that the result of this function is the same both with
154 and without GUI. After thinking about this it is clear that no Font
155 metrics should be used here, since these come from the gui. If we can't
156 easily get the LaTeX font metrics we should make our own poor mans font
157 metrics replacement, e.g. by hardcoding the metrics of the standard TeX
161 ParagraphList::const_iterator it = buffer.paragraphs().begin();
162 ParagraphList::const_iterator end = buffer.paragraphs().end();
164 for (; it != end; ++it) {
165 if (it->insetList().empty())
167 Inset * inset = it->insetList().begin()->inset;
168 if (inset->lyxCode() != BIBITEM_CODE)
171 bitem = static_cast<InsetBibitem const *>(inset);
172 docstring const label = bitem->getBibLabel();
174 // FIXME: we can't be sure using the following that the GUI
175 // version and the command-line version will give the same
178 //int const wx = use_gui?
179 // theFontMetrics(font).width(label): label.size();
181 // So for now we just use the label size in order to be sure
182 // that GUI and no-GUI gives the same bibitem (even if that is
183 // potentially the wrong one.
184 int const wx = label.size();
190 if (bitem && !bitem->getBibLabel().empty())
191 return bitem->getBibLabel();
193 return from_ascii("99");
197 void InsetBibitem::fillWithBibKeys(Buffer const & buf,
198 BiblioInfo & keys, InsetIterator const & it) const
200 docstring const key = getParam("key");
201 BibTeXInfo keyvalmap;
202 keyvalmap[from_ascii("label")] = getParam("label");
203 DocIterator doc_it(it);
205 keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
206 keyvalmap.isBibTeX = false;
207 keys[key] = keyvalmap;
211 /// Update the counters of this inset and of its contents
212 void InsetBibitem::updateLabels(Buffer const &buf, ParIterator const &)
214 Counters & counters = buf.params().getTextClass().counters();
215 docstring const bibitem = from_ascii("bibitem");
216 if (counters.hasCounter(bibitem) && getParam("label").empty()) {
217 counters.step(bibitem);
218 autolabel_ = counters.theCounter(bibitem);
220 autolabel_ = from_ascii("??");