]> git.lyx.org Git - lyx.git/blobdiff - src/Text3.cpp
Russian layouttranslations reviewed by Yuriy, Dec 13 2017.
[lyx.git] / src / Text3.cpp
index fbcd9b7206a2dd4f0c51810fcabce05af22dc925..305a1d28b21b1640a8d5e43c741fec00fed1a4c6 100644 (file)
@@ -53,7 +53,7 @@
 #include "frontends/Selection.h"
 
 #include "insets/InsetArgument.h"
-#include "insets/InsetCollapsable.h"
+#include "insets/InsetCollapsible.h"
 #include "insets/InsetCommand.h"
 #include "insets/InsetExternal.h"
 #include "insets/InsetFloat.h"
@@ -78,7 +78,7 @@
 #include "support/regex.h"
 
 #include "mathed/InsetMathHull.h"
-#include "mathed/MathMacroTemplate.h"
+#include "mathed/InsetMathMacroTemplate.h"
 
 #include <clocale>
 #include <sstream>
@@ -90,13 +90,16 @@ namespace lyx {
 
 using cap::copySelection;
 using cap::cutSelection;
+using cap::cutSelectionToTemp;
 using cap::pasteFromStack;
+using cap::pasteFromTemp;
 using cap::pasteClipboardText;
 using cap::pasteClipboardGraphics;
 using cap::replaceSelection;
 using cap::grabAndEraseSelection;
 using cap::selClearOrDel;
 using cap::pasteSimpleText;
+using frontend::Clipboard;
 
 // globals...
 static Font freefont(ignore_font, ignore_language);
@@ -178,7 +181,7 @@ static void mathDispatch(Cursor & cur, FuncRequest const & cmd)
                        LASSERT(cur.inMathed(), return);
                        cur.pos() = 0;
                        cur.resetAnchor();
-                       cur.setSelection(true);
+                       cur.selection(true);
                        cur.pos() = cur.lastpos();
                        if (cmd.action() != LFUN_MATH_MODE)
                                // LFUN_MATH_MODE has a different meaning in math mode
@@ -242,7 +245,7 @@ static bool doInsertInset(Cursor & cur, Text * text,
        if (!inset)
                return false;
 
-       if (InsetCollapsable * ci = inset->asInsetCollapsable())
+       if (InsetCollapsible * ci = inset->asInsetCollapsible())
                ci->setButtonLabel();
 
        cur.recordUndo();
@@ -298,7 +301,7 @@ static bool doInsertInset(Cursor & cur, Text * text,
 
        bool gotsel = false;
        if (cur.selection()) {
-               cutSelection(cur, false, pastesel);
+               cutSelectionToTemp(cur, false, pastesel);
                cur.clearSelection();
                gotsel = true;
        }
@@ -310,7 +313,7 @@ static bool doInsertInset(Cursor & cur, Text * text,
        if (!gotsel || !pastesel)
                return true;
 
-       pasteFromStack(cur, cur.buffer()->errorList("Paste"), 0);
+       pasteFromTemp(cur, cur.buffer()->errorList("Paste"));
        cur.buffer()->errors("Paste");
        cur.clearSelection(); // bug 393
        cur.finishUndo();
@@ -449,7 +452,7 @@ static void outline(OutlineOp mode, Cursor & cur)
                                DocumentClass const & tc = buf.params().documentClass();
                                DocumentClass::const_iterator lit = tc.begin();
                                DocumentClass::const_iterator len = tc.end();
-                               int const newtoclevel = 
+                               int const newtoclevel =
                                        (mode == OutlineIn ? toclevel + 1 : toclevel - 1);
                                LabelType const oldlabeltype = start->layout().labeltype;
 
@@ -481,14 +484,14 @@ bool Text::isRTL(Paragraph const & par) const
        return par.isRTL(buffer.params());
 }
 
-       
+
 namespace {
-               
+
        Language const * getLanguage(Cursor const & cur, string const & lang) {
                return lang.empty() ? cur.getFont().language() : languages.getLanguage(lang);
        }
 
-}
+} // namespace
 
 
 void Text::dispatch(Cursor & cur, FuncRequest & cmd)
@@ -515,7 +518,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        cur.noScreenUpdate();
 
        LBUFERR(this == cur.text());
-       
+
        // NOTE: This should NOT be a reference. See commit 94a5481a.
        CursorSlice const oldTopSlice = cur.top();
        bool const oldBoundary = cur.boundary();
@@ -583,7 +586,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                if (cur.selection())
                        cutSelection(cur, true, false);
                else
-                       deleteWordForward(cur);
+                       deleteWordForward(cur, cmd.getArg(0) == "force");
                finishChange(cur, false);
                break;
 
@@ -591,7 +594,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                if (cur.selection())
                        cutSelection(cur, true, false);
                else
-                       deleteWordBackward(cur);
+                       deleteWordBackward(cur, cmd.getArg(0) == "force");
                finishChange(cur, false);
                break;
 
@@ -767,6 +770,18 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        cur.upDownInText(up, needsUpdate);
                        needsUpdate |= cur.beforeDispatchCursor().inMathed();
                } else {
+                       pos_type newpos = up ? 0 : cur.lastpos();
+                       if (lyxrc.mac_like_cursor_movement && cur.pos() != newpos) {
+                               needsUpdate |= cur.selHandle(select);
+                               // we do not reset the targetx of the cursor
+                               cur.pos() = newpos;
+                               needsUpdate |= bv->checkDepm(cur, bv->cursor());
+                               cur.updateTextTargetOffset();
+                               if (needsUpdate)
+                                       cur.forceBufferUpdate();
+                               break;
+                       }
+
                        // if the cursor cannot be moved up or down do not remove
                        // the selection right now, but wait for the next dispatch.
                        if (select)
@@ -832,6 +847,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                break;
                }
                cur.pos() = cur.lastpos();
+               cur.boundary(false);
+               cur.setCurrentFont();
 
                needsUpdate |= cur != old_cur;
                break;
@@ -1051,6 +1068,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        if (cur.pos() == cur.paragraph().size())
                                // Par boundary, force full-screen update
                                singleParUpdate = false;
+                       else if (cmd.getArg(0) != "force" && cur.confirmDeletion()) {
+                               cur.resetAnchor();
+                               cur.selection(true);
+                               cur.posForward();
+                               cur.setSelection();
+                               break;
+                       }
                        needsUpdate |= erase(cur);
                        cur.resetAnchor();
                } else {
@@ -1068,6 +1092,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                // Par boundary, full-screen update
                                if (par_boundary)
                                        singleParUpdate = false;
+                               else if (cmd.getArg(0) != "force" && cur.confirmDeletion(true)) {
+                                       cur.resetAnchor();
+                                       cur.selection(true);
+                                       cur.posBackward();
+                                       cur.setSelection();
+                                       break;
+                               }
                                needsUpdate |= backspace(cur);
                                cur.resetAnchor();
                                if (par_boundary && !first_par && cur.pos() > 0
@@ -1088,13 +1119,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                Paragraph const & par = pars_[pit];
                bool lastpar = (pit == pit_type(pars_.size() - 1));
                Paragraph const & nextpar = lastpar ? par : pars_[pit + 1];
-               pit_type prev = pit;
-               if (pit > 0) {
-                       if (!pars_[pit - 1].layout().isEnvironment())
-                               prev = depthHook(pit, par.getDepth());
-                       else if (pars_[pit - 1].getDepth() >= par.getDepth())
-                               prev = pit - 1;
-               }
+               pit_type prev = pit > 0 ? depthHook(pit, par.getDepth()) : pit;
                if (prev < pit && cur.pos() == par.beginOfBody()
                    && !par.size() && !par.isEnvSeparator(cur.pos())
                    && !par.layout().isCommand()
@@ -1216,6 +1241,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                }
 
                ins->setParams(inspar);
+               break;
        }
 
        case LFUN_SPACE_INSERT:
@@ -1232,6 +1258,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                string const name = to_utf8(cmd.argument());
                if (name == "hyphenation")
                        specialChar(cur, InsetSpecialChar::HYPHENATION);
+               else if (name == "allowbreak")
+                       specialChar(cur, InsetSpecialChar::ALLOWBREAK);
                else if (name == "ligature-break")
                        specialChar(cur, InsetSpecialChar::LIGATURE_BREAK);
                else if (name == "slash")
@@ -1551,26 +1579,44 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                while (pos > 0 && par.isDeleted(pos - 1))
                        --pos;
 
-               BufferParams const & bufparams = bv->buffer().params();
-               bool const hebrew =
-                       par.getFontSettings(bufparams, pos).language()->lang() == "hebrew";
-               bool const allow_inset_quote = !(par.isPassThru() || hebrew);
-
-               string const arg = to_utf8(cmd.argument());
-               if (allow_inset_quote) {
-                       char_type c = ' ';
-                       if (pos > 0 && (!cur.prevInset() || !cur.prevInset()->isSpace()))
+               bool const inner = (cmd.getArg(0) == "single" || cmd.getArg(0) == "inner");
+
+               // Guess quote side.
+               // A space triggers an opening quote. This is passed if the preceding
+               // char/inset is a space or at paragraph start.
+               char_type c = ' ';
+               if (pos > 0 && !par.isSpace(pos - 1)) {
+                       if (cur.prevInset() && cur.prevInset()->lyxCode() == QUOTE_CODE) {
+                               // If an opening double quotation mark precedes, and this
+                               // is a single quote, make it opening as well
+                               InsetQuotes & ins =
+                                       static_cast<InsetQuotes &>(*cur.prevInset());
+                               string const type = ins.getType();
+                               if (!suffixIs(type, "ld") || !inner)
+                                       c = par.getChar(pos - 1);
+                       }
+                       else if (!cur.prevInset()
+                           || (cur.prevInset() && cur.prevInset()->isChar()))
+                               // If a char precedes, pass that and let InsetQuote decide
                                c = par.getChar(pos - 1);
-                       InsetQuotes::QuoteTimes const quote_type = (arg == "single")
-                               ? InsetQuotes::SingleQuotes : InsetQuotes::DoubleQuotes;
-                       cur.insert(new InsetQuotes(cur.buffer(), c, quote_type));
-                       cur.posForward();
-               } else {
-                       // The cursor might have been invalidated by the replaceSelection.
-                       cur.buffer()->changed(true);
-                       string const quote_string = (arg == "single") ? "'" : "\"";
-                       lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, quote_string));
+                       else {
+                               while (pos > 0) {
+                                       if (par.getInset(pos - 1)
+                                           && !par.getInset(pos - 1)->isPartOfTextSequence()) {
+                                               // skip "invisible" insets
+                                               --pos;
+                                               continue;
+                                       }
+                                       c = par.getChar(pos - 1);
+                                       break;
+                               }
+                       }
                }
+               InsetQuotesParams::QuoteLevel const quote_level = inner
+                               ? InsetQuotesParams::SecondaryQuotes : InsetQuotesParams::PrimaryQuotes;
+               cur.insert(new InsetQuotes(cur.buffer(), c, quote_level, cmd.getArg(1), cmd.getArg(2)));
+               cur.buffer()->updateBuffer();
+               cur.posForward();
                break;
        }
 
@@ -1606,9 +1652,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                bvcur.setMark(false);
                switch (cmd.button()) {
                case mouse_button::button1:
-                       // Set the cursor
-                       if (!bv->mouseSetCursor(cur, cmd.argument() == "region-select"))
-                               cur.screenUpdateFlags(Update::FitCursor);
+                       if (!bvcur.selection())
+                               // Set the cursor
+                               bvcur.resetAnchor();
+                       if (!bv->mouseSetCursor(cur, cmd.modifier() == ShiftModifier))
+                               cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
                        if (bvcur.wordSelection())
                                selectWord(bvcur, WHOLE_WORD);
                        break;
@@ -1661,6 +1709,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
                tm->setCursorFromCoordinates(cur, cmd.x(), y);
                cur.setTargetX(cmd.x());
+               // Don't allow selecting a separator inset
+               if (cur.pos() && cur.paragraph().isEnvSeparator(cur.pos() - 1))
+                       cur.posBackward();
                if (cmd.y() >= wh)
                        lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT));
                else if (cmd.y() < 0)
@@ -1675,7 +1726,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                // We continue with our existing selection or start a new one, so don't
                // reset the anchor.
                bvcur.setCursor(cur);
-               bvcur.setSelection(true);
+               bvcur.selection(true);
+               bvcur.setCurrentFont();
                if (cur.top() == old) {
                        // We didn't move one iota, so no need to update the screen.
                        cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
@@ -1755,13 +1807,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        }
 
        case LFUN_HREF_INSERT: {
-               // FIXME If we're actually given an argument, shouldn't
-               // we use it, whether or not we have a selection?
                docstring content = cmd.argument();
-               if (cur.selection()) {
+               if (content.empty() && cur.selection())
                        content = cur.selectionAsString(false);
-                       cutSelection(cur, true, false);
-               }
 
                InsetCommandParams p(HYPERLINK_CODE);
                if (!content.empty()){
@@ -2012,7 +2060,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        // don't pass "on" as argument
                        // (it would appear literally in the first cell)
                        docstring sel = cur.selectionAsString(false);
-                       MathMacroTemplate * macro = new MathMacroTemplate(cur.buffer());
+                       InsetMathMacroTemplate * macro = new InsetMathMacroTemplate(cur.buffer());
                        // create a macro template if we see "\\newcommand" somewhere, and
                        // an ordinary formula otherwise
                        if (!sel.empty()
@@ -2048,7 +2096,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        MacroType type = MacroTypeNewcommand;
                        if (s2 == "def")
                                type = MacroTypeDef;
-                       MathMacroTemplate * inset = new MathMacroTemplate(cur.buffer(),
+                       InsetMathMacroTemplate * inset = new InsetMathMacroTemplate(cur.buffer(),
                                from_utf8(token(s, ' ', 0)), nargs, false, type);
                        inset->setBuffer(bv->buffer());
                        insertInset(cur, inset);
@@ -2057,7 +2105,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        cur.push(*inset);
                        cur.top().pos() = cur.top().lastpos();
                        cur.resetAnchor();
-                       cur.setSelection(true);
+                       cur.selection(true);
                        cur.top().pos() = 0;
                }
                break;
@@ -2136,6 +2184,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_FONT_CROSSOUT: {
+               Font font(ignore_font, ignore_language);
+               font.fontInfo().setXout(FONT_TOGGLE);
+               toggleAndShow(cur, this, font);
+               break;
+       }
+
        case LFUN_FONT_UNDERUNDERLINE: {
                Font font(ignore_font, ignore_language);
                font.fontInfo().setUuline(FONT_TOGGLE);
@@ -2433,7 +2488,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_ESCAPE:
                if (cur.selection()) {
-                       cur.setSelection(false);
+                       cur.selection(false);
                } else {
                        cur.undispatched();
                        // This used to be LFUN_FINISHED_RIGHT, I think FORWARD is more
@@ -2718,7 +2773,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_CAPTION_INSERT: {
                code = CAPTION_CODE;
                string arg = cmd.getArg(0);
-               bool varia = arg != "LongTableNoNumber"
+               bool varia = arg != "Unnumbered"
                        && cur.inset().allowsCaptionVariation(arg);
                // not allowed in description items,
                // and in specific insets
@@ -2802,19 +2857,13 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                        for (; pit <= lastpit; ++pit) {
                                if (pars_[pit].layout() != lay)
                                        break;
-                               InsetList::const_iterator it = pars_[pit].insetList().begin();
-                               InsetList::const_iterator end = pars_[pit].insetList().end();
-                               for (; it != end; ++it) {
-                                       if (it->inset->lyxCode() == ARG_CODE) {
-                                               InsetArgument const * ins =
-                                                       static_cast<InsetArgument const *>(it->inset);
+                               for (auto const & table : pars_[pit].insetList())
+                                       if (InsetArgument const * ins = table.inset->asInsetArgument())
                                                if (ins->name() == arg) {
                                                        // we have this already
                                                        enable = false;
                                                        break;
                                                }
-                                       }
-                               }
                        }
                } else
                        enable = false;
@@ -2858,6 +2907,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_QUOTE_INSERT:
                // always allow this, since we will inset a raw quote
                // if an inset is not allowed.
+               allow_in_passthru = true;
                break;
        case LFUN_SPECIALCHAR_INSERT:
                code = SPECIALCHAR_CODE;
@@ -3106,7 +3156,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                docstring layout = cmd.argument();
                if (layout.empty())
                        layout = tclass.defaultLayoutName();
-               enable = !cur.inset().forcePlainLayout() && tclass.hasLayout(layout);
+               enable = !owner_->forcePlainLayout() && tclass.hasLayout(layout);
 
                flag.setOnOff(layout == cur.paragraph().layout().name());
                break;
@@ -3142,7 +3192,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_PARAGRAPH_PARAMS:
        case LFUN_PARAGRAPH_PARAMS_APPLY:
        case LFUN_PARAGRAPH_UPDATE:
-               enable = cur.inset().allowParagraphCustomization();
+               enable = owner_->allowParagraphCustomization();
                break;
 
        // FIXME: why are accent lfuns forbidden with pass_thru layouts?
@@ -3172,6 +3222,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_FONT_STATE:
        case LFUN_FONT_UNDERLINE:
        case LFUN_FONT_STRIKEOUT:
+       case LFUN_FONT_CROSSOUT:
        case LFUN_FONT_UNDERUNDERLINE:
        case LFUN_FONT_UNDERWAVE:
        case LFUN_TEXTSTYLE_APPLY: