lyx_mirror/src/mathed/InsetMathScript.cpp

806 lines
17 KiB
C++
Raw Normal View History

/**
* \file InsetMathScript.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author André Pönitz
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "InsetMathScript.h"
#include "InsetMathBrace.h"
#include "InsetMathSymbol.h"
#include "MathData.h"
#include "MathStream.h"
#include "MathSupport.h"
#include "BufferView.h"
#include "Cursor.h"
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LaTeXFeatures.h"
#include "MetricsInfo.h"
#include "support/debug.h"
#include "support/gettext.h"
#include "support/lassert.h"
using namespace std;
namespace lyx {
InsetMathScript::InsetMathScript(Buffer * buf)
: InsetMathNest(buf, 1), cell_1_is_up_(false), limits_(0)
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
{}
InsetMathScript::InsetMathScript(Buffer * buf, bool up)
: InsetMathNest(buf, 2), cell_1_is_up_(up), limits_(0)
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
{}
InsetMathScript::InsetMathScript(Buffer * buf, MathAtom const & at, bool up)
: InsetMathNest(buf, 2), cell_1_is_up_(up), limits_(0)
{
LATTEST(nargs() >= 1);
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
cell(0).push_back(at);
}
Inset * InsetMathScript::clone() const
{
return new InsetMathScript(*this);
}
InsetMathScript const * InsetMathScript::asScriptInset() const
{
return this;
}
InsetMathScript * InsetMathScript::asScriptInset()
{
return this;
}
bool InsetMathScript::idxFirst(Cursor & cur) const
{
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
cur.idx() = 0;
cur.pos() = 0;
return true;
}
bool InsetMathScript::idxLast(Cursor & cur) const
{
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
cur.idx() = 0;
cur.pos() = nuc().size();
return true;
}
MathData const & InsetMathScript::down() const
{
if (nargs() == 3)
return cell(2);
LBUFERR(nargs() > 1);
return cell(1);
}
MathData & InsetMathScript::down()
{
if (nargs() == 3)
return cell(2);
LBUFERR(nargs() > 1);
return cell(1);
}
MathData const & InsetMathScript::up() const
{
LBUFERR(nargs() > 1);
return cell(1);
}
MathData & InsetMathScript::up()
{
LBUFERR(nargs() > 1);
return cell(1);
}
void InsetMathScript::ensure(bool up)
{
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
if (nargs() == 1) {
// just nucleus so far
cells_.push_back(MathData());
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
cell_1_is_up_ = up;
} else if (nargs() == 2 && !has(up)) {
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
if (up) {
cells_.push_back(cell(1));
cell(1).clear();
} else {
cells_.push_back(MathData());
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
}
}
}
MathData const & InsetMathScript::nuc() const
{
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
return cell(0);
}
MathData & InsetMathScript::nuc()
{
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
return cell(0);
}
int InsetMathScript::dy01(BufferView const & bv, int asc, int des, int what) const
{
int dasc = 0;
int slevel = 0;
bool isCharBox = !nuc().empty() ? isAlphaSymbol(nuc().back()) : false;
if (hasDown()) {
Dimension const & dimdown = down().dimension(bv);
dasc = dimdown.ascent();
slevel = nuc().slevel();
int ascdrop = dasc - slevel;
int desdrop = isCharBox ? 0 : des + nuc().sshift();
int mindes = nuc().mindes();
des = max(desdrop, ascdrop);
des = max(mindes, des);
}
if (hasUp()) {
Dimension const & dimup = up().dimension(bv);
int minasc = nuc().minasc();
int ascdrop = isCharBox ? 0 : asc - up().mindes();
int udes = dimup.descent();
asc = udes + nuc().sshift();
asc = max(ascdrop, asc);
asc = max(minasc, asc);
if (hasDown()) {
int del = asc - udes - dasc;
if (del + des <= 2) {
int newdes = 2 - del;
del = slevel - asc + udes;
if (del > 0) {
asc += del;
newdes -= del;
}
des = max(des, newdes);
}
}
}
return what ? asc : des;
}
int InsetMathScript::dy0(BufferView const & bv) const
{
int nd = ndes(bv);
if (!hasDown())
return nd;
int des = down().dimension(bv).ascent();
if (hasLimits())
des += nd + 2;
else {
int na = nasc(bv);
des = dy01(bv, na, nd, 0);
}
return des;
}
int InsetMathScript::dy1(BufferView const & bv) const
{
int na = nasc(bv);
if (!hasUp())
return na;
int asc = up().dimension(bv).descent();
if (hasLimits())
asc += na + 2;
else {
int nd = ndes(bv);
asc = dy01(bv, na, nd, 1);
}
asc = max(asc, 5);
return asc;
}
int InsetMathScript::dx0(BufferView const & bv) const
{
LASSERT(hasDown(), return 0);
Dimension const dim = dimension(bv);
return hasLimits() ? (dim.wid - down().dimension(bv).width()) / 2
: nwid(bv) + min(nker(&bv), 0);
}
int InsetMathScript::dx1(BufferView const & bv) const
{
LASSERT(hasUp(), return 0);
Dimension const dim = dimension(bv);
return hasLimits() ? (dim.wid - up().dimension(bv).width()) / 2
: nwid(bv) + max(nker(&bv), 0);
}
int InsetMathScript::dxx(BufferView const & bv) const
{
Dimension const dim = dimension(bv);
return hasLimits() ? (dim.wid - nwid(bv)) / 2 : 0;
}
int InsetMathScript::nwid(BufferView const & bv) const
{
return !nuc().empty() ? nuc().dimension(bv).width() : 2;
}
int InsetMathScript::nasc(BufferView const & bv) const
{
return !nuc().empty() ? nuc().dimension(bv).ascent() : 5;
}
int InsetMathScript::ndes(BufferView const & bv) const
{
return !nuc().empty() ? nuc().dimension(bv).descent() : 0;
}
int InsetMathScript::nker(BufferView const * bv) const
{
if (!nuc().empty())
return nuc().kerning(bv);
return 0;
}
MathClass InsetMathScript::mathClass() const
{
// FIXME: this is a hack, since the class will not be correct if
// the nucleus has several elements or if the last element is a math macro
// or a macro argument proxy.
// The correct implementation would require to linearize the nucleus.
if (nuc().empty())
return MC_ORD;
else {
// return the class of last element since this is the one that counts.
MathClass mc = nuc().back()->mathClass();
return (mc == MC_UNKNOWN) ? MC_ORD : mc;
}
}
void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const
{
Changer dummy2 = mi.base.changeEnsureMath();
Dimension dim0;
Dimension dim1;
Dimension dim2;
cell(0).metrics(mi, dim0);
Changer dummy = mi.base.changeScript();
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
if (nargs() > 1)
cell(1).metrics(mi, dim1);
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
if (nargs() > 2)
cell(2).metrics(mi, dim2);
dim.wid = 0;
BufferView & bv = *mi.base.bv;
// FIXME: data copying... not very efficient.
Dimension dimup;
Dimension dimdown;
if (hasUp())
dimup = up().dimension(bv);
if (hasDown())
dimdown = down().dimension(bv);
if (hasLimits()) {
dim.wid = nwid(bv);
if (hasUp())
dim.wid = max(dim.wid, dimup.width());
if (hasDown())
dim.wid = max(dim.wid, dimdown.width());
} else {
if (hasUp())
dim.wid = max(dim.wid, max(nker(mi.base.bv), 0) + dimup.width());
if (hasDown())
dim.wid = max(dim.wid, min(nker(mi.base.bv), 0) + dimdown.width());
dim.wid += nwid(bv);
}
int na = nasc(bv);
if (hasUp()) {
int asc = dy1(bv) + dimup.ascent();
dim.asc = max(na, asc);
} else
dim.asc = na;
int nd = ndes(bv);
if (hasDown()) {
int des = dy0(bv) + dimdown.descent();
dim.des = max(nd, des);
} else
dim.des = nd;
}
void InsetMathScript::draw(PainterInfo & pi, int x, int y) const
{
Changer dummy2 = pi.base.changeEnsureMath();
BufferView & bv = *pi.base.bv;
if (!nuc().empty())
nuc().draw(pi, x + dxx(bv), y);
else {
nuc().setXY(bv, x + dxx(bv), y);
if (editing(&bv))
pi.draw(x + dxx(bv), y, char_type('.'));
}
Changer dummy = pi.base.changeScript();
if (hasUp())
up().draw(pi, x + dx1(bv), y - dy1(bv));
if (hasDown())
down().draw(pi, x + dx0(bv), y + dy0(bv));
}
void InsetMathScript::metricsT(TextMetricsInfo const & mi, Dimension & dim) const
{
if (hasUp())
up().metricsT(mi, dim);
if (hasDown())
down().metricsT(mi, dim);
nuc().metricsT(mi, dim);
}
void InsetMathScript::drawT(TextPainter & pain, int x, int y) const
{
// FIXME: BROKEN
if (!nuc().empty())
nuc().drawT(pain, x + 1, y);
if (hasUp())
up().drawT(pain, x + 1, y - 1 /*dy1()*/);
if (hasDown())
down().drawT(pain, x + 1, y + 1 /*dy0()*/);
}
bool InsetMathScript::hasLimits() const
{
// obvious cases
if (limits_ == 1)
return true;
if (limits_ == -1)
return false;
// we can only display limits if the nucleus wants some
if (nuc().empty())
return false;
if (!nuc().back()->isScriptable())
return false;
if (nuc().back()->asSymbolInset()) {
// \intop is an alias for \int\limits, \ointop == \oint\limits
if (nuc().back()->asSymbolInset()->name().find(from_ascii("intop")) != string::npos)
return true;
// per default \int has limits beside the \int even in displayed formulas
if (nuc().back()->asSymbolInset()->name().find(from_ascii("int")) != string::npos)
return false;
}
// assume "real" limits for everything else
return true;
}
void InsetMathScript::removeScript(bool up)
{
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
if (nargs() == 2) {
if (up == cell_1_is_up_)
cells_.pop_back();
} else if (nargs() == 3) {
if (up == true) {
swap(cells_[1], cells_[2]);
cell_1_is_up_ = false;
} else {
cell_1_is_up_ = true;
}
cells_.pop_back();
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
}
}
bool InsetMathScript::has(bool up) const
{
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
return idxOfScript(up);
}
bool InsetMathScript::hasUp() const
{
//lyxerr << "1up: " << bool(cell_1_is_up_));
//lyxerr << "hasUp: " << bool(idxOfScript(true)));
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
return idxOfScript(true);
}
bool InsetMathScript::hasDown() const
{
//LYXERR0("1up: " << bool(cell_1_is_up_));
//LYXERR0("hasDown: " << bool(idxOfScript(false)));
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
return idxOfScript(false);
}
Inset::idx_type InsetMathScript::idxOfScript(bool up) const
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
{
if (nargs() == 1)
return 0;
if (nargs() == 2)
return (cell_1_is_up_ == up) ? 1 : 0;
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
if (nargs() == 3)
return up ? 1 : 2;
LASSERT(false, return 0);
}
bool InsetMathScript::idxForward(Cursor &) const
{
return false;
}
bool InsetMathScript::idxBackward(Cursor &) const
{
return false;
}
bool InsetMathScript::idxUpDown(Cursor & cur, bool up) const
{
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
// in nucleus?
if (cur.idx() == 0) {
// don't go up/down if there is no cell in this direction
if (!has(up))
return false;
// go up/down only if in the last position
// or in the first position of something with displayed limits
if (cur.pos() == cur.lastpos() || (cur.pos() == 0 && hasLimits())) {
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
cur.idx() = idxOfScript(up);
cur.pos() = 0;
return true;
}
return false;
}
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
// Are we 'up'?
if (cur.idx() == idxOfScript(true)) {
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
// can't go further up
if (up)
return false;
// otherwise go to last position in the nucleus
cur.idx() = 0;
cur.pos() = cur.lastpos();
return true;
}
// Are we 'down'?
if (cur.idx() == idxOfScript(false)) {
the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer<ParameterStruct> Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8
2004-03-25 09:16:36 +00:00
// can't go further down
if (!up)
return false;
// otherwise go to last position in the nucleus
cur.idx() = 0;
cur.pos() = cur.lastpos();
return true;
}
return false;
}
void InsetMathScript::write(WriteStream & os) const
{
MathEnsurer ensurer(os);
if (!nuc().empty()) {
os << nuc();
//if (nuc().back()->takesLimits()) {
if (limits_ == -1)
os << "\\nolimits ";
if (limits_ == 1)
os << "\\limits ";
//}
} else {
if (os.firstitem())
LYXERR(Debug::MATHED, "suppressing {} when writing");
else
os << "{}";
}
if (hasDown() /*&& !down().empty()*/)
os << "_{" << down() << '}';
if (hasUp() /*&& !up().empty()*/) {
// insert space if up() is empty or an empty brace inset
// (see bug 8305)
if (os.latex() && (up().empty() ||
(up().size() == 1 && up().back()->asBraceInset() &&
up().back()->asBraceInset()->cell(0).empty())))
os << "^ {}";
else
os << "^{" << up() << '}';
}
if (lock_ && !os.latex())
os << "\\lyxlock ";
}
void InsetMathScript::normalize(NormalStream & os) const
{
bool d = hasDown() && !down().empty();
bool u = hasUp() && !up().empty();
if (u && d)
os << "[subsup ";
else if (u)
os << "[sup ";
else if (d)
os << "[sub ";
if (!nuc().empty())
os << nuc() << ' ';
else
os << "[par]";
if (u && d)
os << down() << ' ' << up() << ']';
else if (d)
os << down() << ']';
else if (u)
os << up() << ']';
}
void InsetMathScript::maple(MapleStream & os) const
{
if (!nuc().empty())
os << nuc();
if (hasDown() && !down().empty())
os << '[' << down() << ']';
if (hasUp() && !up().empty())
os << "^(" << up() << ')';
}
void InsetMathScript::mathematica(MathematicaStream & os) const
{
bool d = hasDown() && !down().empty();
bool u = hasUp() && !up().empty();
if (!nuc().empty()) {
if (d)
os << "Subscript[" << nuc();
else
os << nuc();
}
if (u)
os << "^(" << up() << ')';
if (!nuc().empty()) {
if (d)
os << ',' << down() << ']';
}
}
void InsetMathScript::mathmlize(MathStream & os) const
{
bool d = hasDown() && !down().empty();
bool u = hasUp() && !up().empty();
bool l = hasLimits();
if (u && d)
os << MTag(l ? "munderover" : "msubsup");
else if (u)
os << MTag(l ? "mover" : "msup");
else if (d)
os << MTag(l ? "munder" : "msub");
if (!nuc().empty())
os << MTag("mrow") << nuc() << ETag("mrow");
else
os << "<mrow />";
if (u && d)
os << MTag("mrow") << down() << ETag("mrow")
<< MTag("mrow") << up() << ETag("mrow")
<< ETag(l ? "munderover" : "msubsup");
else if (u)
os << MTag("mrow") << up() << ETag("mrow") << ETag(l ? "mover" : "msup");
else if (d)
os << MTag("mrow") << down() << ETag("mrow") << ETag(l ? "munder" : "msub");
}
void InsetMathScript::htmlize(HtmlStream & os) const
{
bool d = hasDown() && !down().empty();
bool u = hasUp() && !up().empty();
if (!nuc().empty())
os << nuc();
if (u && d)
os << MTag("span", "class='scripts'")
<< MTag("span") << up() << ETag("span")
<< MTag("span") << down() << ETag("span")
<< ETag("span");
else if (u)
os << MTag("sup", "class='math'") << up() << ETag("sup");
else if (d)
os << MTag("sub", "class='math'") << down() << ETag("sub");
}
void InsetMathScript::octave(OctaveStream & os) const
{
if (!nuc().empty())
os << nuc();
if (hasDown() && !down().empty())
os << '[' << down() << ']';
if (hasUp() && !up().empty())
os << "^(" << up() << ')';
}
void InsetMathScript::infoize(odocstream & os) const
{
os << "Scripts";
}
void InsetMathScript::infoize2(odocstream & os) const
{
if (limits_)
os << from_ascii(limits_ == 1 ? ", Displayed limits" : ", Inlined limits");
}
bool InsetMathScript::notifyCursorLeaves(Cursor const & old, Cursor & cur)
{
InsetMathNest::notifyCursorLeaves(old, cur);
//LYXERR0("InsetMathScript::notifyCursorLeaves: 1 " << cur);
// Remove empty scripts if possible:
// The case of two scripts, but only one got empty (1 = super, 2 = sub).
// We keep the script inset, but remove the empty script.
if (nargs() > 2 && (!cell(1).empty() || !cell(2).empty())) {
if (cell(2).empty()) {
// must be a subscript...
old.recordUndoInset();
removeScript(false);
cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar);
return true;
} else if (cell(1).empty()) {
// must be a superscript...
old.recordUndoInset();
removeScript(true);
cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar);
return true;
}
}
// Now the two suicide cases:
// * we have only one script which is empty
// * we have two scripts which are both empty.
// The script inset is removed completely.
if ((nargs() == 2 && cell(1).empty())
|| (nargs() == 3 && cell(1).empty() && cell(2).empty())) {
// Make undo step. We cannot use cur for this because
// it does not necessarily point to us anymore. But we
// should be on top of the cursor old.
Cursor insetCur = old;
int scriptSlice = insetCur.find(this);
LASSERT(scriptSlice != -1, /**/);
insetCur.cutOff(scriptSlice);
insetCur.recordUndoInset();
// Let the script inset commit suicide. This is
// modelled on Cursor.pullArg(), but tries not to
// invoke notifyCursorLeaves again and does not touch
// cur (since the top slice will be deleted
// afterwards)
MathData ar = cell(0);
insetCur.pop();
insetCur.cell().erase(insetCur.pos());
insetCur.cell().insert(insetCur.pos(), ar);
// redraw
cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar);
return true;
}
//LYXERR0("InsetMathScript::notifyCursorLeaves: 2 " << cur);
return false;
}
void InsetMathScript::doDispatch(Cursor & cur, FuncRequest & cmd)
{
//LYXERR("InsetMathScript: request: " << cmd);
if (cmd.action() == LFUN_MATH_LIMITS) {
cur.recordUndoInset();
if (!cmd.argument().empty()) {
if (cmd.argument() == "limits")
limits_ = 1;
else if (cmd.argument() == "nolimits")
limits_ = -1;
else
limits_ = 0;
} else if (limits_ == 0)
limits_ = hasLimits() ? -1 : 1;
else
limits_ = 0;
return;
}
InsetMathNest::doDispatch(cur, cmd);
}
bool InsetMathScript::getStatus(Cursor & cur, FuncRequest const & cmd,
FuncStatus & flag) const
{
if (cmd.action() == LFUN_MATH_LIMITS) {
if (!cmd.argument().empty()) {
if (cmd.argument() == "limits")
flag.setOnOff(limits_ == 1);
else if (cmd.argument() == "nolimits")
flag.setOnOff(limits_ == -1);
else
flag.setOnOff(limits_ == 0);
}
flag.setEnabled(true);
return true;
}
return InsetMathNest::getStatus(cur, cmd, flag);
}
// the idea for dual scripts came from the eLyXer code
void InsetMathScript::validate(LaTeXFeatures & features) const
{
if (features.runparams().math_flavor == OutputParams::MathAsHTML)
features.addCSSSnippet(
"span.scripts{display: inline-block; vertical-align: middle; text-align:center; font-size: 75%;}\n"
"span.scripts span {display: block;}\n"
"sub.math{font-size: 75%;}\n"
"sup.math{font-size: 75%;}");
InsetMathNest::validate(features);
}
} // namespace lyx