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 "BufferView.h"
17 #include "dispatchresult.h"
18 #include "funcrequest.h"
21 #include "paragraph.h"
22 #include "ParagraphList.h"
24 #include "support/lstrings.h"
25 #include "support/std_ostream.h"
26 #include "support/convert.h"
31 using support::prefixIs;
38 int InsetBibitem::key_counter = 0;
39 docstring const key_prefix = from_ascii("key-");
41 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
42 : InsetCommand(p, "bibitem"), counter(1)
44 if (getParam("key").empty())
45 setParam("key", key_prefix + convert<docstring>(++key_counter));
49 auto_ptr<InsetBase> InsetBibitem::doClone() const
51 auto_ptr<InsetBibitem> b(new InsetBibitem(params()));
52 b->setCounter(counter);
53 return auto_ptr<InsetBase>(b);
57 void InsetBibitem::doDispatch(LCursor & cur, FuncRequest & cmd)
61 case LFUN_INSET_MODIFY: {
62 InsetCommandParams p("bibitem");
63 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
64 if (p.getCmdName().empty()) {
68 if (p["key"] != params()["key"])
69 cur.bv().buffer()->changeRefsIfUnique(params()["key"],
70 p["key"], InsetBase::CITE_CODE);
75 InsetCommand::doDispatch(cur, cmd);
81 void InsetBibitem::setCounter(int c)
87 void InsetBibitem::read(Buffer const & buf, LyXLex & lex)
89 InsetCommand::read(buf, lex);
91 if (prefixIs(getParam("key"), key_prefix)) {
92 int const key = convert<int>(getParam("key").substr(key_prefix.length()));
93 key_counter = max(key_counter, key);
98 docstring const InsetBibitem::getBibLabel() const
100 docstring const & label = getParam("label");
101 return label.empty() ? convert<docstring>(counter) : label;
105 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
107 return getParam("key") + " [" + getBibLabel() + ']';
111 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
112 OutputParams const &) const
114 odocstringstream oss;
115 oss << '[' << getCounter() << "] ";
117 docstring const str = oss.str();
125 docstring const bibitemWidest(Buffer const & buffer)
129 InsetBibitem const * bitem = 0;
131 // FIXME: this font is used unitialized for now but should be set to
132 // a proportional font. Here is what Georg Baum has to say about it:
134 bibitemWidest() is supposed to find the bibitem with the widest label in the
135 output, because that is needed as an argument of the bibliography
136 environment to dtermine the correct indentation. To be 100% correct we
137 would need the metrics of the font that is used in the output, but usually
138 we don't have access to these.
139 In practice, any proportional font is probably good enough, since we don't
140 need to know the final with, we only need to know the which label is the
142 Unless there is an easy way to get the metrics of the output font I suggest
143 to use a hardcoded font like "Times" or so.
145 It is very important that the result of this function is the same both with
146 and without GUI. After thinking about this it is clear that no LyXFont
147 metrics should be used here, since these come from the gui. If we can't
148 easily get the LaTeX font metrics we should make our own poor mans front
149 metrics replacement, e.g. by hardcoding the metrics of the standard TeX
154 ParagraphList::const_iterator it = buffer.paragraphs().begin();
155 ParagraphList::const_iterator end = buffer.paragraphs().end();
157 for (; it != end; ++it) {
159 docstring const label = it->bibitem()->getBibLabel();
161 // FIXME: we can't be sure using the following that the GUI
162 // version and the command-line version will give the same
165 //int const wx = use_gui?
166 // theFontMetrics(font).width(label): label.size();
168 // So for now we just use the label size in order to be sure
169 // that GUI and no-GUI gives the same bibitem (even if that is
170 // potentially the wrong one.
171 int const wx = label.size();
175 bitem = it->bibitem();
180 if (bitem && !bitem->getBibLabel().empty())
181 return bitem->getBibLabel();
183 return from_ascii("99");