mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-23 13:31:49 +00:00
* fixed bug #4357 when pasting a macro with script index
* fixed some other unreported bug when the cursor is not inside or near the macro during fold/unfold * fixed the bug that the cursor jumped into the first parameter when pasting a macro. This should only happen when the macro was entered interactively git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21611 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
3ab1031f97
commit
240e59ae0d
@ -950,7 +950,7 @@ bool Cursor::macroModeClose()
|
|||||||
MathMacro * atomAsMacro = atom.nucleus()->asMacro();
|
MathMacro * atomAsMacro = atom.nucleus()->asMacro();
|
||||||
if (atomAsMacro) {
|
if (atomAsMacro) {
|
||||||
// make non-greedy, i.e. don't eat parameters from the right
|
// make non-greedy, i.e. don't eat parameters from the right
|
||||||
atomAsMacro->setDisplayMode(MathMacro::DISPLAY_NONGREEDY_INIT);
|
atomAsMacro->setDisplayMode(MathMacro::DISPLAY_INTERACTIVE_INIT);
|
||||||
}
|
}
|
||||||
plainInsert(atom);
|
plainInsert(atom);
|
||||||
return true;
|
return true;
|
||||||
|
@ -383,20 +383,26 @@ void MathData::updateMacros(MetricsInfo & mi)
|
|||||||
// is it a virgin macro which was never attached to parameters?
|
// is it a virgin macro which was never attached to parameters?
|
||||||
bool fromInitToNormalMode
|
bool fromInitToNormalMode
|
||||||
= (oldDisplayMode == MathMacro::DISPLAY_INIT
|
= (oldDisplayMode == MathMacro::DISPLAY_INIT
|
||||||
|| oldDisplayMode == MathMacro::DISPLAY_NONGREEDY_INIT)
|
|| oldDisplayMode == MathMacro::DISPLAY_INTERACTIVE_INIT)
|
||||||
&& newDisplayMode == MathMacro::DISPLAY_NORMAL;
|
&& newDisplayMode == MathMacro::DISPLAY_NORMAL;
|
||||||
bool greedy = (oldDisplayMode != MathMacro::DISPLAY_NONGREEDY_INIT);
|
|
||||||
|
// if the macro was entered interactively (i.e. not by paste or during
|
||||||
|
// loading), it should not be greedy, but the cursor should
|
||||||
|
// automatically jump into the macro when behind
|
||||||
|
bool interactive = (oldDisplayMode == MathMacro::DISPLAY_INTERACTIVE_INIT);
|
||||||
|
|
||||||
// attach parameters
|
// attach parameters
|
||||||
attachMacroParameters(cur, i, macroNumArgs, macroOptionals,
|
attachMacroParameters(cur, i, macroNumArgs, macroOptionals,
|
||||||
fromInitToNormalMode, greedy);
|
fromInitToNormalMode, interactive);
|
||||||
|
|
||||||
// FIXME: proper anchor handling, this removes the selection
|
// FIXME: proper anchor handling, this removes the selection
|
||||||
cur.updateInsets(&cur.bottom().inset());
|
cur.updateInsets(&cur.bottom().inset());
|
||||||
cur.clearSelection();
|
cur.clearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
// give macro the chance to adapt to new situation
|
// Give macro the chance to adapt to new situation.
|
||||||
|
// The macroInset could be invalid now because it was put into a script
|
||||||
|
// inset and therefore "deep" copied. So get it again from the MathData.
|
||||||
InsetMath * inset = operator[](i).nucleus();
|
InsetMath * inset = operator[](i).nucleus();
|
||||||
if (inset->asScriptInset())
|
if (inset->asScriptInset())
|
||||||
inset = inset->asScriptInset()->nuc()[0].nucleus();
|
inset = inset->asScriptInset()->nuc()[0].nucleus();
|
||||||
@ -477,6 +483,10 @@ void MathData::detachMacroParameters(Cursor & cur, const size_type macroPos)
|
|||||||
insert(p, optarg);
|
insert(p, optarg);
|
||||||
p += optarg.size();
|
p += optarg.size();
|
||||||
|
|
||||||
|
// cursor in macro?
|
||||||
|
if (curMacroSlice == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
// cursor in optional argument of macro?
|
// cursor in optional argument of macro?
|
||||||
if (curMacroIdx == j) {
|
if (curMacroIdx == j) {
|
||||||
if (brace) {
|
if (brace) {
|
||||||
@ -491,13 +501,17 @@ void MathData::detachMacroParameters(Cursor & cur, const size_type macroPos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// put them back into the MathData
|
// put them back into the MathData
|
||||||
for (; j < detachedArgs.size(); ++j) {
|
for (; j < detachedArgs.size(); ++j, ++p) {
|
||||||
MathData const & arg = detachedArgs[j];
|
MathData const & arg = detachedArgs[j];
|
||||||
if (arg.size() == 1 && !arg[0]->asScriptInset()) // && arg[0]->asCharInset())
|
if (arg.size() == 1 && !arg[0]->asScriptInset()) // && arg[0]->asCharInset())
|
||||||
insert(p, arg[0]);
|
insert(p, arg[0]);
|
||||||
else
|
else
|
||||||
insert(p, MathAtom(new InsetMathBrace(arg)));
|
insert(p, MathAtom(new InsetMathBrace(arg)));
|
||||||
|
|
||||||
|
// cursor in macro?
|
||||||
|
if (curMacroSlice == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
// cursor in j-th argument of macro?
|
// cursor in j-th argument of macro?
|
||||||
if (curMacroIdx == j) {
|
if (curMacroIdx == j) {
|
||||||
if (operator[](p).nucleus()->asBraceInset()) {
|
if (operator[](p).nucleus()->asBraceInset()) {
|
||||||
@ -510,8 +524,6 @@ void MathData::detachMacroParameters(Cursor & cur, const size_type macroPos)
|
|||||||
}
|
}
|
||||||
} else if (cur[curMacroSlice - 1].pos() >= int(p))
|
} else if (cur[curMacroSlice - 1].pos() >= int(p))
|
||||||
++cur[curMacroSlice - 1].pos();
|
++cur[curMacroSlice - 1].pos();
|
||||||
|
|
||||||
++p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: proper anchor handling, this removes the selection
|
// FIXME: proper anchor handling, this removes the selection
|
||||||
@ -523,29 +535,28 @@ void MathData::detachMacroParameters(Cursor & cur, const size_type macroPos)
|
|||||||
void MathData::attachMacroParameters(Cursor & cur,
|
void MathData::attachMacroParameters(Cursor & cur,
|
||||||
const size_type macroPos, const size_type macroNumArgs,
|
const size_type macroPos, const size_type macroNumArgs,
|
||||||
const int macroOptionals, const bool fromInitToNormalMode,
|
const int macroOptionals, const bool fromInitToNormalMode,
|
||||||
const bool greedy)
|
const bool interactiveInit)
|
||||||
{
|
{
|
||||||
MathMacro * macroInset = operator[](macroPos).nucleus()->asMacro();
|
MathMacro * macroInset = operator[](macroPos).nucleus()->asMacro();
|
||||||
|
|
||||||
// start at atom behind the macro again, maybe with some new arguments from above
|
// start at atom behind the macro again, maybe with some new arguments
|
||||||
// to add them back into the macro inset
|
// from the detach phase above, to add them back into the macro inset
|
||||||
size_t p = macroPos + 1;
|
size_t p = macroPos + 1;
|
||||||
std::vector<MathData> detachedArgs;
|
std::vector<MathData> detachedArgs;
|
||||||
MathAtom scriptToPutAround;
|
MathAtom scriptToPutAround;
|
||||||
|
|
||||||
// find cursor slice again
|
// find cursor slice again of this MathData
|
||||||
int thisSlice = cur.find(*this);
|
int thisSlice = cur.find(*this);
|
||||||
int thisPos = -1;
|
int thisPos = -1;
|
||||||
if (thisSlice != -1)
|
if (thisSlice != -1)
|
||||||
thisPos = cur[thisSlice].pos();
|
thisPos = cur[thisSlice].pos();
|
||||||
|
|
||||||
// find arguments behind the macro
|
// find arguments behind the macro
|
||||||
if (greedy) {
|
if (!interactiveInit) {
|
||||||
collectOptionalParameters(cur, macroOptionals, detachedArgs, p,
|
collectOptionalParameters(cur, macroOptionals, detachedArgs, p,
|
||||||
macroPos, thisPos, thisSlice);
|
macroPos, thisPos, thisSlice);
|
||||||
collectParameters(cur, macroNumArgs, detachedArgs, p,
|
collectParameters(cur, macroNumArgs, detachedArgs, p,
|
||||||
scriptToPutAround,
|
scriptToPutAround, macroPos, thisPos, thisSlice);
|
||||||
macroPos, thisPos, thisSlice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// attach arguments back to macro inset
|
// attach arguments back to macro inset
|
||||||
@ -558,15 +569,20 @@ void MathData::attachMacroParameters(Cursor & cur,
|
|||||||
= operator[](macroPos);
|
= operator[](macroPos);
|
||||||
operator[](macroPos) = scriptToPutAround;
|
operator[](macroPos) = scriptToPutAround;
|
||||||
|
|
||||||
|
// go into the script inset nucleus
|
||||||
if (thisPos == int(macroPos))
|
if (thisPos == int(macroPos))
|
||||||
cur.append(0, 0);
|
cur.append(0, 0);
|
||||||
|
|
||||||
|
// get pointer to "deep" copied macro inset
|
||||||
|
InsetMathScript * scriptInset
|
||||||
|
= operator[](macroPos).nucleus()->asScriptInset();
|
||||||
|
macroInset = scriptInset->nuc()[0].nucleus()->asMacro();
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove them from the MathData
|
// remove them from the MathData
|
||||||
erase(begin() + macroPos + 1, begin() + p);
|
erase(begin() + macroPos + 1, begin() + p);
|
||||||
|
|
||||||
|
// cursor outside this MathData?
|
||||||
// no need to update the cursor?
|
|
||||||
if (thisSlice == -1)
|
if (thisSlice == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -574,8 +590,10 @@ void MathData::attachMacroParameters(Cursor & cur,
|
|||||||
if (thisPos >= int(p))
|
if (thisPos >= int(p))
|
||||||
cur[thisSlice].pos() -= p - (macroPos + 1);
|
cur[thisSlice].pos() -= p - (macroPos + 1);
|
||||||
|
|
||||||
// was the macro inset just inserted and was now folded?
|
// was the macro inset just inserted interactively and was now folded
|
||||||
|
// and the cursor is just behind?
|
||||||
if (cur[thisSlice].pos() == int(macroPos + 1)
|
if (cur[thisSlice].pos() == int(macroPos + 1)
|
||||||
|
&& interactiveInit
|
||||||
&& fromInitToNormalMode
|
&& fromInitToNormalMode
|
||||||
&& macroInset->arity() > 0
|
&& macroInset->arity() > 0
|
||||||
&& thisSlice + 1 == int(cur.depth())) {
|
&& thisSlice + 1 == int(cur.depth())) {
|
||||||
|
@ -173,7 +173,7 @@ private:
|
|||||||
///
|
///
|
||||||
void attachMacroParameters(Cursor & cur, const size_type macroPos,
|
void attachMacroParameters(Cursor & cur, const size_type macroPos,
|
||||||
const size_type macroNumArgs, const int macroOptionals,
|
const size_type macroNumArgs, const int macroOptionals,
|
||||||
const bool fromInitToNormalMode, const bool greedy);
|
const bool fromInitToNormalMode, const bool interactiveInit);
|
||||||
///
|
///
|
||||||
void collectOptionalParameters(Cursor & cur,
|
void collectOptionalParameters(Cursor & cur,
|
||||||
const size_type numOptionalParams, std::vector<MathData> & params,
|
const size_type numOptionalParams, std::vector<MathData> & params,
|
||||||
|
@ -165,7 +165,7 @@ bool MathMacro::editMode(Cursor const & cur) const {
|
|||||||
void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||||
{
|
{
|
||||||
// calculate new metrics according to display mode
|
// calculate new metrics according to display mode
|
||||||
if (displayMode_ == DISPLAY_INIT || displayMode_ == DISPLAY_NONGREEDY_INIT) {
|
if (displayMode_ == DISPLAY_INIT || displayMode_ == DISPLAY_INTERACTIVE_INIT) {
|
||||||
mathed_string_dim(mi.base.font, from_ascii("\\") + name(), dim);
|
mathed_string_dim(mi.base.font, from_ascii("\\") + name(), dim);
|
||||||
} else if (displayMode_ == DISPLAY_UNFOLDED) {
|
} else if (displayMode_ == DISPLAY_UNFOLDED) {
|
||||||
cell(0).metrics(mi, dim);
|
cell(0).metrics(mi, dim);
|
||||||
@ -280,7 +280,7 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
|
|||||||
int expx = x;
|
int expx = x;
|
||||||
int expy = y;
|
int expy = y;
|
||||||
|
|
||||||
if (displayMode_ == DISPLAY_INIT || displayMode_ == DISPLAY_NONGREEDY_INIT) {
|
if (displayMode_ == DISPLAY_INIT || displayMode_ == DISPLAY_INTERACTIVE_INIT) {
|
||||||
PainterInfo pi2(pi.base.bv, pi.pain);
|
PainterInfo pi2(pi.base.bv, pi.pain);
|
||||||
pi2.base.font.setColor(macro_ ? Color_latex : Color_error);
|
pi2.base.font.setColor(macro_ ? Color_latex : Color_error);
|
||||||
//pi2.base.style = LM_ST_TEXT;
|
//pi2.base.style = LM_ST_TEXT;
|
||||||
|
@ -87,7 +87,7 @@ public:
|
|||||||
|
|
||||||
enum DisplayMode {
|
enum DisplayMode {
|
||||||
DISPLAY_INIT,
|
DISPLAY_INIT,
|
||||||
DISPLAY_NONGREEDY_INIT,
|
DISPLAY_INTERACTIVE_INIT,
|
||||||
DISPLAY_UNFOLDED,
|
DISPLAY_UNFOLDED,
|
||||||
DISPLAY_NORMAL,
|
DISPLAY_NORMAL,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user