]> git.lyx.org Git - features.git/blob - src/insets/InsetBibitem.cpp
getting rid of superfluous std:: statements.
[features.git] / src / insets / InsetBibitem.cpp
1 /**
2  * \file InsetBibitem.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "InsetBibitem.h"
14
15 #include "Buffer.h"
16 #include "BufferParams.h"
17 #include "BufferView.h"
18 #include "Counters.h"
19 #include "DispatchResult.h"
20 #include "FuncRequest.h"
21 #include "InsetIterator.h"
22 #include "InsetList.h"
23 #include "Lexer.h"
24 #include "Paragraph.h"
25 #include "ParagraphList.h"
26 #include "TextClass.h"
27
28 #include "support/lstrings.h"
29 #include "support/docstream.h"
30 #include "support/convert.h"
31
32 #include <ostream>
33
34 using namespace std;
35
36 namespace lyx {
37
38
39 int InsetBibitem::key_counter = 0;
40
41
42 docstring const key_prefix = from_ascii("key-");
43
44
45 InsetBibitem::InsetBibitem(InsetCommandParams const & p)
46         : InsetCommand(p, "bibitem")
47 {
48         if (getParam("key").empty())
49                 setParam("key", key_prefix + convert<docstring>(++key_counter));
50 }
51
52
53 CommandInfo const * InsetBibitem::findInfo(string const & /* cmdName */)
54 {
55         static const char * const paramnames[] = {"label", "key", ""};
56         static const bool isoptional[] = {true, false};
57         static const CommandInfo info = {2, paramnames, isoptional};
58         return &info;
59 }
60
61
62 Inset * InsetBibitem::clone() const
63 {
64         InsetBibitem * b = new InsetBibitem(params());
65         b->autolabel_ = autolabel_;
66         return b;
67 }
68
69
70 void InsetBibitem::doDispatch(Cursor & cur, FuncRequest & cmd)
71 {
72         switch (cmd.action) {
73
74         case LFUN_INSET_MODIFY: {
75                 InsetCommandParams p(BIBITEM_CODE);
76                 InsetCommandMailer::string2params("bibitem", to_utf8(cmd.argument()), p);
77                 if (p.getCmdName().empty()) {
78                         cur.noUpdate();
79                         break;
80                 }
81                 if (p["key"] != params()["key"])
82                         cur.bv().buffer().changeRefsIfUnique(params()["key"],
83                                                        p["key"], CITE_CODE);
84                 setParams(p);
85         }
86
87         default:
88                 InsetCommand::doDispatch(cur, cmd);
89                 break;
90         }
91 }
92
93
94 void InsetBibitem::read(Buffer const & buf, Lexer & lex)
95 {
96         InsetCommand::read(buf, lex);
97
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);
101         }
102 }
103
104
105 docstring const InsetBibitem::getBibLabel() const
106 {
107         docstring const & label = getParam("label");
108         return label.empty() ? autolabel_ : label;
109 }
110
111
112 docstring const InsetBibitem::getScreenLabel(Buffer const &) const
113 {
114         return getParam("key") + " [" + getBibLabel() + ']';
115 }
116
117
118 int InsetBibitem::plaintext(Buffer const &, odocstream & os,
119                             OutputParams const &) const
120 {
121         odocstringstream oss;
122         oss << '[' << getBibLabel() << "] ";
123
124         docstring const str = oss.str();
125         os << str;
126
127         return str.size();
128 }
129
130
131 // ale070405
132 docstring const bibitemWidest(Buffer const & buffer)
133 {
134         int w = 0;
135
136         InsetBibitem const * bitem = 0;
137
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:
140         /*
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
148         widest.
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.
151
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
157         font.
158         */
159
160         ParagraphList::const_iterator it = buffer.paragraphs().begin();
161         ParagraphList::const_iterator end = buffer.paragraphs().end();
162
163         for (; it != end; ++it) {
164                 if (it->insetList().empty())
165                         continue;
166                 Inset * inset = it->insetList().begin()->inset;
167                 if (inset->lyxCode() != BIBITEM_CODE)
168                         continue;
169
170                 bitem = static_cast<InsetBibitem const *>(inset);
171                 docstring const label = bitem->getBibLabel();
172
173                 // FIXME: we can't be sure using the following that the GUI
174                 // version and the command-line version will give the same
175                 // result.
176                 //
177                 //int const wx = use_gui?
178                 //      theFontMetrics(font).width(label): label.size();
179                 //
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();
184
185                 if (wx > w)
186                         w = wx;
187         }
188
189         if (bitem && !bitem->getBibLabel().empty())
190                 return bitem->getBibLabel();
191
192         return from_ascii("99");
193 }
194
195
196 void InsetBibitem::fillWithBibKeys(Buffer const & buf,
197         BiblioInfo & keys, InsetIterator const & it) const
198 {
199         docstring const key = getParam("key");
200         BibTeXInfo keyvalmap;
201         keyvalmap[from_ascii("label")] = getParam("label");
202         DocIterator doc_it(it); 
203         doc_it.forwardPos();
204         keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
205         keyvalmap.isBibTeX = false;
206         keys[key] = keyvalmap;
207 }
208
209
210 /// Update the counters of this inset and of its contents
211 void InsetBibitem::updateLabels(Buffer const &buf, ParIterator const &) 
212 {
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);
218         } else
219                 autolabel_ = from_ascii("??");
220         refresh();
221 }
222
223
224 } // namespace lyx