* the automatic arity changing proposed by Uwe: you go into a macro and type \#9. The arity is visually adapted right away. The real change though takes place when you leave the macro with the cursor.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23350 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Stefan Schimanski 2008-02-29 10:02:25 +00:00
parent 8c4b08920e
commit e59560a1fa
4 changed files with 203 additions and 29 deletions

View File

@ -139,6 +139,8 @@ ColorSet::ColorSet()
{ Color_mathmacrolabel, N_("Math macro label"), "mathmacrolabel", "#a19992", "mathmacrolabel" }, { Color_mathmacrolabel, N_("Math macro label"), "mathmacrolabel", "#a19992", "mathmacrolabel" },
{ Color_mathmacroframe, N_("Math macro frame"), "mathmacroframe", "#ede2d8", "mathmacroframe" }, { Color_mathmacroframe, N_("Math macro frame"), "mathmacroframe", "#ede2d8", "mathmacroframe" },
{ Color_mathmacroblend, N_("Math macro blended out"), "mathmacroblend", "black", "mathmacroblend" }, { Color_mathmacroblend, N_("Math macro blended out"), "mathmacroblend", "black", "mathmacroblend" },
{ Color_mathmacrooldarg, N_("Math macro old parameter"), "mathmacrooldarg", "grey80", "mathmacrooldarg" },
{ Color_mathmacronewarg, N_("Math macro new parameter"), "mathmacronewarg", "grey20", "mathmacronewarg" },
{ Color_captionframe, N_("caption frame"), "captionframe", "DarkRed", "captionframe" }, { Color_captionframe, N_("caption frame"), "captionframe", "DarkRed", "captionframe" },
{ Color_collapsable, N_("collapsable inset text"), "collapsable", "DarkRed", "collapsable" }, { Color_collapsable, N_("collapsable inset text"), "collapsable", "DarkRed", "collapsable" },
{ Color_collapsableframe, N_("collapsable inset frame"), "collapsableframe", "IndianRed", "collapsableframe" }, { Color_collapsableframe, N_("collapsable inset frame"), "collapsableframe", "IndianRed", "collapsableframe" },

View File

@ -112,6 +112,10 @@ enum ColorCode
Color_mathmacroframe, Color_mathmacroframe,
/// Macro math blended color /// Macro math blended color
Color_mathmacroblend, Color_mathmacroblend,
/// Macro template color for old parameters
Color_mathmacrooldarg,
/// Macro template color for new parameters
Color_mathmacronewarg,
/// Math inset frame color under focus /// Math inset frame color under focus
Color_mathframe, Color_mathframe,
/// Math inset frame color not under focus /// Math inset frame color not under focus

View File

@ -78,7 +78,7 @@ protected:
InsetLabelBox::InsetLabelBox(MathAtom const & atom, docstring label, InsetLabelBox::InsetLabelBox(MathAtom const & atom, docstring label,
MathMacroTemplate const & parent, bool frame) MathMacroTemplate const & parent, bool frame)
: InsetMathNest(1), parent_(parent), label_(label), frame_(frame) : InsetMathNest(1), parent_(parent), label_(label), frame_(frame)
{ {
cell(0).insert(0, atom); cell(0).insert(0, atom);
} }
@ -86,7 +86,7 @@ InsetLabelBox::InsetLabelBox(MathAtom const & atom, docstring label,
InsetLabelBox::InsetLabelBox(docstring label, InsetLabelBox::InsetLabelBox(docstring label,
MathMacroTemplate const & parent, bool frame) MathMacroTemplate const & parent, bool frame)
: InsetMathNest(1), parent_(parent), label_(label), frame_(frame) : InsetMathNest(1), parent_(parent), label_(label), frame_(frame)
{ {
} }
@ -273,6 +273,61 @@ void InsetMathWrapper::draw(PainterInfo & pi, int x, int y) const
} }
///////////////////////////////////////////////////////////////////////
class InsetColoredCell : public InsetMathNest {
public:
///
InsetColoredCell(ColorCode min, ColorCode max);
///
InsetColoredCell(ColorCode min, ColorCode max, MathAtom const & atom);
///
void draw(PainterInfo &, int x, int y) const;
///
void metrics(MetricsInfo & mi, Dimension & dim) const;
protected:
///
Inset * clone() const;
///
ColorCode min_;
///
ColorCode max_;
};
InsetColoredCell::InsetColoredCell(ColorCode min, ColorCode max)
: InsetMathNest(1), min_(min), max_(max)
{
}
InsetColoredCell::InsetColoredCell(ColorCode min, ColorCode max, MathAtom const & atom)
: InsetMathNest(1), min_(min), max_(max)
{
cell(0).insert(0, atom);
}
Inset * InsetColoredCell::clone() const
{
return new InsetColoredCell(*this);
}
void InsetColoredCell::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
}
void InsetColoredCell::draw(PainterInfo & pi, int x, int y) const
{
pi.pain.enterMonochromeMode(min_, max_);
cell(0).draw(pi, x, y);
pi.pain.leaveMonochromeMode();
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
class InsetNameWrapper : public InsetMathWrapper { class InsetNameWrapper : public InsetMathWrapper {
@ -334,7 +389,7 @@ void InsetNameWrapper::draw(PainterInfo & pi, int x, int y) const
MathMacroTemplate::MathMacroTemplate() MathMacroTemplate::MathMacroTemplate()
: InsetMathNest(3), numargs_(0), optionals_(0), : InsetMathNest(3), numargs_(0), argsInLook_(0), optionals_(0),
type_(MacroTypeNewcommand), lookOutdated_(true) type_(MacroTypeNewcommand), lookOutdated_(true)
{ {
initMath(); initMath();
@ -345,7 +400,7 @@ MathMacroTemplate::MathMacroTemplate(docstring const & name, int numargs,
int optionals, MacroType type, int optionals, MacroType type,
vector<MathData> const & optionalValues, vector<MathData> const & optionalValues,
MathData const & def, MathData const & display) MathData const & def, MathData const & display)
: InsetMathNest(optionals + 3), numargs_(numargs), : InsetMathNest(optionals + 3), numargs_(numargs), argsInLook_(0),
optionals_(optionals), optionalValues_(optionalValues), optionals_(optionals), optionalValues_(optionalValues),
type_(type), lookOutdated_(true) type_(type), lookOutdated_(true)
{ {
@ -410,15 +465,16 @@ void MathMacroTemplate::updateToContext(MacroContext const & mc) const
} }
void MathMacroTemplate::updateLook() const void MathMacroTemplate::updateLook(bool editing) const
{ {
lookOutdated_ = true; lookOutdated_ = true;
} }
void MathMacroTemplate::createLook() const void MathMacroTemplate::createLook(int args) const
{ {
look_.clear(); look_.clear();
argsInLook_ = args;
// \foo // \foo
look_.push_back(MathAtom(new InsetLabelBox(_("Name"), *this, false))); look_.push_back(MathAtom(new InsetLabelBox(_("Name"), *this, false)));
@ -429,12 +485,20 @@ void MathMacroTemplate::createLook() const
int i = 0; int i = 0;
if (optionals_ > 0) { if (optionals_ > 0) {
look_.push_back(MathAtom(new InsetLabelBox(_("optional"), *this, false))); look_.push_back(MathAtom(new InsetLabelBox(_("optional"), *this, false)));
MathData & optData = look_[look_.size() - 1].nucleus()->cell(0);
for (; i < optionals_; ++i) { for (; i < optionals_; ++i) {
optData.push_back(MathAtom(new InsetMathChar('['))); MathData * optData = &look_[look_.size() - 1].nucleus()->cell(0);
optData.push_back(MathAtom(new InsetMathWrapper(&cell(1 + i))));
optData.push_back(MathAtom(new InsetMathChar(']'))); // color it red, if it is to be remove when the cursor leaves
if (optionals_ > argsInLook_) {
optData->push_back(MathAtom(
new InsetColoredCell(Color_mathbg, Color_mathmacrooldarg)));
optData = &(*optData)[0].nucleus()->cell(0);
}
optData->push_back(MathAtom(new InsetMathChar('[')));
optData->push_back(MathAtom(new InsetMathWrapper(&cell(1 + i))));
optData->push_back(MathAtom(new InsetMathChar(']')));
} }
} }
@ -442,8 +506,20 @@ void MathMacroTemplate::createLook() const
for (; i < numargs_; ++i) { for (; i < numargs_; ++i) {
MathData arg; MathData arg;
arg.push_back(MathAtom(new MathMacroArgument(i + 1))); arg.push_back(MathAtom(new MathMacroArgument(i + 1)));
if (i >= argsInLook_) {
look_.push_back(MathAtom(new InsetColoredCell(
Color_mathbg, Color_mathmacrooldarg,
MathAtom(new InsetMathBrace(arg)))));
} else
look_.push_back(MathAtom(new InsetMathBrace(arg))); look_.push_back(MathAtom(new InsetMathBrace(arg)));
} }
for (; i < argsInLook_; ++i) {
MathData arg;
arg.push_back(MathAtom(new MathMacroArgument(i + 1)));
look_.push_back(MathAtom(new InsetColoredCell(
Color_mathbg, Color_mathmacronewarg,
MathAtom(new InsetMathBrace(arg)))));
}
// := // :=
look_.push_back(MathAtom(new InsetMathChar(':'))); look_.push_back(MathAtom(new InsetMathChar(':')));
@ -476,9 +552,10 @@ void MathMacroTemplate::metrics(MetricsInfo & mi, Dimension & dim) const
} }
// update look? // update look?
if (lookOutdated_) { int argsInDef = maxArgumentInDefinition();
if (lookOutdated_ || argsInDef != argsInLook_) {
lookOutdated_ = false; lookOutdated_ = false;
createLook(); createLook(argsInDef);
} }
/// metrics for inset contents /// metrics for inset contents
@ -532,7 +609,7 @@ void MathMacroTemplate::draw(PainterInfo & pi, int x, int y) const
void MathMacroTemplate::edit(Cursor & cur, bool front, EntryDirection entry_from) void MathMacroTemplate::edit(Cursor & cur, bool front, EntryDirection entry_from)
{ {
updateLook(); updateLook(true);
cur.updateFlags(Update::Force); cur.updateFlags(Update::Force);
InsetMathNest::edit(cur, front, entry_from); InsetMathNest::edit(cur, front, entry_from);
} }
@ -540,6 +617,7 @@ void MathMacroTemplate::edit(Cursor & cur, bool front, EntryDirection entry_from
bool MathMacroTemplate::notifyCursorLeaves(Cursor const & old, Cursor & cur) bool MathMacroTemplate::notifyCursorLeaves(Cursor const & old, Cursor & cur)
{ {
commitEditChanges(cur);
updateLook(); updateLook();
cur.updateFlags(Update::Force); cur.updateFlags(Update::Force);
return InsetMathNest::notifyCursorLeaves(old, cur); return InsetMathNest::notifyCursorLeaves(old, cur);
@ -582,6 +660,74 @@ void MathMacroTemplate::shiftArguments(size_t from, int by) {
} }
int MathMacroTemplate::maxArgumentInDefinition() const
{
int maxArg = 0;
MathMacroTemplate * nonConst = const_cast<MathMacroTemplate *>(this);
DocIterator it = doc_iterator_begin(*nonConst);
it.idx() = defIdx();
for (; it; it.forwardChar()) {
if (!it.nextInset())
continue;
if (it.nextInset()->lyxCode() != MATHMACROARG_CODE)
continue;
MathMacroArgument * arg = static_cast<MathMacroArgument*>(it.nextInset());
maxArg = std::max(int(arg->number()), maxArg);
}
return maxArg;
}
void MathMacroTemplate::insertMissingArguments(int maxArg)
{
bool found[9] = { false, false, false, false, false, false, false, false, false };
idx_type idx = cell(displayIdx()).empty() ? defIdx() : displayIdx();
// search for #n macros arguments
DocIterator it = doc_iterator_begin(*this);
it.idx() = idx;
for (; it && it[0].idx() == idx; it.forwardChar()) {
if (!it.nextInset())
continue;
if (it.nextInset()->lyxCode() != MATHMACROARG_CODE)
continue;
MathMacroArgument * arg = static_cast<MathMacroArgument*>(it.nextInset());
found[arg->number() - 1] = true;
}
// add missing ones
for (int i = 0; i < maxArg; ++i) {
if (found[i])
continue;
cell(idx).push_back(MathAtom(new MathMacroArgument(i + 1)));
}
}
void MathMacroTemplate::changeArity(Cursor & cur, int newNumArg)
{
// remove parameter which do not appear anymore in the definition
for (int i = numargs_; i > newNumArg; --i)
removeParameter(cur, numargs_ - 1, false);
// add missing parameter
for (int i = numargs_; i < newNumArg; ++i)
insertParameter(cur, numargs_, false, false);
}
void MathMacroTemplate::commitEditChanges(Cursor & cur)
{
int argsInDef = maxArgumentInDefinition();
if (argsInDef != numargs_) {
cur.recordUndoFullDocument();
changeArity(cur, argsInDef);
}
insertMissingArguments(argsInDef);
}
// FIXME: factorize those functions here with a functional style, maybe using Boost's function // FIXME: factorize those functions here with a functional style, maybe using Boost's function
// objects? // objects?
@ -673,16 +819,19 @@ void fixMacroInstancesFunctional(Cursor const & from,
} }
void MathMacroTemplate::insertParameter(Cursor & cur, int pos, bool greedy) void MathMacroTemplate::insertParameter(Cursor & cur, int pos, bool greedy, bool addarg)
{ {
if (pos <= numargs_ && pos >= optionals_ && numargs_ < 9) { if (pos <= numargs_ && pos >= optionals_ && numargs_ < 9) {
++numargs_; ++numargs_;
shiftArguments(pos, 1);
// append example #n // append example #n
if (addarg) {
shiftArguments(pos, 1);
cell(defIdx()).push_back(MathAtom(new MathMacroArgument(pos + 1))); cell(defIdx()).push_back(MathAtom(new MathMacroArgument(pos + 1)));
if (!cell(displayIdx()).empty()) if (!cell(displayIdx()).empty())
cell(displayIdx()).push_back(MathAtom(new MathMacroArgument(pos + 1))); cell(displayIdx()).push_back(MathAtom(new MathMacroArgument(pos + 1)));
}
if (!greedy) { if (!greedy) {
Cursor dit = cur; Cursor dit = cur;
@ -765,7 +914,7 @@ void MathMacroTemplate::makeNonOptional(Cursor & cur) {
if (numargs_ > 0 && optionals_ > 0) { if (numargs_ > 0 && optionals_ > 0) {
--optionals_; --optionals_;
// store default value for later if the use changes his mind // store default value for later if the user changes his mind
optionalValues_[optionals_] = cell(optIdx(optionals_)); optionalValues_[optionals_] = cell(optIdx(optionals_));
cells_.erase(cells_.begin() + optIdx(optionals_)); cells_.erase(cells_.begin() + optIdx(optionals_));
@ -800,6 +949,7 @@ void MathMacroTemplate::doDispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_MATH_MACRO_ADD_PARAM: case LFUN_MATH_MACRO_ADD_PARAM:
if (numargs_ < 9) { if (numargs_ < 9) {
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
size_t pos = numargs_; size_t pos = numargs_;
if (arg.size() != 0) if (arg.size() != 0)
@ -811,6 +961,7 @@ void MathMacroTemplate::doDispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_MATH_MACRO_REMOVE_PARAM: case LFUN_MATH_MACRO_REMOVE_PARAM:
if (numargs_ > 0) { if (numargs_ > 0) {
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
size_t pos = numargs_ - 1; size_t pos = numargs_ - 1;
if (arg.size() != 0) if (arg.size() != 0)
@ -821,6 +972,7 @@ void MathMacroTemplate::doDispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_MATH_MACRO_APPEND_GREEDY_PARAM: case LFUN_MATH_MACRO_APPEND_GREEDY_PARAM:
if (numargs_ < 9) { if (numargs_ < 9) {
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
insertParameter(cur, numargs_, true); insertParameter(cur, numargs_, true);
} }
@ -828,23 +980,27 @@ void MathMacroTemplate::doDispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_MATH_MACRO_REMOVE_GREEDY_PARAM: case LFUN_MATH_MACRO_REMOVE_GREEDY_PARAM:
if (numargs_ > 0) { if (numargs_ > 0) {
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
removeParameter(cur, numargs_ - 1, true); removeParameter(cur, numargs_ - 1, true);
} }
break; break;
case LFUN_MATH_MACRO_MAKE_OPTIONAL: case LFUN_MATH_MACRO_MAKE_OPTIONAL:
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
makeOptional(cur); makeOptional(cur);
break; break;
case LFUN_MATH_MACRO_MAKE_NONOPTIONAL: case LFUN_MATH_MACRO_MAKE_NONOPTIONAL:
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
makeNonOptional(cur); makeNonOptional(cur);
break; break;
case LFUN_MATH_MACRO_ADD_OPTIONAL_PARAM: case LFUN_MATH_MACRO_ADD_OPTIONAL_PARAM:
if (numargs_ < 9) { if (numargs_ < 9) {
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
insertParameter(cur, optionals_); insertParameter(cur, optionals_);
makeOptional(cur); makeOptional(cur);
@ -853,12 +1009,14 @@ void MathMacroTemplate::doDispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_MATH_MACRO_REMOVE_OPTIONAL_PARAM: case LFUN_MATH_MACRO_REMOVE_OPTIONAL_PARAM:
if (optionals_ > 0) { if (optionals_ > 0) {
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
removeParameter(cur, optionals_ - 1); removeParameter(cur, optionals_ - 1);
} break; } break;
case LFUN_MATH_MACRO_ADD_GREEDY_OPTIONAL_PARAM: case LFUN_MATH_MACRO_ADD_GREEDY_OPTIONAL_PARAM:
if (numargs_ == optionals_) { if (numargs_ == optionals_) {
commitEditChanges(cur);
cur.recordUndoFullDocument(); cur.recordUndoFullDocument();
insertParameter(cur, 0, true); insertParameter(cur, 0, true);
makeOptional(cur); makeOptional(cur);

View File

@ -118,9 +118,9 @@ private:
/// shift every #n with from<=n, i.e. #n -> #(n-by) /// shift every #n with from<=n, i.e. #n -> #(n-by)
void shiftArguments(size_t from, int by); void shiftArguments(size_t from, int by);
/// ///
void insertParameter(Cursor & cur, int pos, bool greedy = false); void insertParameter(Cursor & cur, int pos, bool greedy = false, bool addarg = true);
/// ///
void removeParameter(Cursor & cur, int pos, bool greedy = false ); void removeParameter(Cursor & cur, int pos, bool greedy = false);
/// ///
void makeOptional(Cursor & cur); void makeOptional(Cursor & cur);
/// ///
@ -132,12 +132,22 @@ private:
/// ///
idx_type displayIdx() const { return optionals_ + 2; } idx_type displayIdx() const { return optionals_ + 2; }
/// ///
void updateLook() const; void updateLook(bool editing = false) const;
/// The representation of the macro tempalte, with some holes to edit /// look through the macro for #n arguments
int maxArgumentInDefinition() const;
/// add missing #n arguments up to \c maxArg
void insertMissingArguments(int maxArg);
/// change the arity
void changeArity(Cursor & cur, int newNumArg);
/// find arguments in definition and adapt the arity accordingly
void commitEditChanges(Cursor & cur);
/// The representation of the macro template, with some holes to edit
mutable MathData look_; mutable MathData look_;
/// ///
mutable int numargs_; mutable int numargs_;
/// ///
mutable int argsInLook_;
///
int optionals_; int optionals_;
/// keeps the old optional default value when an /// keeps the old optional default value when an
/// optional argument is disabled /// optional argument is disabled
@ -148,7 +158,7 @@ private:
/// defined before already? /// defined before already?
mutable bool redefinition_; mutable bool redefinition_;
/// ///
void createLook() const; void createLook(int args) const;
/// ///
mutable bool lookOutdated_; mutable bool lookOutdated_;
/// true if in pre-calculations of metrics to get height of boxes /// true if in pre-calculations of metrics to get height of boxes