X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext2.C;h=04d3b35de579343b146223feab67e59ef4ff1887;hb=55ef679c8b8fdad62f45944b75d997d274c6ac47;hp=bec3b8529fa38f46f456b4e3c8c6fb4c4a6fa862;hpb=a5e70bd5efcd8b44cd5c2021068ee734a8649577;p=lyx.git diff --git a/src/text2.C b/src/text2.C index bec3b8529f..04d3b35de5 100644 --- a/src/text2.C +++ b/src/text2.C @@ -17,23 +17,22 @@ #include "lyxtext.h" #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" #include "FloatList.h" #include "language.h" #include "ParagraphParameters.h" +#include "counters.h" #include "insets/inseterror.h" #include "insets/insetbib.h" @@ -47,7 +46,6 @@ using std::vector; using std::copy; -using std::find; using std::endl; using std::find; using std::pair; @@ -121,6 +119,7 @@ LyXFont const realizeFont(LyXFont const & font, Buffer const * buf, Paragraph * par) { + LyXTextClass const & tclass = buf->params.getLyXTextClass(); LyXFont tmpfont(font); Paragraph::depth_type par_depth = par->getDepth(); @@ -129,12 +128,9 @@ LyXFont const realizeFont(LyXFont const & font, 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, + tmpfont.realize(tclass[par->layout()]->font, buf->params.language); #endif par_depth = par->getDepth(); @@ -142,10 +138,9 @@ LyXFont const realizeFont(LyXFont const & font, } #ifndef INHERIT_LANGUAGE - tmpfont.realize(textclasslist[buf->params.textclass].defaultfont()); + tmpfont.realize(tclass.defaultfont()); #else - tmpfont.realize(textclasslist[buf->params.textclass].defaultfont(), - buf->params.language); + tmpfont.realize(tclass.defaultfont(), buf->params.language); #endif return tmpfont; @@ -166,20 +161,18 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par, { 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 (!par->getDepth()) { + 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 @@ -188,7 +181,7 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par, 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 @@ -201,10 +194,10 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par, 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); @@ -222,31 +215,25 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par, 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; + if (!par->getDepth()) { + 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; + if (!par->getDepth()) { + return layout->reslabelfont; } - return realizeFont(layout.labelfont, buf, par); + return realizeFont(layout->labelfont, buf, par); } @@ -277,16 +264,16 @@ void LyXText::setCharFont(Buffer const * buf, Paragraph * par, { LyXFont font(fnt); - LyXTextClass const & tclass = textclasslist[buf->params.textclass]; - LyXLayout const & layout = tclass[par->layout()]; + LyXTextClass const & tclass = buf->params.getLyXTextClass(); + 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()) { @@ -295,11 +282,9 @@ void LyXText::setCharFont(Buffer const * buf, Paragraph * par, 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, - tp->layout()).font, + layoutfont.realize(tclass[tp->layout()].font, buf->params.language); #endif } @@ -398,7 +383,7 @@ void LyXText::insertParagraph(BufferView * bview, Paragraph * par, Row * row) const { insertRow(row, par, 0); /* insert a new row, starting - * at postition 0 */ + * at position 0 */ setCounter(bview->buffer(), par); // set the counters @@ -436,6 +421,7 @@ void LyXText::toggleInset(BufferView * bview) && inset_owner->owner()->isOpen()) { bview->unlockInset(static_cast(inset_owner->owner())); inset_owner->owner()->close(bview); + bview->getLyXText()->cursorRight(bview); } return; } @@ -461,15 +447,14 @@ void LyXText::toggleInset(BufferView * bview) 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); @@ -503,22 +488,22 @@ Paragraph * LyXText::setLayout(BufferView * bview, Paragraph * par = sstart_cur.par(); Paragraph * epar = send_cur.par()->next(); - LyXLayout const & lyxlayout = - textclasslist[bview->buffer()->params.textclass][layout]; + LyXLayout_ptr const & lyxlayout = + bview->buffer()->params.getLyXTextClass()[layout]; do { - par->applyLayout(layout); + par->applyLayout(lyxlayout); makeFontEntriesLayoutSpecific(bview->buffer(), par); Paragraph * fppar = par; - fppar->params().spaceTop(lyxlayout.fill_top ? + 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) - 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; @@ -552,7 +537,7 @@ void LyXText::setLayout(BufferView * bview, string const & layout) selection.start.pos(), false); selection.cursor = cursor; setCursor(bview, selection.end.par(), selection.end.pos(), false); - updateCounters(bview, cursor.row()); + updateCounters(bview); clearSelection(); setSelection(bview); setCursor(bview, tmpcursor.par(), tmpcursor.pos(), true); @@ -594,17 +579,14 @@ void LyXText::incDepth(BufferView * bview) 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; } @@ -632,7 +614,7 @@ void LyXText::incDepth(BufferView * bview) setCursor(bview, selection.start.par(), selection.start.pos()); selection.cursor = cursor; setCursor(bview, selection.end.par(), selection.end.pos()); - updateCounters(bview, cursor.row()); + updateCounters(bview); clearSelection(); setSelection(bview); setCursor(bview, tmpcursor.par(), tmpcursor.pos()); @@ -689,7 +671,7 @@ void LyXText::decDepth(BufferView * bview) selection.start.pos()); selection.cursor = cursor; setCursor(bview, selection.end.par(), selection.end.pos()); - updateCounters(bview, cursor.row()); + updateCounters(bview); clearSelection(); setSelection(bview); setCursor(bview, tmpcursor.par(), tmpcursor.pos()); @@ -739,11 +721,10 @@ void LyXText::setFont(BufferView * bview, LyXFont const & font, bool toggleall) 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); @@ -897,30 +878,30 @@ void LyXText::redoParagraphs(BufferView * bview, LyXCursor const & cur, if (tmprow && tmprow->next()) setHeightOfRow(bview, tmprow->next()); + updateCounters(bview); } -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) @@ -983,30 +964,26 @@ string const LyXText::selectionAsString(Buffer const * buffer, bool label) const { if (!selection.set()) return string(); - string result; - // Special handling if the whole selection is within one paragraph - if (selection.start.par() == selection.end.par()) { - result += selection.start.par()->asString(buffer, - selection.start.pos(), - selection.end.pos(), - label); - return result; + // should be const ... + Paragraph * startpar(selection.start.par()); + Paragraph * endpar(selection.end.par()); + pos_type const startpos(selection.start.pos()); + pos_type const endpos(selection.end.pos()); + + if (startpar == endpar) { + return startpar->asString(buffer, startpos, endpos, label); } - // The selection spans more than one paragraph + string result; // First paragraph in selection - result += selection.start.par()->asString(buffer, - selection.start.pos(), - selection.start.par()->size(), - label) - + "\n\n"; + result += startpar->asString(buffer, startpos, startpar->size(), label) + "\n\n"; // The paragraphs in between (if any) LyXCursor tmpcur(selection.start); tmpcur.par(tmpcur.par()->next()); - while (tmpcur.par() != selection.end.par()) { + while (tmpcur.par() != endpar) { result += tmpcur.par()->asString(buffer, 0, tmpcur.par()->size(), label) + "\n\n"; @@ -1014,8 +991,7 @@ string const LyXText::selectionAsString(Buffer const * buffer, } // Last paragraph in selection - result += selection.end.par()->asString(buffer, 0, - selection.end.pos(), label); + result += endpar->asString(buffer, 0, endpos, label); return result; } @@ -1044,7 +1020,7 @@ void LyXText::cursorEnd(BufferView * bview) const || cursor.row()->next()->par() != cursor.row()->par()) { setCursor(bview, cursor.par(), rowLast(cursor.row()) + 1); } else { - if (cursor.par()->size() && + if (!cursor.par()->empty() && (cursor.par()->getChar(rowLast(cursor.row())) == ' ' || cursor.par()->isNewline(rowLast(cursor.row())))) { setCursor(bview, cursor.par(), rowLast(cursor.row())); @@ -1113,8 +1089,8 @@ string LyXText::getStringToIndex(BufferView * bview) // Try implicit word selection // If there is a change in the language the implicit word selection // is disabled. - LyXCursor resetCursor = cursor; - bool implicitSelection = selectWordWhenUnderCursor(bview, PREVIOUS_WORD); + LyXCursor const reset_cursor = cursor; + bool const implicitSelection = selectWordWhenUnderCursor(bview, PREVIOUS_WORD); if (!selection.set()) { bview->owner()->message(_("Nothing to index!")); @@ -1131,7 +1107,7 @@ string LyXText::getStringToIndex(BufferView * bview) //and cursor is set to the original position. if (implicitSelection) { clearSelection(); - cursor = resetCursor; + cursor = reset_cursor; setCursor(bview, cursor.par(), cursor.pos()); selection.cursor = cursor; } @@ -1139,22 +1115,21 @@ string LyXText::getStringToIndex(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, @@ -1191,8 +1166,6 @@ void LyXText::setParagraph(BufferView * bview, Paragraph * tmppar = selection.end.par(); - LyXTextClass const & tclass = - textclasslist[bview->buffer()->params.textclass]; while (tmppar != selection.start.par()->previous()) { setCursor(bview, tmppar, 0); @@ -1207,12 +1180,12 @@ void LyXText::setParagraph(BufferView * bview, 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); @@ -1235,86 +1208,22 @@ void LyXText::setParagraph(BufferView * bview, } -char loweralphaCounter(int n) -{ - if (n < 1 || n > 26) - return '?'; - else - return 'a' + n - 1; -} - - -namespace { - -inline -char alphaCounter(int n) -{ - if (n < 1 || n > 26) - return '?'; - else - return 'A' + n - 1; -} - - -inline -char hebrewCounter(int n) -{ - static const char hebrew[22] = { - 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', - 'é', 'ë', 'ì', 'î', 'ð', 'ñ', 'ò', 'ô', 'ö', - '÷', 'ø', 'ù', 'ú' - }; - if (n < 1 || n > 22) - return '?'; - else - return hebrew[n-1]; -} - - -inline -string const romanCounter(int n) -{ - static char const * roman[20] = { - "i", "ii", "iii", "iv", "v", - "vi", "vii", "viii", "ix", "x", - "xi", "xii", "xiii", "xiv", "xv", - "xvi", "xvii", "xviii", "xix", "xx" - }; - if (n < 1 || n > 20) - return "??"; - else - return roman[n-1]; -} - -} // namespace anon - - // set the counter of a paragraph. This includes the labels void LyXText::setCounter(Buffer const * buf, Paragraph * par) const { - LyXTextClass const & textclass = textclasslist[buf->params.textclass]; - LyXLayout const & layout = textclass[par->layout()]; + LyXTextClass const & textclass = buf->params.getLyXTextClass(); + LyXLayout_ptr const & layout = par->layout(); - - // copy the prev-counters to this one, - // unless this is the first paragraph if (par->previous()) { - for (int i = 0; i < 10; ++i) { - par->setCounter(i, par->previous()->getFirstCounter(i)); - } + par->params().appendix(par->previous()->params().appendix()); if (!par->params().appendix() && par->params().startOfAppendix()) { par->params().appendix(true); - for (int i = 0; i < 10; ++i) { - par->setCounter(i, 0); - } + buf->counters().reset(); } par->enumdepth = par->previous()->enumdepth; par->itemdepth = par->previous()->itemdepth; } else { - for (int i = 0; i < 10; ++i) { - par->setCounter(i, 0); - } par->params().appendix(par->params().startOfAppendix()); par->enumdepth = 0; par->itemdepth = 0; @@ -1329,269 +1238,127 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const */ 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 - */ - for (int i = 6 + par->enumdepth + 1; i < 10; ++i) - par->setCounter(i, 0); } if (!par->params().labelString().empty()) { 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; + string numbertype, langtype; + ostringstream s; - int i = layout.labeltype - LABEL_COUNTER_CHAPTER; if (i >= 0 && i<= buf->params.secnumdepth) { - par->incCounter(i); // increment the counter + + buf->counters().step(buf->counters().sects[i]); // 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()); } - ostringstream s; - + // Use if an integer is here less than elegant. For now. + int head = textclass.maxcounter() - LABEL_COUNTER_CHAPTER; if (!par->params().appendix()) { - switch (2 * LABEL_COUNTER_CHAPTER - - textclass.maxcounter() + i) { - case LABEL_COUNTER_CHAPTER: - s << par->getCounter(i); - break; - case LABEL_COUNTER_SECTION: - s << par->getCounter(i - 1) << '.' - << par->getCounter(i); - break; - case LABEL_COUNTER_SUBSECTION: - s << par->getCounter(i - 2) << '.' - << par->getCounter(i - 1) << '.' - << par->getCounter(i); - break; - case LABEL_COUNTER_SUBSUBSECTION: - s << par->getCounter(i - 3) << '.' - << par->getCounter(i - 2) << '.' - << par->getCounter(i - 1) << '.' - << par->getCounter(i); - - break; - case LABEL_COUNTER_PARAGRAPH: - s << par->getCounter(i - 4) << '.' - << par->getCounter(i - 3) << '.' - << par->getCounter(i - 2) << '.' - << par->getCounter(i - 1) << '.' - << par->getCounter(i); - break; - case LABEL_COUNTER_SUBPARAGRAPH: - s << par->getCounter(i - 5) << '.' - << par->getCounter(i - 4) << '.' - << par->getCounter(i - 3) << '.' - << par->getCounter(i - 2) << '.' - << par->getCounter(i - 1) << '.' - << par->getCounter(i); - - break; - default: - // Can this ever be reached? And in the - // case it is, how can this be correct? - // (Lgb) - s << par->getCounter(i) << '.'; - break; - } - } else { // appendix - switch (2 * LABEL_COUNTER_CHAPTER - textclass.maxcounter() + i) { - case LABEL_COUNTER_CHAPTER: - if (par->isRightToLeftPar(buf->params)) - s << hebrewCounter(par->getCounter(i)); - else - s << alphaCounter(par->getCounter(i)); - break; - case LABEL_COUNTER_SECTION: - if (par->isRightToLeftPar(buf->params)) - s << hebrewCounter(par->getCounter(i - 1)); - else - s << alphaCounter(par->getCounter(i - 1)); - - s << '.' - << par->getCounter(i); - - break; - case LABEL_COUNTER_SUBSECTION: - if (par->isRightToLeftPar(buf->params)) - s << hebrewCounter(par->getCounter(i - 2)); - else - s << alphaCounter(par->getCounter(i - 2)); - - s << '.' - << par->getCounter(i-1) << '.' - << par->getCounter(i); - - break; - case LABEL_COUNTER_SUBSUBSECTION: - if (par->isRightToLeftPar(buf->params)) - s << hebrewCounter(par->getCounter(i-3)); - else - s << alphaCounter(par->getCounter(i-3)); - - s << '.' - << par->getCounter(i-2) << '.' - << par->getCounter(i-1) << '.' - << par->getCounter(i); - - break; - case LABEL_COUNTER_PARAGRAPH: - if (par->isRightToLeftPar(buf->params)) - s << hebrewCounter(par->getCounter(i-4)); - else - s << alphaCounter(par->getCounter(i-4)); - - s << '.' - << par->getCounter(i-3) << '.' - << par->getCounter(i-2) << '.' - << par->getCounter(i-1) << '.' - << par->getCounter(i); - - break; - case LABEL_COUNTER_SUBPARAGRAPH: - if (par->isRightToLeftPar(buf->params)) - s << hebrewCounter(par->getCounter(i-5)); - else - s << alphaCounter(par->getCounter(i-5)); - - s << '.' - << par->getCounter(i-4) << '.' - << par->getCounter(i-3) << '.' - << par->getCounter(i-2) << '.' - << par->getCounter(i-1) << '.' - << par->getCounter(i); - - break; - default: - // Can this ever be reached? And in the - // case it is, how can this be correct? - // (Lgb) - s << par->getCounter(i) << '.'; - - break; - } + numbertype = "sectioning"; + } else { + numbertype = "appendix"; + if (par->isRightToLeftPar(buf->params)) + langtype = "hebrew"; + else + langtype = "latin"; } - par->params().labelString(par->params().labelString() +s.str().c_str()); + s << buf->counters().numberLabel(buf->counters().sects[i], + numbertype, langtype, head); + + par->params().labelString(par->params().labelString() + s.str().c_str()); // We really want to remove the c_str as soon as // possible... - for (i++; i < 10; ++i) { - // reset the following counters - par->setCounter(i, 0); - } - } 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) { - par->incCounter(i + par->enumdepth); - int number = par->getCounter(i + par->enumdepth); - - ostringstream s; - - switch (par->enumdepth) { - case 1: - if (par->isRightToLeftPar(buf->params)) - s << '(' - << hebrewCounter(number) - << ')'; - else - s << '(' - << loweralphaCounter(number) - << ')'; - break; - case 2: - if (par->isRightToLeftPar(buf->params)) - s << '.' << romanCounter(number); - else - s << romanCounter(number) << '.'; - break; - case 3: - if (par->isRightToLeftPar(buf->params)) - s << '.' - << alphaCounter(number); - else - s << alphaCounter(number) - << '.'; - break; - default: - if (par->isRightToLeftPar(buf->params)) - s << '.' << number; - else - s << number << '.'; - break; - } + // reset enum counters + buf->counters().reset("enum"); + } else if (layout->labeltype < LABEL_COUNTER_ENUMI) { + buf->counters().reset("enum"); + } else if (layout->labeltype == LABEL_COUNTER_ENUMI) { + buf->counters().step(buf->counters().enums[par->enumdepth]); + s << buf->counters().numberLabel(buf->counters().enums[par->enumdepth], + "enumeration", langtype); par->params().labelString(s.str().c_str()); - for (i += par->enumdepth + 1; i < 10; ++i) { - // reset the following counters - par->setCounter(i, 0); - } - } - } 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); + } else if (layout->labeltype == LABEL_BIBLIO) {// ale970302 + buf->counters().step("bibitem"); + int number = buf->counters().value("bibitem"); if (!par->bibkey) { InsetCommandParams p("bibitem" ); 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) { - bool isOK (par->inInset() && par->inInset()->owner() && - (par->inInset()->owner()->lyxCode() == Inset::FLOAT_CODE)); + if (layout->labeltype == LABEL_SENSITIVE) { + Paragraph * tmppar = par; + Inset * in = 0; + bool isOK = false; + while (tmppar && tmppar->inInset() + // the single '=' is intended below + && (in = tmppar->inInset()->owner())) { + if (in->lyxCode() == Inset::FLOAT_CODE) { + isOK = true; + break; + } else { + tmppar = in->parOwner(); + } + } if (isOK) { - InsetFloat * tmp = static_cast(par->inInset()->owner()); Floating const & fl - = floatList.getType(tmp->type()); - // We should get the correct number here too. - s = fl.name() + " #:"; + = floatList.getType(static_cast(in)->type()); + + buf->counters().step(fl.name()); + + // Doesn't work... yet. + ostringstream o; + //o << fl.name() << " " << buf->counters().value(fl.name()) << ":"; + o << fl.name() << " #:"; + s = o.str(); } else { /* par->SetLayout(0); s = layout->labelstring; */ @@ -1603,39 +1370,35 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const /* reset the enumeration counter. They are always resetted * when there is any other layout between */ - for (int i = 6 + par->enumdepth; i < 10; ++i) - par->setCounter(i, 0); + for (int i = par->enumdepth + 1; i < 4; i++) { + buf->counters().set(buf->counters().enums[i], 0); + } } } // Updates all counters BEHIND the row. Changed paragraphs // with a dynamic left margin will be rebroken. -void LyXText::updateCounters(BufferView * bview, Row * row) const +void LyXText::updateCounters(BufferView * bview) const { Paragraph * par; + + Row * row = firstrow; + par = row->par(); - if (!row) { - row = firstrow; - par = row->par(); - } else { - par = row->par()->next(); - } - + bview->buffer()->counters().reset(); while (par) { while (row->par() != par) row = row->next(); - + setCounter(bview->buffer(), par); // 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); @@ -1669,7 +1432,7 @@ void LyXText::insertInset(BufferView * bview, Inset * inset) void LyXText::copyEnvironmentType() { - copylayouttype = cursor.par()->layout(); + copylayouttype = cursor.par()->layout()->name(); } @@ -1741,7 +1504,7 @@ void LyXText::cutSelection(BufferView * bview, bool doclear, bool realcut) // sometimes necessary if (doclear) - selection.start.par()->stripLeadingSpaces(bview->buffer()->params.textclass); + selection.start.par()->stripLeadingSpaces(); redoParagraphs(bview, selection.start, endpar); @@ -1754,7 +1517,7 @@ void LyXText::cutSelection(BufferView * bview, bool doclear, bool realcut) setCursor(bview, cursor.par(), cursor.pos()); selection.cursor = cursor; - updateCounters(bview, cursor.row()); + updateCounters(bview); } @@ -1807,7 +1570,7 @@ void LyXText::pasteSelection(BufferView * bview) selection.cursor = cursor; setCursor(bview, actpar, pos); setSelection(bview); - updateCounters(bview, cursor.row()); + updateCounters(bview); } @@ -1976,10 +1739,7 @@ void LyXText::checkParagraph(BufferView * bview, Paragraph * par, 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); @@ -2073,6 +1833,7 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par, 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())) { @@ -2119,7 +1880,7 @@ float LyXText::getCursorX(BufferView * bview, Row * row, 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); + fill_label_hfill); if (last < row->pos()) cursor_vpos = row->pos(); @@ -2147,13 +1908,13 @@ float LyXText::getCursorX(BufferView * bview, Row * row, 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); @@ -2254,6 +2015,30 @@ void LyXText::setCursorFromCoordinates(BufferView * bview, int x, int y) const } +namespace { + + /** + * return true if the cursor given is at the end of a row, + * and the next row is filled by an inset that spans an entire + * row. + */ + bool beforeFullRowInset(Row & row, LyXCursor & cur) { + if (!row.next()) + return false; + Row const & next = *row.next(); + + if (next.pos() != cur.pos() || next.par() != cur.par()) + return false; + if (!cur.par()->isInset(cur.pos())) + return false; + Inset const * inset = cur.par()->getInset(cur.pos()); + if (inset->needFullRow() || inset->display()) + return true; + return false; + } +} + + void LyXText::setCursorFromCoordinates(BufferView * bview, LyXCursor & cur, int x, int y) const { @@ -2267,16 +2052,8 @@ void LyXText::setCursorFromCoordinates(BufferView * bview, LyXCursor & cur, 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. + + if (beforeFullRowInset(*row, cur)) { pos_type last = rowLastPrintable(row); float x = getCursorX(bview, row->next(), cur.pos(), last, bound); cur.ix(int(x)); @@ -2334,7 +2111,7 @@ void LyXText::cursorUp(BufferView * bview, bool selecting) const Inset * inset_hit = bview->checkInsetHit(const_cast(this), x, y1); if (inset_hit && isHighlyEditableInset(inset_hit)) { - inset_hit->edit(bview, x, y - (y2 - y1), 0); + inset_hit->edit(bview, x, y - (y2 - y1), mouse_button::none); } } #else @@ -2351,14 +2128,14 @@ void LyXText::cursorDown(BufferView * bview, bool selecting) const int y = cursor.y() - cursor.row()->baseline() + cursor.row()->height() + 1; setCursorFromCoordinates(bview, x, y); - if (!selecting) { + 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(this), x, y1); if (inset_hit && isHighlyEditableInset(inset_hit)) { - inset_hit->edit(bview, x, y - (y2 - y1), 0); + inset_hit->edit(bview, x, y - (y2 - y1), mouse_button::none); } } #else @@ -2405,6 +2182,11 @@ void LyXText::fixCursorAfterDelete(BufferView * bview, 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()); } @@ -2418,10 +2200,8 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview, 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; } @@ -2487,9 +2267,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview, 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 @@ -2500,7 +2278,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview, // we can't possibly have deleted a paragraph before this point bool deleted = false; - if ((old_cursor.par()->size() == 0 + if ((old_cursor.par()->empty() || (old_cursor.par()->size() == 1 && old_cursor.par()->isLineSeparator(0)))) { // ok, we will delete anything @@ -2538,7 +2316,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview, * there is another layout before */ if (refresh_row->next()) { breakAgain(bview, refresh_row->next()); - updateCounters(bview, refresh_row); + updateCounters(bview); } setHeightOfRow(bview, refresh_row); } else { @@ -2571,7 +2349,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview, there is another layout before */ if (refresh_row) { breakAgain(bview, refresh_row); - updateCounters(bview, refresh_row->previous()); + updateCounters(bview); } } @@ -2585,7 +2363,7 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview, } } 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 @@ -2597,34 +2375,12 @@ bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview, } -void LyXText::toggleAppendix(BufferView * bview) -{ - Paragraph * par = cursor.par(); - bool start = !par->params().startOfAppendix(); - - // ensure that we have only one start_of_appendix in this document - Paragraph * tmp = ownerParagraph(); - for (; tmp; tmp = tmp->next()) { - tmp->params().startOfAppendix(false); - } - - par->params().startOfAppendix(start); - - // we can set the refreshing parameters now - status(bview, LyXText::NEED_MORE_REFRESH); - refresh_y = 0; - refresh_row = 0; // not needed for full update - updateCounters(bview, 0); - setCursor(bview, cursor.par(), cursor.pos()); -} - - Paragraph * LyXText::ownerParagraph() const { if (inset_owner) { return inset_owner->paragraph(); } - return bv_owner->buffer()->paragraph; + return &*(bv_owner->buffer()->paragraphs.begin()); } @@ -2633,7 +2389,7 @@ void LyXText::ownerParagraph(Paragraph * p) const if (inset_owner) { inset_owner->paragraph(p); } else { - bv_owner->buffer()->paragraph = p; + bv_owner->buffer()->paragraphs.set(p); } } @@ -2657,9 +2413,8 @@ LyXText::text_status LyXText::status() const 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: + LyXText * t = bview->text; + // 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 @@ -2670,17 +2425,14 @@ void LyXText::status(BufferView * bview, LyXText::text_status st) const // tell'em that it should redraw the actual row (where the inset // resides! Capito?! - if ((status_ != NEED_MORE_REFRESH) - || (status_ == NEED_MORE_REFRESH - && st != NEED_VERY_LITTLE_REFRESH)) - { + if (status_ != NEED_MORE_REFRESH || st != NEED_VERY_LITTLE_REFRESH) { status_ = st; if (inset_owner && st != UNCHANGED) { - bview->text->status(bview, NEED_VERY_LITTLE_REFRESH); - if (!bview->text->refresh_row) { - bview->text->refresh_row = bview->text->cursor.row(); - bview->text->refresh_y = bview->text->cursor.y() - - bview->text->cursor.row()->baseline(); + t->status(bview, NEED_VERY_LITTLE_REFRESH); + if (!t->refresh_row) { + t->refresh_row = t->cursor.row(); + t->refresh_y = t->cursor.y() - + t->cursor.row()->baseline(); } } }