]> git.lyx.org Git - lyx.git/blobdiff - src/Text3.cpp
merge recent changes from master
[lyx.git] / src / Text3.cpp
index fea23b002bc30e9e2d4b4977f3222e65c376536c..3e6fdf0e14e62634173830b242372aa160a48a51 100644 (file)
@@ -90,7 +90,9 @@ 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;
@@ -299,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;
        }
@@ -311,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();
@@ -1089,13 +1091,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()
@@ -1552,26 +1548,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;
        }
 
@@ -1607,9 +1621,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;
@@ -1759,13 +1775,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()){
@@ -2862,6 +2874,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;