+ if (pos <= numargs_ && pos >= optionals_ && numargs_ < 9) {
+ ++numargs_;
+
+ // append example #n
+ if (addarg) {
+ shiftArguments(pos, 1);
+
+ cell(defIdx()).push_back(MathAtom(new MathMacroArgument(pos + 1)));
+ if (!cell(displayIdx()).empty())
+ cell(displayIdx()).push_back(MathAtom(new MathMacroArgument(pos + 1)));
+ }
+
+ if (!greedy) {
+ // fix macro instances
+ AddRemoveMacroInstanceFix fix(pos, true);
+ fixMacroInstances(cur, inset_pos, name(), fix);
+ }
+ }
+
+ updateLook();
+}
+
+
+void MathMacroTemplate::removeParameter(Cursor & cur,
+ DocIterator const & inset_pos, int pos, bool greedy)
+{
+ if (pos < numargs_ && pos >= 0) {
+ --numargs_;
+ removeArguments(cur, inset_pos, pos, pos);
+ shiftArguments(pos + 1, -1);
+
+ // removed optional parameter?
+ if (pos < optionals_) {
+ --optionals_;
+ optionalValues_[pos] = cell(optIdx(pos));
+ cells_.erase(cells_.begin() + optIdx(pos));
+
+ // fix cursor
+ int macroSlice = cur.find(this);
+ if (macroSlice != -1) {
+ if (cur[macroSlice].idx() == optIdx(pos)) {
+ cur.cutOff(macroSlice);
+ cur[macroSlice].idx() = 1;
+ cur[macroSlice].pos() = 0;
+ } else if (cur[macroSlice].idx() > optIdx(pos))
+ --cur[macroSlice].idx();
+ }
+ }
+
+ if (!greedy) {
+ // fix macro instances
+ AddRemoveMacroInstanceFix fix(pos, false);
+ fixMacroInstances(cur, inset_pos, name(), fix);
+ }
+ }
+
+ updateLook();
+}
+
+
+void MathMacroTemplate::makeOptional(Cursor & cur,
+ DocIterator const & inset_pos)
+{
+ if (numargs_ > 0 && optionals_ < numargs_) {
+ ++optionals_;
+ cells_.insert(cells_.begin() + optIdx(optionals_ - 1), optionalValues_[optionals_ - 1]);
+ // fix cursor
+ int macroSlice = cur.find(this);
+ if (macroSlice != -1 && cur[macroSlice].idx() >= optIdx(optionals_ - 1))
+ ++cur[macroSlice].idx();
+
+ // fix macro instances
+ OptionalsMacroInstanceFix fix(optionals_);
+ fixMacroInstances(cur, inset_pos, name(), fix);
+ }
+
+ updateLook();
+}
+
+
+void MathMacroTemplate::makeNonOptional(Cursor & cur,
+ DocIterator const & inset_pos)
+{
+ if (numargs_ > 0 && optionals_ > 0) {
+ --optionals_;
+
+ // store default value for later if the user changes his mind
+ optionalValues_[optionals_] = cell(optIdx(optionals_));
+ cells_.erase(cells_.begin() + optIdx(optionals_));
+
+ // fix cursor
+ int macroSlice = cur.find(this);
+ if (macroSlice != -1) {
+ if (cur[macroSlice].idx() > optIdx(optionals_))
+ --cur[macroSlice].idx();
+ else if (cur[macroSlice].idx() == optIdx(optionals_)) {
+ cur.cutOff(macroSlice);
+ cur[macroSlice].idx() = optIdx(optionals_);
+ cur[macroSlice].pos() = 0;
+ }
+ }
+
+ // fix macro instances
+ OptionalsMacroInstanceFix fix(optionals_);
+ fixMacroInstances(cur, inset_pos, name(), fix);
+ }
+
+ updateLook();
+}
+
+
+void MathMacroTemplate::doDispatch(Cursor & cur, FuncRequest & cmd)
+{
+ string const arg = to_utf8(cmd.argument());
+ switch (cmd.action()) {
+
+ case LFUN_MATH_MACRO_ADD_PARAM:
+ if (numargs_ < 9) {
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ size_t pos = numargs_;
+ if (arg.size() != 0)
+ pos = (size_t)convert<int>(arg) - 1; // it is checked for >=0 in getStatus
+ insertParameter(cur, cur, pos);
+ }
+ break;
+
+
+ case LFUN_MATH_MACRO_REMOVE_PARAM:
+ if (numargs_ > 0) {
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ size_t pos = numargs_ - 1;
+ if (arg.size() != 0)
+ pos = (size_t)convert<int>(arg) - 1; // it is checked for >=0 in getStatus
+ removeParameter(cur, cur, pos);
+ }
+ break;
+
+ case LFUN_MATH_MACRO_APPEND_GREEDY_PARAM:
+ if (numargs_ < 9) {
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ insertParameter(cur, cur, numargs_, true);
+ }
+ break;
+
+ case LFUN_MATH_MACRO_REMOVE_GREEDY_PARAM:
+ if (numargs_ > 0) {
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ removeParameter(cur, cur, numargs_ - 1, true);
+ }
+ break;
+
+ case LFUN_MATH_MACRO_MAKE_OPTIONAL:
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ makeOptional(cur, cur);
+ break;
+
+ case LFUN_MATH_MACRO_MAKE_NONOPTIONAL:
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ makeNonOptional(cur, cur);
+ break;
+
+ case LFUN_MATH_MACRO_ADD_OPTIONAL_PARAM:
+ if (numargs_ < 9) {
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ insertParameter(cur, cur, optionals_);
+ makeOptional(cur, cur);
+ }
+ break;
+
+ case LFUN_MATH_MACRO_REMOVE_OPTIONAL_PARAM:
+ if (optionals_ > 0) {
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ removeParameter(cur, cur, optionals_ - 1);
+ } break;
+
+ case LFUN_MATH_MACRO_ADD_GREEDY_OPTIONAL_PARAM:
+ if (numargs_ == optionals_) {
+ commitEditChanges(cur, cur);
+ cur.recordUndoFullDocument();
+ insertParameter(cur, cur, 0, true);
+ makeOptional(cur, cur);
+ }
+ break;
+
+ default:
+ InsetMathNest::doDispatch(cur, cmd);
+ break;
+ }
+}
+
+
+bool MathMacroTemplate::getStatus(Cursor & /*cur*/, FuncRequest const & cmd,
+ FuncStatus & flag) const
+{
+ bool ret = true;
+ string const arg = to_utf8(cmd.argument());
+ switch (cmd.action()) {
+ case LFUN_MATH_MACRO_ADD_PARAM: {
+ int num = numargs_ + 1;
+ if (arg.size() != 0)
+ num = convert<int>(arg);
+ bool on = (num >= optionals_
+ && numargs_ < 9 && num <= numargs_ + 1);
+ flag.setEnabled(on);
+ break;
+ }
+
+ case LFUN_MATH_MACRO_APPEND_GREEDY_PARAM:
+ flag.setEnabled(numargs_ < 9);
+ break;
+
+ case LFUN_MATH_MACRO_REMOVE_GREEDY_PARAM:
+ case LFUN_MATH_MACRO_REMOVE_PARAM: {
+ int num = numargs_;
+ if (arg.size() != 0)
+ num = convert<int>(arg);
+ flag.setEnabled(num >= 1 && num <= numargs_);
+ break;
+ }
+
+ case LFUN_MATH_MACRO_MAKE_OPTIONAL:
+ flag.setEnabled(numargs_ > 0
+ && optionals_ < numargs_
+ && type_ != MacroTypeDef);
+ break;
+
+ case LFUN_MATH_MACRO_MAKE_NONOPTIONAL:
+ flag.setEnabled(optionals_ > 0
+ && type_ != MacroTypeDef);
+ break;
+
+ case LFUN_MATH_MACRO_ADD_OPTIONAL_PARAM:
+ flag.setEnabled(numargs_ < 9);
+ break;
+
+ case LFUN_MATH_MACRO_REMOVE_OPTIONAL_PARAM:
+ flag.setEnabled(optionals_ > 0);
+ break;
+
+ case LFUN_MATH_MACRO_ADD_GREEDY_OPTIONAL_PARAM:
+ flag.setEnabled(numargs_ == 0
+ && type_ != MacroTypeDef);
+ break;
+
+ case LFUN_IN_MATHMACROTEMPLATE:
+ flag.setEnabled(true);
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+}
+
+
+void MathMacroTemplate::read(Lexer & lex)
+{
+ MathData ar(buffer_);
+ mathed_parse_cell(ar, lex.getStream(), Parse::TRACKMACRO);