]> git.lyx.org Git - lyx.git/blobdiff - src/Text3.cpp
Make math autocorrrect work with more than 2 chars
[lyx.git] / src / Text3.cpp
index b4bfd4442b8232159840148a735fb9c61b5cf361..f234c7cb7d027c95fd979b3cd281c0709092493a 100644 (file)
@@ -70,6 +70,7 @@
 
 #include "support/convert.h"
 #include "support/debug.h"
+#include "support/filetools.h"
 #include "support/gettext.h"
 #include "support/lassert.h"
 #include "support/limited_stack.h"
@@ -561,10 +562,10 @@ void Text::number(Cursor & cur)
 }
 
 
-bool Text::isRTL(Paragraph const & par) const
+bool Text::isRTL(pit_type const pit) const
 {
        Buffer const & buffer = owner_->buffer();
-       return par.isRTL(buffer.params());
+       return pars_[pit].isRTL(buffer.params());
 }
 
 
@@ -926,6 +927,14 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_PARAGRAPH_SELECT:
+               if (cur.pos() > 0)
+                       needsUpdate |= setCursor(cur, cur.pit(), 0);
+               needsUpdate |= cur.selHandle(true);
+               if (cur.pos() < cur.lastpos())
+                       needsUpdate |= setCursor(cur, cur.pit(), cur.lastpos());
+               break;
+
        case LFUN_PARAGRAPH_UP:
        case LFUN_PARAGRAPH_UP_SELECT:
                needsUpdate |= cur.selHandle(cmd.action() == LFUN_PARAGRAPH_UP_SELECT);
@@ -1255,6 +1264,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                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().keepempty
                    && !par.layout().isCommand()
                    && pars_[prev].layout() != par.layout()
                    && pars_[prev].layout().isEnvironment()
@@ -1585,11 +1595,20 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                }
 
                DocumentClass const & tclass = bv->buffer().params().documentClass();
+               bool inautoarg = false;
                for (auto const & la_pair : tclass[layout].args()) {
                        Layout::latexarg const & arg = la_pair.second;
                        if (arg.autoinsert) {
+                               // If we had already inserted an arg automatically,
+                               // leave this now in order to insert the next one.
+                               if (inautoarg) {
+                                       cur.leaveInset(cur.inset());
+                                       cur.posForward();
+                                       inautoarg = false;
+                               }
                                FuncRequest const cmd2(LFUN_ARGUMENT_INSERT, la_pair.first);
                                lyx::dispatch(cmd2);
+                               inautoarg = true;
                        }
                }
 
@@ -1760,9 +1779,12 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_MOUSE_TRIPLE:
                if (cmd.button() == mouse_button::button1) {
-                       tm->cursorHome(cur);
+                       if (cur.pos() > 0)
+                               setCursor(cur, cur.pit(), 0);
+                       bv->cursor() = cur;
                        cur.resetAnchor();
-                       tm->cursorEnd(cur);
+                       if (cur.pos() < cur.lastpos())
+                               setCursor(cur, cur.pit(), cur.lastpos());
                        cur.setSelection();
                        bv->cursor() = cur;
                }
@@ -2029,6 +2051,16 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                // inside it.
                doInsertInset(cur, this, cmd, true, true);
                cur.posForward();
+               if (act == LFUN_SCRIPT_INSERT) {
+                       /* Script insets change the font style in metrics(), and
+                        * this is used to compute the height of the caret
+                        * (because the font is stored in TextMetrics::font_).
+                        * When we insert, we have to make sure that metrics are
+                        * computed so that the caret height is wrong. Arguably,
+                        * this is hackish.*/
+                       bv->processUpdateFlags(Update::SinglePar);
+               }
+               cur.setCurrentFont();
                // Some insets are numbered, others are shown in the outline pane so
                // let's update the labels and the toc backend.
                cur.forceBufferUpdate();
@@ -2040,18 +2072,34 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                bool const sel = cur.selection();
                doInsertInset(cur, this, cmd, true, true);
                // Insert auto-insert arguments
-               bool autoargs = false;
-               Layout::LaTeXArgMap args = cur.inset().getLayout().latexargs();
+               bool autoargs, inautoarg = false;
+               Layout::LaTeXArgMap args = cur.inset().getLayout().args();
                Layout::LaTeXArgMap::const_iterator lait = args.begin();
                Layout::LaTeXArgMap::const_iterator const laend = args.end();
                for (; lait != laend; ++lait) {
                        Layout::latexarg arg = (*lait).second;
+                       if (!inautoarg && arg.insertonnewline && cur.pos() > 0) {
+                               FuncRequest cmd2(LFUN_PARAGRAPH_BREAK);
+                               lyx::dispatch(cmd2);
+                       }
                        if (arg.autoinsert) {
                                // The cursor might have been invalidated by the replaceSelection.
                                cur.buffer()->changed(true);
+                               // If we had already inserted an arg automatically,
+                               // leave this now in order to insert the next one.
+                               if (inautoarg) {
+                                       cur.leaveInset(cur.inset());
+                                       cur.posForward();
+                                       inautoarg = false;
+                                       if (arg.insertonnewline && cur.pos() > 0) {
+                                               FuncRequest cmd2(LFUN_PARAGRAPH_BREAK);
+                                               lyx::dispatch(cmd2);
+                                       }
+                               }
                                FuncRequest cmd2(LFUN_ARGUMENT_INSERT, (*lait).first);
                                lyx::dispatch(cmd2);
                                autoargs = true;
+                               inautoarg = true;
                        }
                }
                if (!autoargs) {
@@ -2065,14 +2113,78 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
-       case LFUN_TABULAR_INSERT:
+       case LFUN_TABULAR_INSERT: {
                // if there were no arguments, just open the dialog
+               if (cmd.argument().empty()) {
+                       bv->showDialog("tabularcreate");
+                       break;
+               } else if (cur.buffer()->masterParams().tablestyle != "default"
+                          || bv->buffer().params().documentClass().tablestyle() != "default") {
+                       string tabstyle = cur.buffer()->masterParams().tablestyle;
+                       if (tabstyle == "default")
+                               tabstyle = bv->buffer().params().documentClass().tablestyle();
+                       if (!libFileSearch("tabletemplates", tabstyle + ".lyx").empty()) {
+                               FuncRequest fr(LFUN_TABULAR_STYLE_INSERT,
+                                              tabstyle + " " + to_ascii(cmd.argument()));
+                               lyx::dispatch(fr);
+                               break;
+                       } else
+                               // Unknown style. Report and fall back to default.
+                               cur.errorMessage(from_utf8(N_("Table Style ")) + from_utf8(tabstyle) +
+                                                    from_utf8(N_(" not known")));
+                       
+               }
                if (doInsertInset(cur, this, cmd, false, true))
                        cur.posForward();
-               else
-                       bv->showDialog("tabularcreate");
+               break;
+       }
 
+       case LFUN_TABULAR_STYLE_INSERT: {
+               string const style = cmd.getArg(0);
+               string const rows = cmd.getArg(1);
+               string const cols = cmd.getArg(2);
+               if (cols.empty() || !isStrInt(cols)
+                   || rows.empty() || !isStrInt(rows))
+                       break;
+               int const r = convert<int>(rows);
+               int const c = convert<int>(cols);
+                       
+               string suffix;
+               if (r == 1)
+                       suffix = "_1x1";
+               else if (r == 2)
+                       suffix = "_1x2";
+               FileName const tabstyle = libFileSearch("tabletemplates",
+                                                       style + suffix + ".lyx", "lyx");
+               if (tabstyle.empty())
+                           break;
+               UndoGroupHelper ugh(cur.buffer());
+               cur.recordUndo();
+               FuncRequest cmd2(LFUN_FILE_INSERT, tabstyle.absFileName() + " ignorelang");
+               lyx::dispatch(cmd2);
+               // go into table
+               cur.backwardPos();
+               if (r > 2) {
+                       // move one cell up to middle cell
+                       cur.up();
+                       // add the missing rows
+                       int const addrows = r - 3;
+                       for (int i = 0 ; i < addrows ; ++i) {
+                               FuncRequest fr(LFUN_TABULAR_FEATURE, "append-row");
+                               lyx::dispatch(fr);
+                       }
+               }
+               // add the missing columns
+               int const addcols = c - 1;
+               for (int i = 0 ; i < addcols ; ++i) {
+                       FuncRequest fr(LFUN_TABULAR_FEATURE, "append-column");
+                       lyx::dispatch(fr);
+               }
+               if (r > 1)
+                       // go to first cell
+                       cur.up();
                break;
+       }
 
        case LFUN_FLOAT_INSERT:
        case LFUN_FLOAT_WIDE_INSERT:
@@ -2390,7 +2502,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        // Set the freefont using the contents of \param data dispatched from
        // the frontends and apply it at the current cursor location.
        case LFUN_TEXTSTYLE_UPDATE: {
-               Font font;
+               Font font(ignore_font, ignore_language);
                bool toggle;
                if (font.fromString(to_utf8(cmd.argument()), toggle)) {
                        docstring const props = font.stateText(&bv->buffer().params(), true);
@@ -2771,7 +2883,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        bool enable = true;
        bool allow_in_passthru = false;
        InsetCode code = NO_CODE;
-
+       
        switch (cmd.action()) {
 
        case LFUN_DEPTH_DECREMENT:
@@ -2861,6 +2973,9 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_TABULAR_INSERT:
                code = TABULAR_CODE;
                break;
+       case LFUN_TABULAR_STYLE_INSERT:
+               code = TABULAR_CODE;
+               break;
        case LFUN_MARGINALNOTE_INSERT:
                code = MARGIN_CODE;
                break;
@@ -3233,7 +3348,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                        for (DocIterator it = cur.selectionBegin(); ; it.forwardPar()) {
                                pos_type const beg = it.pos();
                                pos_type end;
-                               bool const in_last_par = (it.pit() == cur.selectionEnd().pit());
+                               bool const in_last_par = (it.pit() == cur.selectionEnd().pit() &&
+                                                         it.idx() == cur.selectionEnd().idx());
                                if (in_last_par)
                                        end = cur.selectionEnd().pos();
                                else
@@ -3387,7 +3503,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_ACCENT_UMLAUT:
        case LFUN_ACCENT_UNDERBAR:
        case LFUN_ACCENT_UNDERDOT:
-       case LFUN_FONT_DEFAULT:
        case LFUN_FONT_FRAK:
        case LFUN_FONT_SIZE:
        case LFUN_FONT_STATE:
@@ -3400,6 +3515,38 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                enable = !cur.paragraph().isPassThru();
                break;
 
+       case LFUN_FONT_DEFAULT: {
+               Font font(inherit_font, ignore_language);
+               BufferParams const & bp = cur.buffer()->masterParams();
+               if (cur.selection()) {
+                       enable = false;
+                       // Check if we have a non-default font attribute
+                       // in the selection range.
+                       DocIterator const from = cur.selectionBegin();
+                       DocIterator const to = cur.selectionEnd();
+                       for (DocIterator dit = from ; dit != to && !dit.atEnd(); ) {
+                               if (!dit.inTexted()) {
+                                       dit.forwardPos();
+                                       continue;
+                               }
+                               Paragraph const & par = dit.paragraph();
+                               pos_type const pos = dit.pos();
+                               Font tmp = par.getFontSettings(bp, pos);
+                               if (tmp.fontInfo() != font.fontInfo()
+                                   || tmp.language() != bp.language) {
+                                       enable = true;
+                                       break;
+                               }
+                               dit.forwardPos();
+                       }
+                       break;
+               }
+               // Disable if all is default already.
+               enable = (cur.current_font.fontInfo() != font.fontInfo()
+                         || cur.current_font.language() != bp.language);
+               break;
+       }
+
        case LFUN_TEXTSTYLE_APPLY:
                enable = !freeFonts.empty();
                break;
@@ -3423,6 +3570,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_UP_SELECT:
        case LFUN_DOWN:
        case LFUN_DOWN_SELECT:
+       case LFUN_PARAGRAPH_SELECT:
        case LFUN_PARAGRAPH_UP_SELECT:
        case LFUN_PARAGRAPH_DOWN_SELECT:
        case LFUN_LINE_BEGIN_SELECT: