}
-bool LCursor::inNucleus()
-{
- return inset()->asMathInset()->asScriptInset() && idx() == 2;
-}
-
-
bool positionable(CursorBase const & cursor, CursorBase const & anchor)
{
// avoid deeper nested insets when selecting
}
-bool LCursor::script(bool up)
-{
- // Hack to get \\^ and \\_ working
- lyxerr << "handling script: up: " << up << endl;
- if (inMacroMode() && macroName() == "\\") {
- if (up)
- niceInsert(createMathInset("mathcircumflex"));
- else
- interpret('_');
- return true;
- }
-
- macroModeClose();
- string safe = grabAndEraseSelection();
- if (inNucleus()) {
- // we are in a nucleus of a script inset, move to _our_ script
- inset()->asMathInset()->asScriptInset()->ensure(up);
- idx() = up;
- pos() = 0;
- } else if (pos() != 0 && prevAtom()->asScriptInset()) {
- --pos();
- nextAtom().nucleus()->asScriptInset()->ensure(up);
- push(nextInset());
- idx() = up;
- pos() = lastpos();
- } else if (pos() != 0) {
- --pos();
- cell()[pos()] = MathAtom(new MathScriptInset(nextAtom(), up));
- push(nextInset());
- idx() = up;
- pos() = 0;
- } else {
- plainInsert(MathAtom(new MathScriptInset(up)));
- --pos();
- nextAtom().nucleus()->asScriptInset()->ensure(up);
- push(nextInset());
- idx() = up;
- pos() = 0;
- }
- paste(safe);
- return true;
-}
-
-
-bool LCursor::interpret(char c)
-{
- //lyxerr << "interpret 2: '" << c << "'" << endl;
- clearTargetX();
- if (inMacroArgMode()) {
- posLeft();
- plainErase();
-#warning FIXME
-#if 0
- int n = c - '0';
- MathMacroTemplate const * p = formula()->asMacroTemplate();
- if (p && 1 <= n && n <= p->numargs())
- insert(MathAtom(new MathMacroArgument(c - '0')));
- else {
- insert(createMathInset("#"));
- interpret(c); // try again
- }
-#endif
- return true;
- }
-
- // handle macroMode
- if (inMacroMode()) {
- string name = macroName();
- //lyxerr << "interpret name: '" << name << "'" << endl;
-
- if (isalpha(c)) {
- activeMacro()->setName(activeMacro()->name() + c);
- return true;
- }
-
- // handle 'special char' macros
- if (name == "\\") {
- // remove the '\\'
- backspace();
- if (c == '\\') {
- if (currentMode() == MathInset::TEXT_MODE)
- niceInsert(createMathInset("textbackslash"));
- else
- niceInsert(createMathInset("backslash"));
- } else if (c == '{') {
- niceInsert(MathAtom(new MathBraceInset));
- } else {
- niceInsert(createMathInset(string(1, c)));
- }
- return true;
- }
-
- // leave macro mode and try again if necessary
- macroModeClose();
- if (c == '{')
- niceInsert(MathAtom(new MathBraceInset));
- else if (c != ' ')
- interpret(c);
- return true;
- }
-
- // This is annoying as one has to press <space> far too often.
- // Disable it.
-
- if (0) {
- // leave autocorrect mode if necessary
- if (autocorrect() && c == ' ') {
- autocorrect() = false;
- return true;
- }
- }
-
- // just clear selection on pressing the space bar
- if (selection() && c == ' ') {
- selection() = false;
- return true;
- }
-
- selClearOrDel();
-
- if (c == '\\') {
- //lyxerr << "starting with macro" << endl;
- insert(MathAtom(new MathUnknownInset("\\", false)));
- return true;
- }
-
- if (c == '\n') {
- if (currentMode() == MathInset::TEXT_MODE)
- insert(c);
- return true;
- }
-
- if (c == ' ') {
- if (currentMode() == MathInset::TEXT_MODE) {
- // insert spaces in text mode,
- // but suppress direct insertion of two spaces in a row
- // the still allows typing '<space>a<space>' and deleting the 'a', but
- // it is better than nothing...
- if (!pos() != 0 || prevAtom()->getChar() != ' ')
- insert(c);
- return true;
- }
- if (pos() != 0 && prevAtom()->asSpaceInset()) {
- prevAtom().nucleus()->asSpaceInset()->incSpace();
- return true;
- }
- if (popRight())
- return true;
- // if are at the very end, leave the formula
- return pos() != lastpos();
- }
-
- if (c == '_') {
- script(false);
- return true;
- }
-
- if (c == '^') {
- script(true);
- return true;
- }
-
- if (c == '{' || c == '}' || c == '#' || c == '&' || c == '$') {
- niceInsert(createMathInset(string(1, c)));
- return true;
- }
-
- if (c == '%') {
- niceInsert(MathAtom(new MathCommentInset));
- return true;
- }
-
- // try auto-correction
- //if (autocorrect() && hasPrevAtom() && math_autocorrect(prevAtom(), c))
- // return true;
-
- // no special circumstances, so insert the character without any fuss
- insert(c);
- autocorrect() = true;
- return true;
-}
-
-
void LCursor::lockToggle()
{
if (pos() != lastpos()) {
///
MathHullInset * formula() const;
/// current offset in the current cell
- ///
- bool script(bool);
- ///
- bool interpret(char);
/// interpret name a name of a macro
void macroModeClose();
/// are we currently typing the name of a macro?
///
std::string getPossibleLabel();
-private:
/// moves position somehow up or down
bool goUpDown(bool up);
/// moves position closest to (x, y) in given box
bool bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh);
/// moves position closest to (x, y) in current cell
void bruteFind2(int x, int y);
- /// are we in a nucleus of a script inset?
- bool inNucleus();
/// the name of the macro we are currently inputting
std::string macroName();
/// where in the curent cell does the macro name start?
int macroNamePos();
-public:
/// can we enter the inset?
bool openable(MathAtom const &) const;
};
Row::Row()
- : pos_(0), end_(0), fill_(0), height_(0), width_(0), y_offset_(0),
+ : pos_(0), end_(0), height_(0), width_(0), y_offset_(0),
ascent_of_text_(0), baseline_(0),
x_(0), fill_separator_(0), fill_hfill_(0), fill_label_hfill_(0)
{}
Row::Row(pos_type pos)
- : pos_(pos), end_(0), fill_(0), height_(0), width_(0), y_offset_(0),
+ : pos_(pos), end_(0), height_(0), width_(0), y_offset_(0),
ascent_of_text_(0), baseline_(0),
x_(0), fill_separator_(0), fill_hfill_(0), fill_label_hfill_(0)
{}
}
-void Row::fill(int f)
-{
- fill_ = f;
-}
-
-
-int Row::fill() const
-{
- return fill_;
-}
-
-
void Row::width(unsigned int w)
{
width_ = w;
{
lyxerr << s << " pos: " << pos_ << " width: " << width_
<< " height: " << height_
- << " fill: " << fill_
<< " ascent_of_text: " << ascent_of_text_
<< " top_of_text: " << top_of_text_
<< " y_offset: " << y_offset_ << std::endl;
///
lyx::pos_type endpos() const;
///
- void fill(int f);
- ///
- int fill() const;
- ///
void height(unsigned int h) { height_ = h; }
///
unsigned int height() const { return height_; }
lyx::pos_type pos_;
/// one behind last pos covered by this row
lyx::pos_type end_;
- /** what is missing to a full row. Can be negative.
- Needed for hfills, flushright, block etc. */
- mutable int fill_;
///
unsigned int height_;
///
/// sets row.end to the pos value *after* which a row should break.
/// for example, the pos after which isNewLine(pos) == true
void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
- /// sets row.witdh to the minimum space a row needs on the screen in pixel
- void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
+ /// sets row.width to the minimum space a row needs on the screen in pixel
+ void setRowWidth(ParagraphList::iterator pit, Row & row) const;
/// the minimum space a manual label needs on the screen in pixels
int labelFill(ParagraphList::iterator pit, Row const & row) const;
/// FIXME
#include "math_nestinset.h"
#include "math_arrayinset.h"
+#include "math_braceinset.h"
+#include "math_commentinset.h"
#include "math_data.h"
#include "math_deliminset.h"
#include "math_factory.h"
#include "math_hullinset.h"
#include "math_mathmlstream.h"
#include "math_parser.h"
+#include "math_scriptinset.h"
#include "math_spaceinset.h"
#include "math_support.h"
#include "math_mboxinset.h"
+#include "math_unknowninset.h"
#include "BufferView.h"
#include "bufferview_funcs.h"
void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
{
lyxerr << "MathNestInset: request: " << cmd << std::endl;
- CursorSlice sl = cur.current();
+ //CursorSlice sl = cur.current();
switch (cmd.action) {
cur.insert(cmd.argument);
break;
}
- if (!cur.interpret(cmd.argument[0]))
+ if (!interpret(cur, cmd.argument[0]))
cur.dispatched(FINISHED_RIGHT);
break;
// do superscript if LyX handles
// deadkeys
//recordUndo(cur, Undo::ATOMIC);
- cur.script(true);
+ script(cur, true);
}
break;
cur.posLeft();
cur.pushLeft(cur.nextInset());
#else
- if (cur.currentMode() == InsetBase::TEXT_MODE)
+ if (currentMode() == InsetBase::TEXT_MODE)
cur.niceInsert(MathAtom(new MathHullInset("simple")));
else
handleFont(cur, cmd.argument, "textrm");
case LFUN_INSET_ERT:
// interpret this as if a backslash was typed
//recordUndo(cur, Undo::ATOMIC);
- cur.interpret('\\');
+ interpret(cur, '\\');
break;
// FIXME: We probably should swap parts of "math-insert" and "self-insert"
cur.bv().cursor().selection() = true;
return;
}
+
+
+bool MathNestInset::interpret(LCursor & cur, char c)
+{
+ //lyxerr << "interpret 2: '" << c << "'" << endl;
+ cur.clearTargetX();
+ if (cur.inMacroArgMode()) {
+ cur.posLeft();
+ cur.plainErase();
+#warning FIXME
+#if 0
+ int n = c - '0';
+ MathMacroTemplate const * p = formula()->asMacroTemplate();
+ if (p && 1 <= n && n <= p->numargs())
+ cur.insert(MathAtom(new MathMacroArgument(c - '0')));
+ else {
+ cur.insert(createMathInset("#"));
+ interpret(cur, c); // try again
+ }
+#endif
+ return true;
+ }
+
+ // handle macroMode
+ if (cur.inMacroMode()) {
+ string name = cur.macroName();
+ //lyxerr << "interpret name: '" << name << "'" << endl;
+
+ if (isalpha(c)) {
+ cur.activeMacro()->setName(cur.activeMacro()->name() + c);
+ return true;
+ }
+
+ // handle 'special char' macros
+ if (name == "\\") {
+ // remove the '\\'
+ cur.backspace();
+ if (c == '\\') {
+ if (currentMode() == MathInset::TEXT_MODE)
+ cur.niceInsert(createMathInset("textbackslash"));
+ else
+ cur.niceInsert(createMathInset("backslash"));
+ } else if (c == '{') {
+ cur.niceInsert(MathAtom(new MathBraceInset));
+ } else {
+ cur.niceInsert(createMathInset(string(1, c)));
+ }
+ return true;
+ }
+
+ // leave macro mode and try again if necessary
+ cur.macroModeClose();
+ if (c == '{')
+ cur.niceInsert(MathAtom(new MathBraceInset));
+ else if (c != ' ')
+ interpret(cur, c);
+ return true;
+ }
+
+ // This is annoying as one has to press <space> far too often.
+ // Disable it.
+
+#if 0
+ // leave autocorrect mode if necessary
+ if (autocorrect() && c == ' ') {
+ autocorrect() = false;
+ return true;
+ }
+#endif
+
+ // just clear selection on pressing the space bar
+ if (cur.selection() && c == ' ') {
+ cur.selection() = false;
+ return true;
+ }
+
+ cur.selClearOrDel();
+
+ if (c == '\\') {
+ //lyxerr << "starting with macro" << endl;
+ cur.insert(MathAtom(new MathUnknownInset("\\", false)));
+ return true;
+ }
+
+ if (c == '\n') {
+ if (currentMode() == MathInset::TEXT_MODE)
+ cur.insert(c);
+ return true;
+ }
+
+ if (c == ' ') {
+ if (currentMode() == MathInset::TEXT_MODE) {
+ // insert spaces in text mode,
+ // but suppress direct insertion of two spaces in a row
+ // the still allows typing '<space>a<space>' and deleting the 'a', but
+ // it is better than nothing...
+ if (!cur.pos() != 0 || cur.prevAtom()->getChar() != ' ')
+ cur.insert(c);
+ return true;
+ }
+ if (cur.pos() != 0 && cur.prevAtom()->asSpaceInset()) {
+ cur.prevAtom().nucleus()->asSpaceInset()->incSpace();
+ return true;
+ }
+ if (cur.popRight())
+ return true;
+ // if are at the very end, leave the formula
+ return cur.pos() != cur.lastpos();
+ }
+
+ if (c == '_') {
+ script(cur, false);
+ return true;
+ }
+
+ if (c == '^') {
+ script(cur, true);
+ return true;
+ }
+
+ if (c == '{' || c == '}' || c == '#' || c == '&' || c == '$') {
+ cur.niceInsert(createMathInset(string(1, c)));
+ return true;
+ }
+
+ if (c == '%') {
+ cur.niceInsert(MathAtom(new MathCommentInset));
+ return true;
+ }
+
+ // try auto-correction
+ //if (autocorrect() && hasPrevAtom() && math_autocorrect(prevAtom(), c))
+ // return true;
+
+ // no special circumstances, so insert the character without any fuss
+ cur.insert(c);
+ cur.autocorrect() = true;
+ return true;
+}
+
+
+bool MathNestInset::script(LCursor & cur, bool up)
+{
+ // Hack to get \\^ and \\_ working
+ lyxerr << "handling script: up: " << up << endl;
+ if (cur.inMacroMode() && cur.macroName() == "\\") {
+ if (up)
+ cur.niceInsert(createMathInset("mathcircumflex"));
+ else
+ interpret(cur, '_');
+ return true;
+ }
+
+ cur.macroModeClose();
+ string safe = cur.grabAndEraseSelection();
+ if (asScriptInset() && cur.idx() == 2) {
+ // we are in a nucleus of a script inset, move to _our_ script
+ asScriptInset()->ensure(up);
+ cur.idx() = up;
+ cur.pos() = 0;
+ } else if (cur.pos() != 0 && cur.prevAtom()->asScriptInset()) {
+ --cur.pos();
+ cur.nextAtom().nucleus()->asScriptInset()->ensure(up);
+ cur.push(cur.nextInset());
+ cur.idx() = up;
+ cur.pos() = cur.lastpos();
+ } else if (cur.pos() != 0) {
+ --cur.pos();
+ cur.cell()[cur.pos()] = MathAtom(new MathScriptInset(cur.nextAtom(), up));
+ cur.push(cur.nextInset());
+ cur.idx() = up;
+ cur.pos() = 0;
+ } else {
+ cur.plainInsert(MathAtom(new MathScriptInset(up)));
+ --cur.pos();
+ cur.nextAtom().nucleus()->asScriptInset()->ensure(up);
+ cur.push(cur.nextInset());
+ cur.idx() = up;
+ cur.pos() = 0;
+ }
+ cur.paste(safe);
+ return true;
+}
///
void handleFont2(LCursor & cur, std::string const & arg);
+ ///
+ bool interpret(LCursor & cur, char c);
+ ///
+ bool script(LCursor & cur, bool);
+
private:
/// lfun handler
if (!pit_->params().appendix())
return;
- // FIXME: can be just width_ ?
- int const ww = width_;
-
int y = yo_;
if (pit_->params().startOfAppendix())
y += 2 * defaultRowHeight();
pain_.line(1, y, 1, yo_ + row_.height(), LColor::appendix);
- pain_.line(ww - 2, y, ww - 2, yo_ + row_.height(), LColor::appendix);
+ pain_.line(width_ - 2, y, width_ - 2, yo_ + row_.height(), LColor::appendix);
}
}
}
- int const ww = bv_.workWidth();
-
bool const is_rtl = text_.isRTL(*pit_);
bool const is_seq = isFirstInSequence(pit_, text_.paragraphs());
//lyxerr << "paintFirst: " << pit_->id() << " is_seq: " << is_seq << std::endl;
+ int(layout->parsep) * defaultRowHeight();
if (is_rtl) {
- x = ww - leftMargin() -
+ x = width_ - leftMargin() -
font_metrics::width(str, font);
}
}
} else {
if (is_rtl) {
- x = ww - leftMargin()
+ x = width_ - leftMargin()
+ font_metrics::width(layout->labelsep, font);
} else {
x = x_ - font_metrics::width(layout->labelsep, font)
double x = x_;
if (layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) {
x = ((is_rtl ? leftMargin() : x_)
- + ww - text_.rightMargin(*pit_)) / 2;
+ + width_ - text_.rightMargin(*pit_)) / 2;
x -= font_metrics::width(str, font) / 2;
} else if (is_rtl) {
- x = ww - leftMargin() -
+ x = width_ - leftMargin() -
font_metrics::width(str, font);
}
pain_.text(int(x),
void RowPainter::paintLast()
{
- int const ww = bv_.workWidth();
bool const is_rtl = text_.isRTL(*pit_);
int const endlabel = getEndLabel(pit_, text_.paragraphs());
LyXFont const font = getLabelFont();
int const size = int(0.75 * font_metrics::maxAscent(font));
int const y = yo_ + row_.baseline() - size;
- int x = is_rtl ? NEST_MARGIN + CHANGEBAR_MARGIN: ww - size;
+ int x = is_rtl ? NEST_MARGIN + CHANGEBAR_MARGIN: width_ - size;
- if (row_.fill() <= size)
- x += (size - row_.fill() + 1) * (is_rtl ? -1 : 1);
+ if (width_ - row_.width() <= size)
+ x += (size - width_ + row_.width() + 1) * (is_rtl ? -1 : 1);
if (endlabel == END_LABEL_BOX)
pain_.rectangle(x, y, size, size, LColor::eolmarker);
string const & str = pit_->layout()->endlabelstring();
double const x = is_rtl ?
x_ - font_metrics::width(str, font)
- : ww - text_.rightMargin(*pit_) - row_.fill();
+ : - text_.rightMargin(*pit_) - row_.width();
pain_.text(int(x), yo_ + row_.baseline(), str, font);
break;
}
}
-// returns the minimum space a row needs on the screen in pixel
-void LyXText::fill(ParagraphList::iterator pit, Row & row, int workwidth) const
+void LyXText::setRowWidth(ParagraphList::iterator pit, Row & row) const
{
// get the pure distance
pos_type const end = row.endpos();
w = max(w, labelEnd(pit));
}
- int const fill = workwidth - w - rightMargin(*pit);
- row.fill(fill);
- row.width(workwidth - fill);
+ row.width(w + rightMargin(*pit));
}
void LyXText::prepareToPrint(ParagraphList::iterator pit, Row & row) const
{
- double w = row.fill();
+ double w = textWidth() - row.width();
double fill_hfill = 0;
double fill_label_hfill = 0;
double fill_separator = 0;
do {
Row row(z);
rowBreakPoint(pit, row);
- z = row.endpos();
- fill(pit, row, textwidth_);
+ setRowWidth(pit, row);
prepareToPrint(pit, row);
setHeightOfRow(pit, row);
row.y_offset(pit->height);
pit->rows.push_back(row);
pit->width = std::max(pit->width, row.width());
pit->height += row.height();
+ z = row.endpos();
} while (z < pit->size());
height += pit->height;