X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext2.C;h=04d3b35de579343b146223feab67e59ef4ff1887;hb=55ef679c8b8fdad62f45944b75d997d274c6ac47;hp=658db776c069c0894783cf8c36da396a17006910;hpb=b2ea4c019dd6535787631f47ab31c99283e9ccc3;p=lyx.git diff --git a/src/text2.C b/src/text2.C index 658db776c0..04d3b35de5 100644 --- a/src/text2.C +++ b/src/text2.C @@ -32,6 +32,7 @@ #include "FloatList.h" #include "language.h" #include "ParagraphParameters.h" +#include "counters.h" #include "insets/inseterror.h" #include "insets/insetbib.h" @@ -45,7 +46,6 @@ using std::vector; using std::copy; -using std::find; using std::endl; using std::find; using std::pair; @@ -163,9 +163,8 @@ LyXFont const LyXText::getFont(Buffer const * buf, Paragraph * par, LyXLayout_ptr const & layout = par->layout(); - Paragraph::depth_type par_depth = par->getDepth(); // We specialize the 95% common case: - if (!par_depth) { + if (!par->getDepth()) { if (layout->labeltype == LABEL_MANUAL && pos < beginningOfMainBody(buf, par)) { // 1% goes here @@ -218,9 +217,7 @@ LyXFont const LyXText::getLayoutFont(Buffer const * buf, Paragraph * par) const { LyXLayout_ptr const & layout = par->layout(); - Paragraph::depth_type par_depth = par->getDepth(); - - if (!par_depth) { + if (!par->getDepth()) { return layout->resfont; } @@ -232,9 +229,7 @@ LyXFont const LyXText::getLabelFont(Buffer const * buf, Paragraph * par) const { LyXLayout_ptr const & layout = par->layout(); - Paragraph::depth_type par_depth = par->getDepth(); - - if (!par_depth) { + if (!par->getDepth()) { return layout->reslabelfont; } @@ -388,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 @@ -542,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); @@ -619,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()); @@ -676,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()); @@ -883,6 +878,7 @@ void LyXText::redoParagraphs(BufferView * bview, LyXCursor const & cur, if (tmprow && tmprow->next()) setHeightOfRow(bview, tmprow->next()); + updateCounters(bview); } @@ -968,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"; @@ -999,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; } @@ -1029,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())); @@ -1098,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!")); @@ -1116,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; } @@ -1217,85 +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 = 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; @@ -1321,11 +1249,6 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const && par->previous()->getDepth() > par->getDepth() && 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()) { @@ -1344,8 +1267,12 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const if (layout->labeltype >= LABEL_COUNTER_CHAPTER) { int i = layout->labeltype - LABEL_COUNTER_CHAPTER; + string numbertype, langtype; + ostringstream s; + 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()) { @@ -1360,195 +1287,40 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const 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); - } + // reset enum counters + buf->counters().reset("enum"); } else if (layout->labeltype < LABEL_COUNTER_ENUMI) { - for (i++; i < 10; ++i) { - // reset the following counters - par->setCounter(i, 0); - } + buf->counters().reset("enum"); } 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; - } + 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); + buf->counters().step("bibitem"); + int number = buf->counters().value("bibitem"); if (!par->bibkey) { InsetCommandParams p("bibitem" ); par->bibkey = new InsetBibKey(p); @@ -1562,15 +1334,31 @@ void LyXText::setCounter(Buffer const * buf, Paragraph * par) const // the caption hack: if (layout->labeltype == LABEL_SENSITIVE) { - bool isOK (par->inInset() && par->inInset()->owner() && - (par->inInset()->owner()->lyxCode() == Inset::FLOAT_CODE)); + 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; */ @@ -1582,29 +1370,27 @@ 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 @@ -1731,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); } @@ -1784,7 +1570,7 @@ void LyXText::pasteSelection(BufferView * bview) selection.cursor = cursor; setCursor(bview, actpar, pos); setSelection(bview); - updateCounters(bview, cursor.row()); + updateCounters(bview); } @@ -2229,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 { @@ -2242,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)); @@ -2476,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 @@ -2514,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 { @@ -2547,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); } } @@ -2573,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()); } @@ -2609,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); } } @@ -2634,7 +2414,7 @@ LyXText::text_status LyXText::status() const void LyXText::status(BufferView * bview, LyXText::text_status st) const { 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