2 * \file InsetArgument.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Martin Vermeer
7 * \author Jürgen Spitzmüller
9 * Full author contact details are available in file CREDITS.
14 #include "InsetArgument.h"
17 #include "BufferParams.h"
19 #include "FuncStatus.h"
20 #include "FuncRequest.h"
21 #include "InsetList.h"
25 #include "OutputParams.h"
26 #include "ParIterator.h"
28 #include "texstream.h"
30 #include "support/convert.h"
31 #include "support/debug.h"
32 #include "support/docstream.h"
33 #include "support/gettext.h"
34 #include "support/lstrings.h"
41 InsetArgument::InsetArgument(Buffer * buf, string const & name)
42 : InsetCollapsable(buf), name_(name), labelstring_(docstring()),
43 font_(inherit_font), labelfont_(inherit_font), decoration_(string()),
44 pass_thru_(false), pass_thru_chars_(docstring())
48 void InsetArgument::write(ostream & os) const
50 os << "Argument " << name_ << "\n";
51 InsetCollapsable::write(os);
55 void InsetArgument::read(Lexer & lex)
58 InsetCollapsable::read(lex);
62 void InsetArgument::updateBuffer(ParIterator const & it, UpdateType utype)
64 Layout::LaTeXArgMap args = it.paragraph().layout().args();
65 pass_thru_ = it.paragraph().layout().pass_thru;
66 bool const insetlayout = args.empty();
68 args = it.inset().getLayout().args();
69 pass_thru_ = it.inset().getLayout().isPassThru();
72 // Handle pre 2.1 ArgInsets (lyx2lyx cannot classify them)
74 unsigned int const req = insetlayout ? it.inset().getLayout().requiredArgs()
75 : it.paragraph().layout().requiredArgs();
76 unsigned int const opts = insetlayout ? it.inset().getLayout().optArgs()
77 : it.paragraph().layout().optArgs();
79 unsigned int ours = 0;
80 InsetList::const_iterator parit = it.paragraph().insetList().begin();
81 InsetList::const_iterator parend = it.paragraph().insetList().end();
82 for (; parit != parend; ++parit) {
83 if (parit->inset->lyxCode() == ARG_CODE) {
85 if (parit->inset == this)
90 unsigned int realopts = 0;
92 // We have optional arguments
94 if (ours <= realopts) {
95 name_ = convert<string>(ours);
100 // This is a mandatory argument. We have to consider
101 // non-given optional arguments for the numbering
102 int offset = opts - realopts;
104 name_ = convert<string>(ours);
108 // FIXME It does not look to me as if this needs to be redone
109 // over and over again. All the arguments are coming from the
110 // layout. If that changes....
111 Layout::LaTeXArgMap::const_iterator const lait = args.find(name_);
112 if (lait != args.end()) {
113 docstring label = translateIfPossible((*lait).second.labelstring);
114 docstring striplabel;
115 support::rsplit(label, striplabel, '|');
116 labelstring_ = striplabel.empty() ? label: striplabel;
117 tooltip_ = translateIfPossible((*lait).second.tooltip);
118 font_ = (*lait).second.font;
119 labelfont_ = (*lait).second.labelfont;
120 decoration_ = (*lait).second.decoration;
121 pass_thru_chars_ = (*lait).second.pass_thru_chars;
123 labelstring_ = _("Unknown Argument");
124 tooltip_ = _("Argument not known in this Layout. Will be supressed in the output.");
127 InsetCollapsable::updateBuffer(it, utype);
131 void InsetArgument::setButtonLabel()
133 setLabel(labelstring_);
137 docstring InsetArgument::toolTip(BufferView const & bv, int, int) const
141 return toolTipText(tooltip_ + from_ascii(":\n"));
145 void InsetArgument::doDispatch(Cursor & cur, FuncRequest & cmd)
147 switch (cmd.action()) {
149 case LFUN_INSET_MODIFY: {
150 string const first_arg = cmd.getArg(0);
151 bool const change_type = first_arg == "changetype";
154 // this will not be handled higher up
158 cur.recordUndoInset(this);
159 name_ = cmd.getArg(1);
160 cur.forceBufferUpdate();
165 case LFUN_CLIPBOARD_PASTE:
166 case LFUN_SELECTION_PASTE:
167 case LFUN_PRIMARY_SELECTION_PASTE:
168 // Do not call InsetCollapsable::doDispatch(cur, cmd)
169 // with (inherited) pass_thru to avoid call for
170 // fixParagraphsFont(), which does not play nicely with
171 // inherited pass_thru (see #8471).
172 // FIXME: Once we have implemented genuine pass_thru
173 // option for InsetArgument (not inherited pass_thru),
174 // we should probably directly call
175 // InsetCollapsable::doDispatch(cur, cmd) for that
178 text().dispatch(cur, cmd);
180 InsetCollapsable::doDispatch(cur, cmd);
184 InsetCollapsable::doDispatch(cur, cmd);
190 bool InsetArgument::getStatus(Cursor & cur, FuncRequest const & cmd,
191 FuncStatus & flag) const
193 switch (cmd.action()) {
195 case LFUN_INSET_MODIFY: {
196 string const first_arg = cmd.getArg(0);
197 if (first_arg == "changetype") {
198 string const type = cmd.getArg(1);
199 flag.setOnOff(type == name_);
201 flag.setEnabled(true);
204 Layout::LaTeXArgMap args;
205 bool const insetlayout = cur.paragraph().layout().latexargs().empty();
207 args = cur.inset().getLayout().latexargs();
209 args = cur.paragraph().layout().latexargs();
210 Layout::LaTeXArgMap::const_iterator const lait = args.find(type);
211 if (lait != args.end()) {
212 flag.setEnabled(true);
213 InsetList::const_iterator it = cur.paragraph().insetList().begin();
214 InsetList::const_iterator end = cur.paragraph().insetList().end();
215 for (; it != end; ++it) {
216 if (it->inset->lyxCode() == ARG_CODE) {
217 InsetArgument const * ins =
218 static_cast<InsetArgument const *>(it->inset);
219 if (ins->name() == type) {
220 // we have this already
221 flag.setEnabled(false);
227 flag.setEnabled(false);
230 return InsetCollapsable::getStatus(cur, cmd, flag);
234 return InsetCollapsable::getStatus(cur, cmd, flag);
239 string InsetArgument::contextMenuName() const
241 if (decoration() == InsetLayout::CONGLOMERATE)
242 return "context-argument-conglomerate";
244 return "context-argument";
248 FontInfo InsetArgument::getFont() const
250 if (font_ != inherit_font)
252 return getLayout().font();
256 FontInfo InsetArgument::getLabelfont() const
258 if (labelfont_ != inherit_font)
260 return getLayout().labelfont();
264 InsetLayout::InsetDecoration InsetArgument::decoration() const
266 InsetLayout::InsetDecoration dec = getLayout().decoration();
267 if (!decoration_.empty())
268 dec = translateDecoration(decoration_);
269 return dec == InsetLayout::DEFAULT ? InsetLayout::CLASSIC : dec;
273 void InsetArgument::latexArgument(otexstream & os,
274 OutputParams const & runparams_in, docstring const & ldelim,
275 docstring const & rdelim, docstring const & presetarg) const
279 OutputParams runparams = runparams_in;
280 if (!pass_thru_chars_.empty())
281 runparams.pass_thru_chars += pass_thru_chars_;
282 InsetText::latex(ots, runparams);
283 docstring str = ss.str();
284 docstring const sep = str.empty() ? docstring() : from_ascii(", ");
285 if (!presetarg.empty())
286 str = presetarg + sep + str;
287 if (ldelim != "{" && support::contains(str, rdelim))
288 str = '{' + str + '}';
289 // TODO: append texrow information
290 os << ldelim << str << rdelim;