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);
107 Layout::LaTeXArgMap::const_iterator const lait = args.find(name_);
108 if (lait != args.end()) {
109 docstring label = translateIfPossible((*lait).second.labelstring);
110 docstring striplabel;
111 support::rsplit(label, striplabel, '|');
112 labelstring_ = striplabel.empty() ? label: striplabel;
113 tooltip_ = translateIfPossible((*lait).second.tooltip);
114 font_ = (*lait).second.font;
115 labelfont_ = (*lait).second.labelfont;
116 decoration_ = (*lait).second.decoration;
117 pass_thru_chars_ = (*lait).second.pass_thru_chars;
119 labelstring_ = _("Unknown Argument");
120 tooltip_ = _("Argument not known in this Layout. Will be supressed in the output.");
123 InsetCollapsable::updateBuffer(it, utype);
127 void InsetArgument::setButtonLabel()
129 setLabel(labelstring_);
133 docstring InsetArgument::toolTip(BufferView const & bv, int, int) const
137 return toolTipText(tooltip_ + from_ascii(":\n"));
141 void InsetArgument::doDispatch(Cursor & cur, FuncRequest & cmd)
143 switch (cmd.action()) {
145 case LFUN_INSET_MODIFY: {
146 string const first_arg = cmd.getArg(0);
147 bool const change_type = first_arg == "changetype";
150 // this will not be handled higher up
154 cur.recordUndoInset(this);
155 name_ = cmd.getArg(1);
156 cur.forceBufferUpdate();
161 case LFUN_CLIPBOARD_PASTE:
162 case LFUN_SELECTION_PASTE:
163 case LFUN_PRIMARY_SELECTION_PASTE:
164 // Do not call InsetCollapsable::doDispatch(cur, cmd)
165 // with (inherited) pass_thru to avoid call for
166 // fixParagraphsFont(), which does not play nicely with
167 // inherited pass_thru (see #8471).
168 // FIXME: Once we have implemented genuine pass_thru
169 // option for InsetArgument (not inherited pass_thru),
170 // we should probably directly call
171 // InsetCollapsable::doDispatch(cur, cmd) for that
174 text().dispatch(cur, cmd);
176 InsetCollapsable::doDispatch(cur, cmd);
180 InsetCollapsable::doDispatch(cur, cmd);
186 bool InsetArgument::getStatus(Cursor & cur, FuncRequest const & cmd,
187 FuncStatus & flag) const
189 switch (cmd.action()) {
191 case LFUN_INSET_MODIFY: {
192 string const first_arg = cmd.getArg(0);
193 if (first_arg == "changetype") {
194 string const type = cmd.getArg(1);
195 flag.setOnOff(type == name_);
197 flag.setEnabled(true);
200 Layout::LaTeXArgMap args;
201 bool const insetlayout = cur.paragraph().layout().latexargs().empty();
203 args = cur.inset().getLayout().latexargs();
205 args = cur.paragraph().layout().latexargs();
206 Layout::LaTeXArgMap::const_iterator const lait = args.find(type);
207 if (lait != args.end()) {
208 flag.setEnabled(true);
209 InsetList::const_iterator it = cur.paragraph().insetList().begin();
210 InsetList::const_iterator end = cur.paragraph().insetList().end();
211 for (; it != end; ++it) {
212 if (it->inset->lyxCode() == ARG_CODE) {
213 InsetArgument const * ins =
214 static_cast<InsetArgument const *>(it->inset);
215 if (ins->name() == type) {
216 // we have this already
217 flag.setEnabled(false);
223 flag.setEnabled(false);
226 return InsetCollapsable::getStatus(cur, cmd, flag);
230 return InsetCollapsable::getStatus(cur, cmd, flag);
235 string InsetArgument::contextMenuName() const
237 if (decoration() == InsetLayout::CONGLOMERATE)
238 return "context-argument-conglomerate";
240 return "context-argument";
244 FontInfo InsetArgument::getFont() const
246 if (font_ != inherit_font)
248 return InsetCollapsable::getFont();
252 FontInfo InsetArgument::getLabelfont() const
254 if (labelfont_ != inherit_font)
256 return InsetCollapsable::getLabelfont();
260 ColorCode InsetArgument::labelColor() const {
261 if (labelfont_.color() != Color_inherit)
262 return labelfont_.color();
263 return InsetCollapsable::labelColor();
267 InsetLayout::InsetDecoration InsetArgument::decoration() const
269 InsetLayout::InsetDecoration dec = getLayout().decoration();
270 if (!decoration_.empty())
271 dec = translateDecoration(decoration_);
272 return dec == InsetLayout::DEFAULT ? InsetLayout::CLASSIC : dec;
276 void InsetArgument::latexArgument(otexstream & os,
277 OutputParams const & runparams_in, docstring const & ldelim,
278 docstring const & rdelim, docstring const & presetarg) const
280 otexstringstream ots;
281 OutputParams runparams = runparams_in;
282 if (!pass_thru_chars_.empty())
283 runparams.pass_thru_chars += pass_thru_chars_;
284 InsetText::latex(ots, runparams);
285 TexString ts = ots.release();
286 bool const add_braces = ldelim != "{" && support::contains(ts.str, rdelim);
291 if (!presetarg.empty() && !ts.str.empty())