X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FText.cpp;h=0bb66f6666e46ee6bf69fe89390cc9cb2df3ac15;hb=6a21ec854b356fbbc89aaf99b2a23e4c3de4aca6;hp=e1c37faf3ab2700376d70f2d2f2e0ca2b4e3fc8a;hpb=9fe8190364d27a538efa3928d2166b09e1cef2d5;p=lyx.git diff --git a/src/Text.cpp b/src/Text.cpp index e1c37faf3a..0bb66f6666 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -22,51 +22,44 @@ #include "Author.h" #include "Buffer.h" -#include "buffer_funcs.h" #include "BufferParams.h" #include "BufferView.h" #include "Changes.h" #include "CompletionList.h" #include "Cursor.h" +#include "CursorSlice.h" #include "CutAndPaste.h" #include "DispatchResult.h" #include "Encoding.h" #include "ErrorList.h" -#include "FuncRequest.h" #include "factory.h" -#include "InsetList.h" +#include "Font.h" #include "Language.h" #include "Layout.h" -#include "Length.h" #include "Lexer.h" #include "lyxfind.h" #include "LyXRC.h" #include "Paragraph.h" #include "ParagraphParameters.h" -#include "ParIterator.h" #include "TextClass.h" #include "TextMetrics.h" -#include "WordLangTuple.h" +#include "Undo.h" #include "WordList.h" +#include "insets/Inset.h" #include "insets/InsetText.h" -#include "insets/InsetBibitem.h" #include "insets/InsetCaption.h" -#include "insets/InsetNewline.h" -#include "insets/InsetNewpage.h" -#include "insets/InsetArgument.h" #include "insets/InsetIPAMacro.h" -#include "insets/InsetSpace.h" #include "insets/InsetSpecialChar.h" #include "insets/InsetTabular.h" #include "support/convert.h" #include "support/debug.h" #include "support/docstream.h" +#include "support/docstring.h" #include "support/gettext.h" #include "support/lassert.h" #include "support/lstrings.h" -#include "support/lyxalgo.h" #include "support/lyxtime.h" #include "support/textutils.h" #include "support/unique_ptr.h" @@ -113,8 +106,7 @@ void breakParagraphConservative(BufferParams const & bparams, ParagraphList & pars, pit_type pit, pos_type pos) { // create a new paragraph - Paragraph & tmp = *pars.insert(lyx::next(pars.begin(), pit + 1), - Paragraph()); + Paragraph & tmp = *pars.insert(pars.iterator_at(pit + 1), Paragraph()); Paragraph & par = pars[pit]; tmp.setInsetOwner(&par.inInset()); @@ -169,7 +161,7 @@ void mergeParagraph(BufferParams const & bparams, // move the change of the end-of-paragraph character par.setChange(par.size(), change); - pars.erase(lyx::next(pars.begin(), par_offset + 1)); + pars.erase(pars.iterator_at(par_offset + 1)); } @@ -190,10 +182,8 @@ Text::Text(InsetText * owner, bool use_default_layout) Text::Text(InsetText * owner, Text const & text) : owner_(owner), pars_(text.pars_) { - ParagraphList::iterator const end = pars_.end(); - ParagraphList::iterator it = pars_.begin(); - for (; it != end; ++it) - it->setInsetOwner(owner); + for (auto & p : pars_) + p.setInsetOwner(owner); } @@ -288,6 +278,35 @@ Font const Text::outerFont(pit_type par_offset) const } +int Text::getEndLabel(pit_type p) const +{ + pit_type pit = p; + depth_type par_depth = pars_[p].getDepth(); + while (pit != pit_type(pars_.size())) { + Layout const & layout = pars_[pit].layout(); + int const endlabeltype = layout.endlabeltype; + + if (endlabeltype != END_LABEL_NO_LABEL) { + if (p + 1 == pit_type(pars_.size())) + return endlabeltype; + + depth_type const next_depth = + pars_[p + 1].getDepth(); + if (par_depth > next_depth || + (par_depth == next_depth && layout != pars_[p + 1].layout())) + return endlabeltype; + break; + } + if (par_depth == 0) + break; + pit = outerHook(pit); + if (pit != pit_type(pars_.size())) + par_depth = pars_[pit].getDepth(); + } + return END_LABEL_NO_LABEL; +} + + static void acceptOrRejectChanges(ParagraphList & pars, BufferParams const & bparams, Text::ChangeOp op) { @@ -445,6 +464,9 @@ void Text::readParToken(Paragraph & par, Lexer & lex, } else if (token == "\\numeric") { lex.next(); font.fontInfo().setNumber(setLyXMisc(lex.getString())); + } else if (token == "\\nospellcheck") { + lex.next(); + font.fontInfo().setNoSpellcheck(setLyXMisc(lex.getString())); } else if (token == "\\emph") { lex.next(); font.fontInfo().setEmph(setLyXMisc(lex.getString())); @@ -590,7 +612,8 @@ void Text::readParagraph(Paragraph & par, Lexer & lex, } } // Final change goes to paragraph break: - par.setChange(par.size(), change); + if (inset().allowMultiPar()) + par.setChange(par.size(), change); // Initialize begin_of_body_ on load; redoParagraph maintains par.setBeginOfBody(); @@ -611,14 +634,14 @@ public: virtual ~TextCompletionList() {} /// - virtual bool sorted() const { return true; } + bool sorted() const override { return true; } /// - virtual size_t size() const + size_t size() const override { return list_.size(); } /// - virtual docstring const & data(size_t idx) const + docstring const & data(size_t idx) const override { return list_.word(idx); } @@ -661,8 +684,7 @@ static void breakParagraph(Text & text, pit_type par_offset, pos_type pos, ParagraphList & pars = text.paragraphs(); // create a new paragraph, and insert into the list ParagraphList::iterator tmp = - pars.insert(lyx::next(pars.begin(), par_offset + 1), - Paragraph()); + pars.insert(pars.iterator_at(par_offset + 1), Paragraph()); Paragraph & par = pars[par_offset]; @@ -693,6 +715,7 @@ static void breakParagraph(Text & text, pit_type par_offset, pos_type pos, tmp->params().depth(par.params().depth()); tmp->params().noindent(par.params().noindent()); + tmp->params().spacing(par.params().spacing()); // move everything behind the break position // to the new paragraph @@ -836,12 +859,18 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str, pit_type pit = cur.pit(); pos_type pos = cur.pos(); + // The special chars we handle + map specialchars; + specialchars[0x200c] = InsetSpecialChar::LIGATURE_BREAK; + specialchars[0x200b] = InsetSpecialChar::ALLOWBREAK; + specialchars[0x2026] = InsetSpecialChar::LDOTS; + specialchars[0x2011] = InsetSpecialChar::NOBREAKDASH; + // insert the string, don't insert doublespace bool space_inserted = true; - for (docstring::const_iterator cit = str.begin(); - cit != str.end(); ++cit) { + for (auto const & ch : str) { Paragraph & par = pars_[pit]; - if (*cit == '\n') { + if (ch == '\n') { if (inset().allowMultiPar() && (!par.empty() || par.allowEmpty())) { lyx::breakParagraph(*this, pit, pos, par.layout().isEnvironment()); @@ -852,28 +881,35 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str, continue; } // do not insert consecutive spaces if !free_spacing - } else if ((*cit == ' ' || *cit == '\t') && + } else if ((ch == ' ' || ch == '\t') && space_inserted && !par.isFreeSpacing()) { continue; - } else if (*cit == '\t') { + } else if (ch == '\t') { if (!par.isFreeSpacing()) { // tabs are like spaces here par.insertChar(pos, ' ', font, bparams.track_changes); ++pos; space_inserted = true; } else { - par.insertChar(pos, *cit, font, bparams.track_changes); + par.insertChar(pos, ch, font, bparams.track_changes); ++pos; space_inserted = true; } - } else if (!isPrintable(*cit)) { - // Ignore unprintables + } else if (specialchars.find(ch) != specialchars.end()) { + par.insertInset(pos, new InsetSpecialChar(specialchars.find(ch)->second), + font, bparams.track_changes ? + Change(Change::INSERTED) + : Change(Change::UNCHANGED)); + ++pos; + space_inserted = false; + } else if (!isPrintable(ch)) { + // Ignore (other) unprintables continue; } else { // just insert the character - par.insertChar(pos, *cit, font, bparams.track_changes); + par.insertChar(pos, ch, font, bparams.track_changes); ++pos; - space_inserted = (*cit == ' '); + space_inserted = (ch == ' '); } } setCursor(cur, pit, pos); @@ -922,8 +958,8 @@ bool canInsertChar(Cursor const & cur, char_type c) "beginning of a paragraph. Please read the Tutorial.")); return false; } - // LASSERT: Is it safe to continue here? - LASSERT(cur.pos() > 0, /**/); + // If something is wrong, ignore this character. + LASSERT(cur.pos() > 0, return false); if ((par.isLineSeparator(cur.pos() - 1) || par.isNewline(cur.pos() - 1)) && !par.isDeleted(cur.pos() - 1)) { cur.message(_( @@ -933,15 +969,12 @@ bool canInsertChar(Cursor const & cur, char_type c) } } - // Prevent to insert uncodable characters in verbatim and ERT - // (workaround for bug 9012) - // Don't do it for listings inset, since InsetListings::latex() tries - // to switch to a usable encoding which works in many cases (bug 9102). - if (par.isPassThru() && cur.inset().lyxCode() != LISTINGS_CODE && - cur.current_font.language()) { - Encoding const * e = cur.current_font.language()->encoding(); + // Prevent to insert uncodable characters in verbatim and ERT. + // The encoding is inherited from the context here. + if (par.isPassThru() && cur.getEncoding()) { + Encoding const * e = cur.getEncoding(); if (!e->encodable(c)) { - cur.message(_("Character is uncodable in verbatim paragraphs.")); + cur.message(_("Character is uncodable in this verbatim context.")); return false; } } @@ -971,14 +1004,19 @@ void Text::insertChar(Cursor & cur, char_type c) if (lyxrc.auto_number) { static docstring const number_operators = from_ascii("+-/*"); static docstring const number_unary_operators = from_ascii("+-"); - static docstring const number_separators = from_ascii(".,:"); + // Common Number Separators: comma, dot etc. + // European Number Terminators: percent, permille, degree, euro etc. if (cur.current_font.fontInfo().number() == FONT_ON) { if (!isDigitASCII(c) && !contains(number_operators, c) && - !(contains(number_separators, c) && + !(isCommonNumberSeparator(c) && cur.pos() != 0 && cur.pos() != cur.lastpos() && tm.displayFont(pit, cur.pos()).fontInfo().number() == FONT_ON && + tm.displayFont(pit, cur.pos() - 1).fontInfo().number() == FONT_ON) && + !(isEuropeanNumberTerminator(c) && + cur.pos() != 0 && + tm.displayFont(pit, cur.pos()).fontInfo().number() == FONT_ON && tm.displayFont(pit, cur.pos() - 1).fontInfo().number() == FONT_ON) ) number(cur); // Set current_font.number to OFF @@ -987,8 +1025,8 @@ void Text::insertChar(Cursor & cur, char_type c) number(cur); // Set current_font.number to ON if (cur.pos() != 0) { - char_type const c = par.getChar(cur.pos() - 1); - if (contains(number_unary_operators, c) && + char_type const ch = par.getChar(cur.pos() - 1); + if (contains(number_unary_operators, ch) && (cur.pos() == 1 || par.isSeparator(cur.pos() - 2) || par.isEnvSeparator(cur.pos() - 2) @@ -996,7 +1034,7 @@ void Text::insertChar(Cursor & cur, char_type c) ) { setCharFont(pit, cur.pos() - 1, cur.current_font, tm.font_); - } else if (contains(number_separators, c) + } else if (isCommonNumberSeparator(ch) && cur.pos() >= 2 && tm.displayFont(pit, cur.pos() - 2).fontInfo().number() == FONT_ON) { setCharFont(pit, cur.pos() - 1, cur.current_font, @@ -1089,7 +1127,7 @@ void Text::charInserted(Cursor & cur) && par.isWordSeparator(cur.pos() - 1)) { // get the word in front of cursor LBUFERR(this == cur.text()); - cur.paragraph().updateWords(); + par.updateWords(); } } @@ -1101,30 +1139,53 @@ bool Text::cursorForwardOneWord(Cursor & cur) { LBUFERR(this == cur.text()); - pos_type const lastpos = cur.lastpos(); - pit_type pit = cur.pit(); - pos_type pos = cur.pos(); - Paragraph const & par = cur.paragraph(); - - // Paragraph boundary is a word boundary - if (pos == lastpos || (pos + 1 == lastpos && par.isEnvSeparator(pos))) { - if (pit != cur.lastpit()) - return setCursor(cur, pit + 1, 0); - else - return false; - } - if (lyxrc.mac_like_cursor_movement) { - // Skip through trailing punctuation and spaces. - while (pos != lastpos && (par.isChar(pos) || par.isSpace(pos))) - ++pos; - - // Skip over either a non-char inset or a full word - if (pos != lastpos && par.isWordSeparator(pos)) - ++pos; - else while (pos != lastpos && !par.isWordSeparator(pos)) - ++pos; + DocIterator dit(cur); + DocIterator prv(cur); + bool inword = false; + bool intext = dit.inTexted(); + while (!dit.atEnd()) { + if (dit.inTexted()) { // no paragraphs in mathed + Paragraph const & par = dit.paragraph(); + pos_type const pos = dit.pos(); + + if (!par.isDeleted(pos)) { + bool wordsep = par.isWordSeparator(pos); + if (inword && wordsep) + break; // stop at word end + else if (!inword && !wordsep) + inword = true; + } + intext = true; + } else if (intext) { + // move to end of math + while (!dit.inTexted() && !dit.atEnd()) dit.forwardPos(); + break; + } + prv = dit; + dit.forwardPosIgnoreCollapsed(); + } + if (dit.atEnd()) dit = prv; + if (dit == cur) return false; // we didn't move + Cursor orig(cur); + cur.setCursor(dit); + // see comment above + cur.bv().checkDepm(cur, orig); + return true; } else { + pos_type const lastpos = cur.lastpos(); + pit_type pit = cur.pit(); + pos_type pos = cur.pos(); + Paragraph const & par = cur.paragraph(); + + // Paragraph boundary is a word boundary + if (pos == lastpos || (pos + 1 == lastpos && par.isEnvSeparator(pos))) { + if (pit != cur.lastpit()) + return setCursor(cur, pit + 1, 0); + else + return false; + } + LASSERT(pos < lastpos, return false); // see above if (!par.isWordSeparator(pos)) while (pos != lastpos && !par.isWordSeparator(pos)) @@ -1138,13 +1199,13 @@ bool Text::cursorForwardOneWord(Cursor & cur) // Skip over white space while (pos != lastpos && par.isSpace(pos)) ++pos; - } - // Don't skip a separator inset at the end of a paragraph - if (pos == lastpos && pos && par.isEnvSeparator(pos - 1)) - --pos; + // Don't skip a separator inset at the end of a paragraph + if (pos == lastpos && pos && par.isEnvSeparator(pos - 1)) + --pos; - return setCursor(cur, pit, pos); + return setCursor(cur, pit, pos); + } } @@ -1152,34 +1213,55 @@ bool Text::cursorBackwardOneWord(Cursor & cur) { LBUFERR(this == cur.text()); - pit_type pit = cur.pit(); - pos_type pos = cur.pos(); - Paragraph & par = cur.paragraph(); - - // Paragraph boundary is a word boundary - if (pos == 0 && pit != 0) { - Paragraph & prevpar = getPar(pit - 1); - pos = prevpar.size(); - // Don't stop after an environment separator - if (pos && prevpar.isEnvSeparator(pos - 1)) - --pos; - return setCursor(cur, pit - 1, pos); - } - if (lyxrc.mac_like_cursor_movement) { - // Skip through punctuation and spaces. - while (pos != 0 && (par.isChar(pos - 1) || par.isSpace(pos - 1))) - --pos; - - // Skip over either a non-char inset or a full word - if (pos != 0 && par.isWordSeparator(pos - 1) && !par.isChar(pos - 1)) - --pos; - else while (pos != 0 && !par.isWordSeparator(pos - 1)) - --pos; + DocIterator dit(cur); + bool inword = false; + bool intext = dit.inTexted(); + while (!dit.atBegin()) { + DocIterator prv(dit); + dit.backwardPosIgnoreCollapsed(); + if (dit.inTexted()) { // no paragraphs in mathed + Paragraph const & par = dit.paragraph(); + pos_type pos = dit.pos(); + + if (!par.isDeleted(pos)) { + bool wordsep = par.isWordSeparator(pos); + if (inword && wordsep) { + dit = prv; + break; // stop at word begin + } else if (!inword && !wordsep) + inword = true; + } + intext = true; + } else if (intext) { + // move to begin of math + while (!dit.inTexted() && !dit.atBegin()) dit.backwardPos(); + break; + } + } + if (dit == cur) return false; // we didn't move + Cursor orig(cur); + cur.setCursor(dit); + // see comment above cursorForwardOneWord + cur.bv().checkDepm(cur, orig); + return true; } else { + Paragraph const & par = cur.paragraph(); + pit_type const pit = cur.pit(); + pos_type pos = cur.pos(); + + // Paragraph boundary is a word boundary + if (pos == 0 && pit != 0) { + Paragraph & prevpar = getPar(pit - 1); + pos = prevpar.size(); + // Don't stop after an environment separator + if (pos && prevpar.isEnvSeparator(pos - 1)) + --pos; + return setCursor(cur, pit - 1, pos); + } // Skip over white space while (pos != 0 && par.isSpace(pos - 1)) - --pos; + --pos; if (pos != 0 && !par.isWordSeparator(pos - 1)) while (pos != 0 && !par.isWordSeparator(pos - 1)) @@ -1189,9 +1271,9 @@ bool Text::cursorBackwardOneWord(Cursor & cur) --pos; else if (pos != 0 && !par.isSpace(pos - 1)) // non-char inset --pos; - } - return setCursor(cur, pit, pos); + return setCursor(cur, pit, pos); + } } @@ -1336,7 +1418,7 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op) pos_type endPos = cur.selectionEnd().pos(); // keep selection info, because endPos becomes invalid after the first loop - bool endsBeforeEndOfPar = (endPos < pars_[endPit].size()); + bool const endsBeforeEndOfPar = (endPos < pars_[endPit].size()); // first, accept/reject changes within each individual paragraph (do not consider end-of-par) for (pit_type pit = begPit; pit <= endPit; ++pit) { @@ -1355,8 +1437,8 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op) if (pit == endPit && endPos == 0) break; // last iteration anyway - pos_type left = (pit == begPit ? begPos : 0); - pos_type right = (pit == endPit ? endPos : parSize); + pos_type const left = (pit == begPit ? begPos : 0); + pos_type const right = (pit == endPit ? endPos : parSize); if (left == right) // there is no change here @@ -1479,7 +1561,7 @@ void Text::deleteWordForward(Cursor & cur, bool const force) cursorForwardOneWord(cur); cur.setSelection(); if (force || !cur.confirmDeletion()) { - cutSelection(cur, true, false); + cutSelection(cur, false); cur.checkBufferStructure(); } } @@ -1497,7 +1579,7 @@ void Text::deleteWordBackward(Cursor & cur, bool const force) cursorBackwardOneWord(cur); cur.setSelection(); if (force || !cur.confirmDeletion()) { - cutSelection(cur, true, false); + cutSelection(cur, false); cur.checkBufferStructure(); } } @@ -1640,10 +1722,7 @@ bool Text::backspacePos0(Cursor & cur) if (cur.pit() == 0) return false; - bool needsUpdate = false; - BufferParams const & bufparams = cur.buffer()->params(); - DocumentClass const & tclass = bufparams.documentClass(); ParagraphList & plist = cur.text()->paragraphs(); Paragraph const & par = cur.paragraph(); Cursor prevcur = cur; @@ -1655,35 +1734,29 @@ bool Text::backspacePos0(Cursor & cur) if (cur.lastpos() == 0 || (cur.lastpos() == 1 && par.isSeparator(0))) { cur.recordUndo(prevcur.pit()); - plist.erase(lyx::next(plist.begin(), cur.pit())); - needsUpdate = true; + plist.erase(plist.iterator_at(cur.pit())); } // is previous par empty? else if (prevcur.lastpos() == 0 || (prevcur.lastpos() == 1 && prevpar.isSeparator(0))) { cur.recordUndo(prevcur.pit()); - plist.erase(lyx::next(plist.begin(), prevcur.pit())); - needsUpdate = true; + plist.erase(plist.iterator_at(prevcur.pit())); } + // FIXME: Do we really not want to allow this??? // Pasting is not allowed, if the paragraphs have different // layouts. I think it is a real bug of all other // word processors to allow it. It confuses the user. // Correction: Pasting is always allowed with standard-layout // or the empty layout. - else if (par.layout() == prevpar.layout() - || tclass.isDefaultLayout(par.layout()) - || tclass.isPlainLayout(par.layout())) { + else { cur.recordUndo(prevcur.pit()); mergeParagraph(bufparams, plist, prevcur.pit()); - needsUpdate = true; } - if (needsUpdate) { - cur.forceBufferUpdate(); - setCursorIntern(cur, prevcur.pit(), prevcur.pos()); - } + cur.forceBufferUpdate(); + setCursorIntern(cur, prevcur.pit(), prevcur.pos()); - return needsUpdate; + return true; } @@ -1698,7 +1771,8 @@ bool Text::backspace(Cursor & cur) Cursor prev_cur = cur; --prev_cur.pit(); - if (!prev_cur.paragraph().isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) { + if (!cur.paragraph().empty() + && !prev_cur.paragraph().isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) { cur.recordUndo(prev_cur.pit(), prev_cur.pit()); prev_cur.paragraph().setChange(prev_cur.lastpos(), Change(Change::DELETED)); setCursorIntern(cur, prev_cur.pit(), prev_cur.lastpos()); @@ -1732,7 +1806,7 @@ bool Text::backspace(Cursor & cur) needsUpdate |= handleBibitems(cur); // A singlePar update is not enough in this case. -// cur.screenUpdateFlags(Update::Force); + // cur.screenUpdateFlags(Update::Force); cur.top().setPitPos(cur.pit(), cur.pos()); return needsUpdate; @@ -1752,9 +1826,7 @@ bool Text::dissolveInset(Cursor & cur) // save position inside inset pos_type spos = cur.pos(); pit_type spit = cur.pit(); - ParagraphList plist; - if (cur.lastpit() != 0 || cur.lastpos() != 0) - plist = paragraphs(); + bool const inset_non_empty = cur.lastpit() != 0 || cur.lastpos() != 0; cur.popBackward(); // update cursor offset if (spit == 0) @@ -1767,7 +1839,8 @@ bool Text::dissolveInset(Cursor & cur) ++cur.pos(); Buffer & b = *cur.buffer(); - if (!plist.empty()) { + // Is there anything in this text? + if (inset_non_empty) { // see bug 7319 // we clear the cache so that we won't get conflicts with labels // that get pasted into the buffer. we should update this before @@ -1777,13 +1850,29 @@ bool Text::dissolveInset(Cursor & cur) // but we'll try the cheaper solution here. cur.buffer()->clearReferenceCache(); + ParagraphList & plist = paragraphs(); + if (!lyxrc.ct_markup_copied) + // Do not revive deleted text + lyx::acceptChanges(plist, b.params()); + // ERT paragraphs have the Language latex_language. // This is invalid outside of ERT, so we need to // change it to the buffer language. - ParagraphList::iterator it = plist.begin(); - ParagraphList::iterator it_end = plist.end(); - for (; it != it_end; ++it) - it->changeLanguage(b.params(), latex_language, b.language()); + for (auto & p : plist) + p.changeLanguage(b.params(), latex_language, b.language()); + + /* If the inset is the only thing in paragraph and the layout + * is not plain, then the layout of the first paragraph of + * inset should be remembered. + * FIXME: this does not work as expected when change tracking + * is on However, we do not really know what to do in this + * case. + */ + DocumentClass const & tclass = cur.buffer()->params().documentClass(); + if (inset_it.lastpos() == 1 + && !tclass.isPlainLayout(plist[0].layout()) + && !tclass.isDefaultLayout(plist[0].layout())) + cur.paragraph().makeSameLayout(plist[0]); pasteParagraphList(cur, plist, b.params().documentClassPtr(), b.errorList("Paste")); @@ -1895,8 +1984,8 @@ bool Text::read(Lexer & lex, } -// Returns the current font and depth as a message. -docstring Text::currentState(Cursor const & cur, bool devel_mode) const +// Returns the current state (font, depth etc.) as a message for status bar. +docstring Text::currentState(CursorData const & cur, bool devel_mode) const { LBUFERR(this == cur.text()); Buffer & buf = *cur.buffer(); @@ -1925,7 +2014,7 @@ docstring Text::currentState(Cursor const & cur, bool devel_mode) const os << bformat(_("Font: %1$s"), font.stateText(&buf.params())); // The paragraph depth - int depth = cur.paragraph().getDepth(); + int depth = par.getDepth(); if (depth > 0) os << bformat(_(", Depth: %1$d"), depth); @@ -1953,8 +2042,15 @@ docstring Text::currentState(Cursor const & cur, bool devel_mode) const } } + // Custom text style + InsetLayout const & layout = cur.inset().getLayout(); + if (layout.lyxtype() == InsetLayout::CHARSTYLE) + os << _(", Style: ") << translateIfPossible(layout.labelstring()); + if (devel_mode) { os << _(", Inset: ") << &cur.inset(); + if (cur.lastidx() > 0) + os << _(", Cell: ") << cur.idx(); os << _(", Paragraph: ") << cur.pit(); os << _(", Id: ") << par.id(); os << _(", Position: ") << cur.pos(); @@ -1973,14 +2069,46 @@ docstring Text::currentState(Cursor const & cur, bool devel_mode) const } -docstring Text::getPossibleLabel(Cursor const & cur) const +docstring Text::getPossibleLabel(DocIterator const & cur) const { - pit_type pit = cur.pit(); + pit_type textpit = cur.pit(); + Layout const * layout = &(pars_[textpit].layout()); + + // Will contain the label prefix. + docstring name; - Layout const * layout = &(pars_[pit].layout()); + // For captions, we just take the caption type + Inset * caption_inset = cur.innerInsetOfType(CAPTION_CODE); + if (caption_inset) { + string const & ftype = static_cast(caption_inset)->floattype(); + FloatList const & fl = cur.buffer()->params().documentClass().floats(); + if (fl.typeExist(ftype)) { + Floating const & flt = fl.getType(ftype); + name = from_utf8(flt.refPrefix()); + } + if (name.empty()) + name = from_utf8(ftype.substr(0,3)); + } else { + // For section, subsection, etc... + if (layout->latextype == LATEX_PARAGRAPH && textpit != 0) { + Layout const * layout2 = &(pars_[textpit - 1].layout()); + if (layout2->latextype != LATEX_PARAGRAPH) { + --textpit; + layout = layout2; + } + } + if (layout->latextype != LATEX_PARAGRAPH) + name = layout->refprefix; + + // If none of the above worked, see if the inset knows. + if (name.empty()) { + InsetLayout const & il = cur.inset().getLayout(); + name = il.refprefix(); + } + } docstring text; - docstring par_text = pars_[pit].asString(); + docstring par_text = pars_[textpit].asString(AS_STR_SKIPDELETE); // The return string of math matrices might contain linebreaks par_text = subst(par_text, '\n', '-'); @@ -2001,46 +2129,13 @@ docstring Text::getPossibleLabel(Cursor const & cur) const if (text.size() > max_label_length) text.resize(max_label_length); - // Will contain the label prefix. - docstring name; - - // For section, subsection, etc... - if (layout->latextype == LATEX_PARAGRAPH && pit != 0) { - Layout const * layout2 = &(pars_[pit - 1].layout()); - if (layout2->latextype != LATEX_PARAGRAPH) { - --pit; - layout = layout2; - } - } - if (layout->latextype != LATEX_PARAGRAPH) - name = layout->refprefix; - - // For captions, we just take the caption type - Inset * caption_inset = cur.innerInsetOfType(CAPTION_CODE); - if (caption_inset) { - string const & ftype = static_cast(caption_inset)->floattype(); - FloatList const & fl = cur.buffer()->params().documentClass().floats(); - if (fl.typeExist(ftype)) { - Floating const & flt = fl.getType(ftype); - name = from_utf8(flt.refPrefix()); - } - if (name.empty()) - name = from_utf8(ftype.substr(0,3)); - } - - // If none of the above worked, see if the inset knows. - if (name.empty()) { - InsetLayout const & il = cur.inset().getLayout(); - name = il.refprefix(); - } - if (!name.empty()) text = name + ':' + text; // We need a unique label docstring label = text; int i = 1; - while (cur.buffer()->insetLabel(label)) { + while (cur.buffer()->activeLabel(label)) { label = text + '-' + convert(i); ++i; } @@ -2176,23 +2271,11 @@ void Text::setMacrocontextPosition(DocIterator const & pos) } -docstring Text::previousWord(CursorSlice const & sl) const -{ - CursorSlice from = sl; - CursorSlice to = sl; - getWord(from, to, PREVIOUS_WORD); - if (sl == from || to == from) - return docstring(); - - Paragraph const & par = sl.paragraph(); - return par.asString(from.pos(), to.pos()); -} - - bool Text::completionSupported(Cursor const & cur) const { Paragraph const & par = cur.paragraph(); - return cur.pos() > 0 + return !cur.selection() + && cur.pos() > 0 && (cur.pos() >= par.size() || par.isWordSeparator(cur.pos())) && !par.isWordSeparator(cur.pos() - 1); } @@ -2218,7 +2301,11 @@ bool Text::insertCompletion(Cursor & cur, docstring const & s, bool /*finished*/ docstring Text::completionPrefix(Cursor const & cur) const { - return previousWord(cur.top()); + CursorSlice from = cur.top(); + CursorSlice to = from; + getWord(from, to, PREVIOUS_WORD); + + return cur.paragraph().asString(from.pos(), to.pos()); } } // namespace lyx