#include "LString.h"
#include "paragraph.h"
#include "lyxtextclasslist.h"
-#include "LyXView.h"
+#include "frontends/LyXView.h"
#include "undo_funcs.h"
#include "buffer.h"
#include "bufferparams.h"
#include "gettext.h"
#include "BufferView.h"
-#include "LyXView.h"
#include "CutAndPaste.h"
-#include "Painter.h"
-#include "font.h"
+#include "frontends/Painter.h"
+#include "frontends/font_metrics.h"
#include "debug.h"
#include "lyxrc.h"
#include "lyxrow.h"
par = par->outerHook();
if (par) {
#ifndef INHERIT_LANGUAGE
- tmpfont.realize(textclasslist[buf->params.textclass][
- par->layout()].font);
+ tmpfont.realize(par->layout()->font);
#else
tmpfont.realize(textclasslist.
Style(buf->params.textclass,
- par->layout()).font,
+ par->layout())->font,
buf->params.language);
#endif
par_depth = par->getDepth();
{
lyx::Assert(pos >= 0);
- LyXLayout const & layout =
- textclasslist[buf->params.textclass][par->layout()];
+ LyXLayout_ptr const & layout = par->layout();
Paragraph::depth_type par_depth = par->getDepth();
// We specialize the 95% common case:
if (!par_depth) {
- if (layout.labeltype == LABEL_MANUAL
+ if (layout->labeltype == LABEL_MANUAL
&& pos < beginningOfMainBody(buf, par)) {
// 1% goes here
LyXFont f = par->getFontSettings(buf->params, pos);
if (par->inInset())
par->inInset()->getDrawFont(f);
#ifndef INHERIT_LANGUAGE
- return f.realize(layout.reslabelfont);
+ return f.realize(layout->reslabelfont);
#else
return f.realize(layout.reslabelfont, buf->params.language);
#endif
if (par->inInset())
par->inInset()->getDrawFont(f);
#ifndef INHERIT_LANGUAGE
- return f.realize(layout.resfont);
+ return f.realize(layout->resfont);
#else
return f.realize(layout.resfont, buf->params.language);
#endif
if (pos < beginningOfMainBody(buf, par)) {
// 1% goes here
- layoutfont = layout.labelfont;
+ layoutfont = layout->labelfont;
} else {
// 99% goes here
- layoutfont = layout.font;
+ layoutfont = layout->font;
}
LyXFont tmpfont = par->getFontSettings(buf->params, pos);
LyXFont const LyXText::getLayoutFont(Buffer const * buf, Paragraph * par) const
{
- LyXLayout const & layout =
- textclasslist[buf->params.textclass][par->layout()];
+ LyXLayout_ptr const & layout = par->layout();
Paragraph::depth_type par_depth = par->getDepth();
if (!par_depth) {
- return layout.resfont;
+ return layout->resfont;
}
- return realizeFont(layout.font, buf, par);
+ return realizeFont(layout->font, buf, par);
}
LyXFont const LyXText::getLabelFont(Buffer const * buf, Paragraph * par) const
{
- LyXLayout const & layout =
- textclasslist[buf->params.textclass][par->layout()];
+ LyXLayout_ptr const & layout = par->layout();
Paragraph::depth_type par_depth = par->getDepth();
if (!par_depth) {
- return layout.reslabelfont;
+ return layout->reslabelfont;
}
- return realizeFont(layout.labelfont, buf, par);
+ return realizeFont(layout->labelfont, buf, par);
}
LyXFont font(fnt);
LyXTextClass const & tclass = textclasslist[buf->params.textclass];
- LyXLayout const & layout = tclass[par->layout()];
+ LyXLayout_ptr const & layout = par->layout();
// Get concrete layout font to reduce against
LyXFont layoutfont;
if (pos < beginningOfMainBody(buf, par))
- layoutfont = layout.labelfont;
+ layoutfont = layout->labelfont;
else
- layoutfont = layout.font;
+ layoutfont = layout->font;
// Realize against environment font information
if (par->getDepth()) {
tp = tp->outerHook();
if (tp)
#ifndef INHERIT_LANGUAGE
- layoutfont.realize(tclass[tp->layout()].font);
+ layoutfont.realize(tp->layout()->font);
#else
layoutfont.realize(textclasslist.
Style(buf->params.textclass,
void LyXText::makeFontEntriesLayoutSpecific(Buffer const * buf,
Paragraph * par)
{
- LyXLayout const & layout =
- textclasslist[buf->params.textclass][par->layout()];
+ LyXLayout_ptr const & layout = par->layout();
LyXFont layoutfont;
for (pos_type pos = 0; pos < par->size(); ++pos) {
if (pos < beginningOfMainBody(buf, par))
- layoutfont = layout.labelfont;
+ layoutfont = layout->labelfont;
else
- layoutfont = layout.font;
+ layoutfont = layout->font;
LyXFont tmpfont = par->getFontSettings(buf->params, pos);
tmpfont.reduce(layoutfont);
// ok we have a selection. This is always between sstart_cur
// and sel_end cursor
cur = sstart_cur;
+ Paragraph * par = sstart_cur.par();
+ Paragraph * epar = send_cur.par()->next();
- LyXLayout const & lyxlayout =
+ LyXLayout_ptr const & lyxlayout =
textclasslist[bview->buffer()->params.textclass][layout];
do {
- cur.par()->applyLayout(layout);
- makeFontEntriesLayoutSpecific(bview->buffer(), cur.par());
- Paragraph * fppar = cur.par();
- fppar->params().spaceTop(lyxlayout.fill_top ?
+ par->applyLayout(lyxlayout);
+ makeFontEntriesLayoutSpecific(bview->buffer(), par);
+ Paragraph * fppar = par;
+ fppar->params().spaceTop(lyxlayout->fill_top ?
VSpace(VSpace::VFILL)
: VSpace(VSpace::NONE));
- fppar->params().spaceBottom(lyxlayout.fill_bottom ?
+ fppar->params().spaceBottom(lyxlayout->fill_bottom ?
VSpace(VSpace::VFILL)
: VSpace(VSpace::NONE));
- if (lyxlayout.margintype == MARGIN_MANUAL)
- cur.par()->setLabelWidthString(lyxlayout.labelstring());
- if (lyxlayout.labeltype != LABEL_BIBLIO
+ if (lyxlayout->margintype == MARGIN_MANUAL)
+ par->setLabelWidthString(lyxlayout->labelstring());
+ if (lyxlayout->labeltype != LABEL_BIBLIO
&& fppar->bibkey) {
delete fppar->bibkey;
fppar->bibkey = 0;
}
- if (cur.par() != send_cur.par())
- cur.par(cur.par()->next());
- } while (cur.par() != send_cur.par());
+ cur.par(par);
+ par = par->next();
+ } while (par != epar);
return endpar;
}
bool anything_changed = false;
- LyXTextClass const & tclass =
- textclasslist[bview->buffer()->params.textclass];
-
while (true) {
// NOTE: you can't change the depth of a bibliography entry
- if (tclass[cursor.par()->layout()].labeltype != LABEL_BIBLIO) {
+ if (cursor.par()->layout()->labeltype != LABEL_BIBLIO) {
Paragraph * prev = cursor.par()->previous();
if (prev) {
if (cursor.par()->getDepth()
- < prev->getMaxDepthAfter(bview->buffer())){
+ < prev->getMaxDepthAfter()) {
cursor.par()->params().depth(cursor.par()->getDepth() + 1);
anything_changed = true;
}
freezeUndo();
cursor = selection.start;
while (cursor.par() != selection.end.par() ||
- (cursor.pos() < selection.end.pos()))
+ cursor.pos() < selection.end.pos())
{
if (cursor.pos() < cursor.par()->size()) {
- // an open footnote should behave
- // like a closed one
+ // an open footnote should behave like a closed one
setCharFont(bview, cursor.par(), cursor.pos(),
font, toggleall);
cursor.pos(cursor.pos() + 1);
}
-bool LyXText::fullRebreak(BufferView * bview)
+void LyXText::fullRebreak(BufferView * bview)
{
if (!firstrow) {
init(bview);
- return true;
+ return;
}
if (need_break_row) {
breakAgain(bview, need_break_row);
need_break_row = 0;
- return true;
+ return;
}
- return true;
}
// important for the screen
-/* the cursor set functions have a special mechanism. When they
- * realize, that you left an empty paragraph, they will delete it.
- * They also delete the corresponding row */
+// the cursor set functions have a special mechanism. When they
+// realize, that you left an empty paragraph, they will delete it.
+// They also delete the corresponding row
// need the selection cursor:
void LyXText::setSelection(BufferView * bview)
}
-pos_type LyXText::beginningOfMainBody(Buffer const * buf,
+pos_type LyXText::beginningOfMainBody(Buffer const * /*buf*/,
Paragraph const * par) const
{
- if (textclasslist[buf->params.textclass][
- par->layout()].labeltype != LABEL_MANUAL)
+ if (par->layout()->labeltype != LABEL_MANUAL)
return 0;
else
return par->beginningOfMainBody();
}
-/* the DTP switches for paragraphs. LyX will store them in the
-* first physicla paragraph. When a paragraph is broken, the top settings
-* rest, the bottom settings are given to the new one. So I can make shure,
-* they do not duplicate themself and you cannnot make dirty things with
-* them! */
+// the DTP switches for paragraphs. LyX will store them in the first
+// physicla paragraph. When a paragraph is broken, the top settings rest,
+// the bottom settings are given to the new one. So I can make shure,
+// they do not duplicate themself and you cannnot make dirty things with
+// them!
void LyXText::setParagraph(BufferView * bview,
bool line_top, bool line_bottom,
Paragraph * tmppar = selection.end.par();
- LyXTextClass const & tclass =
- textclasslist[bview->buffer()->params.textclass];
while (tmppar != selection.start.par()->previous()) {
setCursor(bview, tmppar, 0);
cursor.par()->params().spaceBottom(space_bottom);
cursor.par()->params().spacing(spacing);
// does the layout allow the new alignment?
- LyXLayout const & layout = tclass[cursor.par()->layout()];
+ LyXLayout_ptr const & layout = cursor.par()->layout();
if (align == LYX_ALIGN_LAYOUT)
- align = layout.align;
- if (align & layout.alignpossible) {
- if (align == layout.align)
+ align = layout->align;
+ if (align & layout->alignpossible) {
+ if (align == layout->align)
cursor.par()->params().align(LYX_ALIGN_LAYOUT);
else
cursor.par()->params().align(align);
void LyXText::setCounter(Buffer const * buf, Paragraph * par) const
{
LyXTextClass const & textclass = textclasslist[buf->params.textclass];
- LyXLayout const & layout = textclass[par->layout()];
-
+ LyXLayout_ptr const & layout = par->layout();
// copy the prev-counters to this one,
// unless this is the first paragraph
*/
if (par->previous()
&& par->previous()->getDepth() < par->getDepth()
- && textclass[par->previous()->layout()].labeltype == LABEL_COUNTER_ENUMI
+ && par->previous()->layout()->labeltype == LABEL_COUNTER_ENUMI
&& par->enumdepth < 3
- && layout.labeltype != LABEL_BIBLIO) {
+ && layout->labeltype != LABEL_BIBLIO) {
par->enumdepth++;
}
// Maybe we have to decrement the enumeration depth, see note above
if (par->previous()
&& par->previous()->getDepth() > par->getDepth()
- && layout.labeltype != LABEL_BIBLIO) {
+ && layout->labeltype != LABEL_BIBLIO) {
par->enumdepth = par->depthHook(par->getDepth())->enumdepth;
par->setCounter(6 + par->enumdepth,
par->depthHook(par->getDepth())->getCounter(6 + par->enumdepth));
- /* reset the counters.
- * A depth change is like a breaking layout
- */
+ // reset the counters.A depth change is like a breaking layout
for (int i = 6 + par->enumdepth + 1; i < 10; ++i)
par->setCounter(i, 0);
}
par->params().labelString(string());
}
- if (layout.margintype == MARGIN_MANUAL) {
+ if (layout->margintype == MARGIN_MANUAL) {
if (par->params().labelWidthString().empty()) {
- par->setLabelWidthString(layout.labelstring());
+ par->setLabelWidthString(layout->labelstring());
}
} else {
par->setLabelWidthString(string());
}
// is it a layout that has an automatic label?
- if (layout.labeltype >= LABEL_COUNTER_CHAPTER) {
+ if (layout->labeltype >= LABEL_COUNTER_CHAPTER) {
- int i = layout.labeltype - LABEL_COUNTER_CHAPTER;
+ int i = layout->labeltype - LABEL_COUNTER_CHAPTER;
if (i >= 0 && i<= buf->params.secnumdepth) {
par->incCounter(i); // increment the counter
// Is there a label? Useful for Chapter layout
if (!par->params().appendix()) {
- if (!layout.labelstring().empty())
- par->params().labelString(layout.labelstring());
+ if (!layout->labelstring().empty())
+ par->params().labelString(layout->labelstring());
else
par->params().labelString(string());
} else {
- if (!layout.labelstring_appendix().empty())
- par->params().labelString(layout.labelstring_appendix());
+ if (!layout->labelstring_appendix().empty())
+ par->params().labelString(layout->labelstring_appendix());
else
par->params().labelString(string());
}
// reset the following counters
par->setCounter(i, 0);
}
- } else if (layout.labeltype < LABEL_COUNTER_ENUMI) {
+ } else if (layout->labeltype < LABEL_COUNTER_ENUMI) {
for (i++; i < 10; ++i) {
// reset the following counters
par->setCounter(i, 0);
}
- } else if (layout.labeltype == LABEL_COUNTER_ENUMI) {
+ } else if (layout->labeltype == LABEL_COUNTER_ENUMI) {
par->incCounter(i + par->enumdepth);
int number = par->getCounter(i + par->enumdepth);
}
}
- } else if (layout.labeltype == LABEL_BIBLIO) {// ale970302
+ } else if (layout->labeltype == LABEL_BIBLIO) {// ale970302
int i = LABEL_COUNTER_ENUMI - LABEL_COUNTER_CHAPTER + par->enumdepth;
par->incCounter(i);
int number = par->getCounter(i);
par->bibkey = new InsetBibKey(p);
}
par->bibkey->setCounter(number);
- par->params().labelString(layout.labelstring());
+ par->params().labelString(layout->labelstring());
// In biblio should't be following counters but...
} else {
- string s = layout.labelstring();
+ string s = layout->labelstring();
// the caption hack:
- if (layout.labeltype == LABEL_SENSITIVE) {
+ if (layout->labeltype == LABEL_SENSITIVE) {
bool isOK (par->inInset() && par->inInset()->owner() &&
(par->inInset()->owner()->lyxCode() == Inset::FLOAT_CODE));
// now check for the headline layouts. remember that they
// have a dynamic left margin
- LyXTextClass const & tclass =
- textclasslist[bview->buffer()->params.textclass];
- LyXLayout const & layout = tclass[par->layout()];
+ LyXLayout_ptr const & layout = par->layout();
- if (layout.margintype == MARGIN_DYNAMIC
- || layout.labeltype == LABEL_SENSITIVE) {
+ if (layout->margintype == MARGIN_DYNAMIC
+ || layout->labeltype == LABEL_SENSITIVE) {
// Rebreak the paragraph
removeParagraph(row);
appendParagraph(bview, row);
{
if (!cursor.par()->insetAllowed(inset->lyxCode()))
return;
- // I don't know if this is necessary here (Jug 20020102)
- setUndo(bview, Undo::INSERT, cursor.par(), cursor.par()->next());
+ setUndo(bview, Undo::FINISH, cursor.par(), cursor.par()->next());
+ freezeUndo();
cursor.par()->insertInset(cursor.pos(), inset);
// Just to rebreak and refresh correctly.
// The character will not be inserted a second time
insertChar(bview, Paragraph::META_INSET);
-#if 1
// If we enter a highly editable inset the cursor should be to before
// the inset. This couldn't happen before as Undo was not handled inside
// inset now after the Undo LyX tries to call inset->Edit(...) again
if (isHighlyEditableInset(inset)) {
cursorLeft(bview, true);
}
-#endif
+ unFreezeUndo();
}
void LyXText::copyEnvironmentType()
{
- copylayouttype = cursor.par()->layout();
+ copylayouttype = cursor.par()->layout()->name();
}
// sometimes necessary
if (doclear)
- selection.start.par()->stripLeadingSpaces(bview->buffer()->params.textclass);
+ selection.start.par()->stripLeadingSpaces();
redoParagraphs(bview, selection.start, endpar);
status(bview, LyXText::NEED_MORE_REFRESH);
// check the special right address boxes
- if (textclasslist[bview->buffer()->params.textclass][
- par->layout()].margintype
- == MARGIN_RIGHT_ADDRESS_BOX)
- {
+ if (par->layout()->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
tmpcursor.par(par);
tmpcursor.row(row);
tmpcursor.y(y);
cur.pos(pos);
cur.boundary(boundary);
-#if 0
- if (pos && par->getChar(pos) == Paragraph::META_INSET &&
- par->getInset(pos)) {
- Inset * ins = par->getInset(pos);
- if (ins->needFullRow() || ins->display()) {
- --pos;
- boundary = true;
- }
- }
-#endif
-
// get the cursor y position in text
int y = 0;
Row * row = getRow(par, pos, y);
+ Row * old_row = row;
+ cur.irow(row);
+ // if we are before the first char of this row and are still in the
+ // same paragraph and there is a previous row then put the cursor on
+ // the end of the previous row
+ cur.iy(y + row->baseline());
+ Inset * ins;
+ if (row->previous() && pos &&
+ row->previous()->par() == row->par() &&
+ par->getChar(pos) == Paragraph::META_INSET &&
+ (ins=par->getInset(pos)) && (ins->needFullRow() || ins->display()))
+ {
+ row = row->previous();
+ y -= row->height();
+ }
+
+ cur.row(row);
// y is now the beginning of the cursor row
y += row->baseline();
// y is now the cursor baseline
cur.y(y);
- // now get the cursors x position
- float x;
- float fill_separator;
- float fill_hfill;
- float fill_label_hfill;
- prepareToPrint(bview, row, x, fill_separator, fill_hfill,
- fill_label_hfill);
- pos_type cursor_vpos = 0;
- pos_type last = rowLastPrintable(row);
+ pos_type last = rowLastPrintable(old_row);
if (pos > last + 1) {
// This shouldn't happen.
cur.pos(pos);
}
+ // now get the cursors x position
+ float x = getCursorX(bview, row, pos, last, boundary);
+ cur.x(int(x));
+ cur.x_fix(cur.x());
+ if (old_row != row) {
+ x = getCursorX(bview, old_row, pos, last, boundary);
+ cur.ix(int(x));
+ } else
+ cur.ix(cur.x());
+}
+
+
+float LyXText::getCursorX(BufferView * bview, Row * row,
+ pos_type pos, pos_type last, bool boundary) const
+{
+ pos_type cursor_vpos = 0;
+ float x;
+ float fill_separator;
+ float fill_hfill;
+ float fill_label_hfill;
+ // This call HAS to be here because of the BidiTables!!!
+ prepareToPrint(bview, row, x, fill_separator, fill_hfill,
+ fill_label_hfill);
+
if (last < row->pos())
cursor_vpos = row->pos();
else if (pos > last && !boundary)
main_body = 0;
for (pos_type vpos = row->pos(); vpos < cursor_vpos; ++vpos) {
- pos = vis2log(vpos);
+ pos_type pos = vis2log(vpos);
if (main_body > 0 && pos == main_body - 1) {
x += fill_label_hfill +
- lyxfont::width(textclasslist[
- bview->buffer()->params.textclass][
- row->par()->layout()]
- .labelsep,
- getLabelFont(bview->buffer(), row->par()));
- if (row->par()->isLineSeparator(main_body-1))
- x -= singleWidth(bview, row->par(),main_body-1);
+ font_metrics::width(
+ row->par()->layout()->labelsep,
+ getLabelFont(bview->buffer(),
+ row->par()));
+ if (row->par()->isLineSeparator(main_body - 1))
+ x -= singleWidth(bview,
+ row->par(), main_body - 1);
}
if (hfillExpansion(bview->buffer(), row, pos)) {
x += singleWidth(bview, row->par(), pos);
} else
x += singleWidth(bview, row->par(), pos);
}
-
- cur.x(int(x));
- cur.x_fix(cur.x());
- cur.row(row);
+ return x;
}
cur.x(x);
cur.y(y + row->baseline());
cur.row(row);
+ Inset * ins;
+ if (row->next() && row->next()->pos() == cur.pos() &&
+ cur.par() == row->next()->par() &&
+ cur.par()->getChar(cur.pos()) == Paragraph::META_INSET &&
+ (ins=cur.par()->getInset(cur.pos())) &&
+ (ins->needFullRow() || ins->display()))
+ {
+ // we enter here if we put the cursor on the end of the row before
+ // a inset which uses a full row and in that case we HAVE to calculate
+ // the right (i) values.
+ pos_type last = rowLastPrintable(row);
+ float x = getCursorX(bview, row->next(), cur.pos(), last, bound);
+ cur.ix(int(x));
+ cur.iy(y + row->height() + row->next()->baseline());
+ cur.irow(row->next());
+ } else {
+ cur.iy(cur.y());
+ cur.ix(cur.x());
+ cur.irow(row);
+ }
cur.boundary(bound);
}
}
-void LyXText::cursorUp(BufferView * bview) const
+void LyXText::cursorUp(BufferView * bview, bool selecting) const
{
+#if 1
+ int x = cursor.x_fix();
+ int y = cursor.y() - cursor.row()->baseline() - 1;
+ setCursorFromCoordinates(bview, x, y);
+ if (!selecting) {
+ int y1 = cursor.iy() - first_y;
+ int y2 = y1;
+ y -= first_y;
+ Inset * inset_hit =
+ bview->checkInsetHit(const_cast<LyXText *>(this), x, y1);
+ if (inset_hit && isHighlyEditableInset(inset_hit)) {
+ inset_hit->edit(bview, x, y - (y2 - y1), mouse_button::none);
+ }
+ }
+#else
setCursorFromCoordinates(bview, cursor.x_fix(),
cursor.y() - cursor.row()->baseline() - 1);
+#endif
}
-void LyXText::cursorDown(BufferView * bview) const
+void LyXText::cursorDown(BufferView * bview, bool selecting) const
{
+#if 1
+ int x = cursor.x_fix();
+ int y = cursor.y() - cursor.row()->baseline() +
+ cursor.row()->height() + 1;
+ setCursorFromCoordinates(bview, x, y);
+ if (!selecting && cursor.row() == cursor.irow()) {
+ int y1 = cursor.iy() - first_y;
+ int y2 = y1;
+ y -= first_y;
+ Inset * inset_hit =
+ bview->checkInsetHit(const_cast<LyXText *>(this), x, y1);
+ if (inset_hit && isHighlyEditableInset(inset_hit)) {
+ inset_hit->edit(bview, x, y - (y2 - y1), mouse_button::none);
+ }
+ }
+#else
setCursorFromCoordinates(bview, cursor.x_fix(),
cursor.y() - cursor.row()->baseline()
+ cursor.row()->height() + 1);
+#endif
}
if (cur.pos() > where.pos())
cur.pos(cur.pos()-1);
+ // check also if we don't want to set the cursor on a spot behind the
+ // pagragraph because we erased the last character.
+ if (cur.pos() > cur.par()->size())
+ cur.pos(cur.par()->size());
+
// recompute row et al. for this cursor
setCursor(bview, cur, cur.par(), cur.pos(), cur.boundary());
}
return false;
// We allow all kinds of "mumbo-jumbo" when freespacing.
- if (textclasslist[bview->buffer()->params.textclass][
- old_cursor.par()->layout()].free_spacing
- || old_cursor.par()->isFreeSpacing())
- {
+ if (old_cursor.par()->layout()->free_spacing
+ || old_cursor.par()->isFreeSpacing()) {
return false;
}
return false;
// Do not delete empty paragraphs with keepempty set.
- if (textclasslist
- [bview->buffer()->params.textclass]
- [old_cursor.par()->layout()].keepempty)
+ if (old_cursor.par()->layout()->keepempty)
return false;
// only do our magic if we changed paragraph
}
}
if (!deleted) {
- if (old_cursor.par()->stripLeadingSpaces(bview->buffer()->params.textclass)) {
+ if (old_cursor.par()->stripLeadingSpaces()) {
redoParagraphs(bview, old_cursor,
old_cursor.par()->next());
// correct cursor y
void LyXText::status(BufferView * bview, LyXText::text_status st) const
{
- // well as much as I know && binds more then || so the above and the
- // below are identical (this for your known use of parentesis!)
- // Now some explanation:
// We should only go up with refreshing code so this means that if
// we have a MORE refresh we should never set it to LITTLE if we still
// didn't handle it (and then it will be UNCHANGED. Now as long as