]> git.lyx.org Git - lyx.git/blob - src/insets/InsetRef.cpp
c2c3358ddd438133ee2458115123a82ca14bd088
[lyx.git] / src / insets / InsetRef.cpp
1 /**
2  * \file InsetRef.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author José Matos
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10 #include <config.h>
11
12 #include "InsetRef.h"
13
14 #include "Buffer.h"
15 #include "buffer_funcs.h"
16 #include "Cursor.h"
17 #include "DispatchResult.h"
18 #include "FuncRequest.h"
19 #include "LaTeXFeatures.h"
20 #include "LyXFunc.h"
21 #include "OutputParams.h"
22 #include "ParIterator.h"
23 #include "sgml.h"
24 #include "TocBackend.h"
25
26 #include "support/docstream.h"
27 #include "support/gettext.h"
28 #include "support/lstrings.h"
29
30 using namespace lyx::support;
31 using namespace std;
32
33 namespace lyx {
34
35
36 InsetRef::InsetRef(Buffer const & buf, InsetCommandParams const & p)
37         : InsetCommand(p, "ref"), isLatex(buf.isLatex())
38 {}
39
40
41 InsetRef::InsetRef(InsetRef const & ir)
42         : InsetCommand(ir), isLatex(ir.isLatex)
43 {}
44
45
46 void InsetRef::initView()
47 {
48         // We need an update of the Buffer reference cache. This is achieved by
49         // updateLabel().
50         lyx::updateLabels(buffer());
51 }
52
53
54 bool InsetRef::isCompatibleCommand(string const & s) {
55         //FIXME This is likely not the best way to handle this.
56         //But this stuff is hardcoded elsewhere already.
57         return s == "ref" 
58                 || s == "pageref"
59                 || s == "vref" 
60                 || s == "vpageref"
61                 || s == "prettyref"
62                 || s == "eqref";
63 }
64
65
66 ParamInfo const & InsetRef::findInfo(string const & /* cmdName */)
67 {
68         static ParamInfo param_info_;
69         if (param_info_.empty()) {
70                 param_info_.add("name", ParamInfo::LATEX_OPTIONAL);
71                 param_info_.add("reference", ParamInfo::LATEX_REQUIRED);
72         }
73         return param_info_;
74 }
75
76
77 void InsetRef::doDispatch(Cursor & cur, FuncRequest & cmd)
78 {
79         switch (cmd.action) {
80         case LFUN_MOUSE_RELEASE:
81                 // Eventually trigger dialog with button 3 not 1
82                 if (cmd.button() == mouse_button::button3)
83                         lyx::dispatch(FuncRequest(LFUN_LABEL_GOTO,
84                                                   getParam("reference")));
85                 else
86                         InsetCommand::doDispatch(cur, cmd);
87                 break;
88
89         default:
90                 InsetCommand::doDispatch(cur, cmd);
91         }
92 }
93
94
95 docstring InsetRef::screenLabel() const
96 {
97         return screen_label_;
98 }
99
100
101 int InsetRef::latex(odocstream & os, OutputParams const &) const
102 {
103         // We don't want to output p_["name"], since that is only used 
104         // in docbook. So we construct new params, without it, and use that.
105         InsetCommandParams p(REF_CODE, getCmdName());
106         p["reference"] = getParam("reference");
107         os << escape(p.getCommand());
108         return 0;
109 }
110
111
112 int InsetRef::plaintext(odocstream & os, OutputParams const &) const
113 {
114         docstring const str = getParam("reference");
115         os << '[' << str << ']';
116         return 2 + str.size();
117 }
118
119
120 int InsetRef::docbook(odocstream & os, OutputParams const & runparams) const
121 {
122         docstring const & name = getParam("name");
123         if (name.empty()) {
124                 if (runparams.flavor == OutputParams::XML) {
125                         os << "<xref linkend=\""
126                            << sgml::cleanID(buffer(), runparams, getParam("reference"))
127                            << "\" />";
128                 } else {
129                         os << "<xref linkend=\""
130                            << sgml::cleanID(buffer(), runparams, getParam("reference"))
131                            << "\">";
132                 }
133         } else {
134                 os << "<link linkend=\""
135                    << sgml::cleanID(buffer(), runparams, getParam("reference"))
136                    << "\">"
137                    << getParam("name")
138                    << "</link>";
139         }
140
141         return 0;
142 }
143
144
145 void InsetRef::textString(odocstream & os) const
146 {
147         plaintext(os, OutputParams(0));
148 }
149
150
151 void InsetRef::updateLabels(ParIterator const & it)
152 {
153         docstring const & label = getParam("reference");
154         // register this inset into the buffer reference cache.
155         buffer().references(label).push_back(make_pair(this, it));
156
157         for (int i = 0; !types[i].latex_name.empty(); ++i) {
158                 if (getCmdName() == types[i].latex_name) {
159                         screen_label_ = _(types[i].short_gui_name);
160                         break;
161                 }
162         }
163         screen_label_ += getParam("reference");
164
165         if (!isLatex && !getParam("name").empty()) {
166                 screen_label_ += "||";
167                 screen_label_ += getParam("name");
168         }
169 }
170
171
172 void InsetRef::addToToc(ParConstIterator const & cpit) const
173 {
174         docstring const & label = getParam("reference");
175         if (buffer().insetLabel(label))
176                 // This InsetRef has already been taken care of in InsetLabel::addToToc().
177                 return;
178
179         // It seems that this reference does not point to any valid label.
180         screen_label_ = _("BROKEN: ") + screen_label_;
181         Toc & toc = buffer().tocBackend().toc("label");
182         toc.push_back(TocItem(cpit, 0, screen_label_));
183 }
184
185
186 void InsetRef::validate(LaTeXFeatures & features) const
187 {
188         if (getCmdName() == "vref" || getCmdName() == "vpageref")
189                 features.require("varioref");
190         else if (getCmdName() == "prettyref")
191                 features.require("prettyref");
192         else if (getCmdName() == "eqref")
193                 features.require("amsmath");
194 }
195
196
197 InsetRef::type_info InsetRef::types[] = {
198         { "ref",       N_("Standard"),              N_("Ref: ")},
199         { "eqref",     N_("Equation"),              N_("EqRef: ")},
200         { "pageref",   N_("Page Number"),           N_("Page: ")},
201         { "vpageref",  N_("Textual Page Number"),   N_("TextPage: ")},
202         { "vref",      N_("Standard+Textual Page"), N_("Ref+Text: ")},
203         { "prettyref", N_("PrettyRef"),             N_("FormatRef: ")},
204         { "", "", "" }
205 };
206
207
208 int InsetRef::getType(string const & name)
209 {
210         for (int i = 0; !types[i].latex_name.empty(); ++i)
211                 if (name == types[i].latex_name)
212                         return i;
213         return 0;
214 }
215
216
217 string const & InsetRef::getName(int type)
218 {
219         return types[type].latex_name;
220 }
221
222
223 } // namespace lyx