]> git.lyx.org Git - lyx.git/blobdiff - src/Text3.cpp
Do not overwrite read-only files. We now move the file to the backup directory and...
[lyx.git] / src / Text3.cpp
index a9e045698b8999e1cb5367d6604b986a8dc3441d..bc1ef41b188c17e8be901ace7b4d9d3c2931d82a 100644 (file)
@@ -268,10 +268,10 @@ static bool doInsertInset(Cursor & cur, Text * text,
        cur.buffer()->errors("Paste");
        cur.clearSelection(); // bug 393
        cur.finishUndo();
-       InsetText * insetText = dynamic_cast<InsetText *>(inset);
-       if (insetText) {
-               insetText->fixParagraphsFont();
-               if (!insetText->allowMultiPar() || cur.lastpit() == 0) {
+       InsetText * inset_text = inset->asInsetText();
+       if (inset_text) {
+               inset_text->fixParagraphsFont();
+               if (!inset_text->allowMultiPar() || cur.lastpit() == 0) {
                        // reset first par to default
                        cur.text()->paragraphs().begin()
                                ->setPlainOrDefaultLayout(bparams.documentClass());
@@ -486,8 +486,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                recUndo(cur, pit, pit + 1);
                cur.finishUndo();
                pars_.swap(pit, pit + 1);
-               cur.buffer()->updateBuffer();
                needsUpdate = true;
+               cur.forceBufferUpdate();
                ++cur.pit();
                break;
        }
@@ -497,9 +497,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                recUndo(cur, pit - 1, pit);
                cur.finishUndo();
                pars_.swap(pit, pit - 1);
-               cur.buffer()->updateBuffer();
                --cur.pit();
                needsUpdate = true;
+               cur.forceBufferUpdate();
                break;
        }
 
@@ -523,7 +523,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                par.params().startOfAppendix(start);
 
                // we can set the refreshing parameters now
-               cur.buffer()->updateBuffer();
+               cur.forceBufferUpdate();
                break;
        }
 
@@ -624,7 +624,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                // provide it with two different cursors.
                                Cursor dummy = cur;
                                dummy.pos() = dummy.pit() = 0;
-                               cur.bv().checkDepm(dummy, cur);
+                               if (cur.bv().checkDepm(dummy, cur))
+                                       cur.forceBufferUpdate();;
                        }
                }
                break;
@@ -650,7 +651,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                Cursor dummy = cur;
                                dummy.pos() = cur.lastpos();
                                dummy.pit() = cur.lastpit();
-                               cur.bv().checkDepm(dummy, cur);
+                               if (cur.bv().checkDepm(dummy, cur))
+                                       cur.forceBufferUpdate();
                        }
                }
                break;
@@ -817,6 +819,26 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_WORD_FORWARD_SELECT:
                needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_FORWARD_SELECT);
                needsUpdate |= cursorForwardOneWord(cur);
+
+               if (!needsUpdate && oldTopSlice == cur.top()
+                               && cur.boundary() == oldBoundary) {
+                       cur.undispatched();
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
+               
+                       // we will probably be moving out the inset, so we should execute
+                       // the depm-mechanism, but only when the cursor has a place to 
+                       // go outside this inset, i.e. in a slice above.
+                       if (cur.depth() > 1 && cur.pos() == cur.lastpos() 
+                                 && cur.pit() == cur.lastpit()) {
+                               // The cursor hasn't changed yet. To give the 
+                               // DEPM the possibility of doing something we must
+                               // provide it with two different cursors.
+                               Cursor dummy = cur;
+                               dummy.pos() = dummy.pit() = 0;
+                               if (cur.bv().checkDepm(dummy, cur))
+                                       cur.forceBufferUpdate();;
+                       }
+               }
                break;
 
        case LFUN_WORD_LEFT:
@@ -846,6 +868,27 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_WORD_BACKWARD_SELECT:
                needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_BACKWARD_SELECT);
                needsUpdate |= cursorBackwardOneWord(cur);
+       
+               if (!needsUpdate && oldTopSlice == cur.top()
+                               && cur.boundary() == oldBoundary) {
+                       cur.undispatched();
+                       cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
+               
+                       // we will probably be moving out the inset, so we should execute
+                       // the depm-mechanism, but only when the cursor has a place to 
+                       // go outside this inset, i.e. in a slice above.
+                       if (cur.depth() > 1 && cur.pos() == 0 
+                                 && cur.pit() == 0) {
+                               // The cursor hasn't changed yet. To give the 
+                               // DEPM the possibility of doing something we must
+                               // provide it with two different cursors.
+                               Cursor dummy = cur;
+                               dummy.pos() = cur.lastpos();
+                               dummy.pit() = cur.lastpit();
+                               if (cur.bv().checkDepm(dummy, cur))
+                                       cur.forceBufferUpdate();
+                       }
+               }
                break;
 
        case LFUN_WORD_SELECT: {
@@ -909,24 +952,22 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        pit_type const pit_end = cur.selEnd().pit();
                        for (pit_type pit = cur.selBegin().pit(); pit <= pit_end; pit++) {
                                Paragraph & par = paragraphs()[pit];
-                               if (par.getChar(0) == '\t') {
-                                       if (cur.pit() == pit)
-                                               cur.posBackward();
-                                       if (cur.realAnchor().pit() == pit && cur.realAnchor().pos() > 0 )
-                                               cur.realAnchor().backwardPos();
-                                       
-                                       par.eraseChar(0, tc);
-                               } else 
-                                       // If no tab was present, try to remove up to four spaces.
-                                       for (int n_spaces = 0;
-                                            par.getChar(0) == ' ' && n_spaces < 4; ++n_spaces) {
+                               if (par.empty())
+                                       continue;
+                               char_type const c = par.getChar(0);
+                               if (c == '\t' || c == ' ') {
+                                       // remove either 1 tab or 4 spaces.
+                                       int const n = (c == ' ' ? 4 : 1);
+                                       for (int i = 0; i < n 
+                                                 && !par.empty() && par.getChar(0) == c; ++i) {
                                                if (cur.pit() == pit)
                                                        cur.posBackward();
-                                               if (cur.realAnchor().pit() == pit && cur.realAnchor().pos() > 0 )
+                                               if (cur.realAnchor().pit() == pit 
+                                                         && cur.realAnchor().pos() > 0 )
                                                        cur.realAnchor().backwardPos();
-                                               
                                                par.eraseChar(0, tc);
                                        }
+                               }
                        }
                        cur.finishUndo();
                } else {
@@ -1032,7 +1073,10 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        if (cur.selection())
                                cutSelection(cur, true, false);
                        cur.insert(inset);
-                       cur.posForward();
+                       if (inset->editable() && inset->asInsetText())
+                               inset->edit(cur, true);
+                       else
+                               cur.posForward();
 
                        // trigger InstantPreview now
                        if (inset->lyxCode() == EXTERNAL_CODE) {
@@ -1046,8 +1090,10 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        }
 
        case LFUN_INSET_DISSOLVE: {
-               if (dissolveInset(cur))
+               if (dissolveInset(cur)) {
                        needsUpdate = true;
+                       cur.forceBufferUpdate();
+               }
                break;
        }
 
@@ -1515,7 +1561,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                }
                p["target"] = (cmd.argument().empty()) ?
                        content : cmd.argument();
-               string const data = InsetCommand::params2string("href", p);
+               string const data = InsetCommand::params2string(p);
                if (p["target"].empty()) {
                        bv->showDialog("href", data);
                } else {
@@ -1531,7 +1577,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                p["name"] = (cmd.argument().empty()) ?
                        cur.getPossibleLabel() :
                        cmd.argument();
-               string const data = InsetCommand::params2string("label", p);
+               string const data = InsetCommand::params2string(p);
 
                if (cmd.argument().empty()) {
                        bv->showDialog("label", data);
@@ -1573,13 +1619,14 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_ARGUMENT_INSERT:
        case LFUN_INDEX_INSERT:
        case LFUN_PREVIEW_INSERT:
+       case LFUN_SCRIPT_INSERT:
                // Open the inset, and move the current selection
                // inside it.
                doInsertInset(cur, this, cmd, true, true);
                cur.posForward();
                // Some insets are numbered, others are shown in the outline pane so
                // let's update the labels and the toc backend.
-               bv->buffer().updateBuffer();
+               cur.forceBufferUpdate();
                break;
 
        case LFUN_TABULAR_INSERT:
@@ -1633,7 +1680,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                // date metrics.
                FuncRequest cmd_caption(LFUN_CAPTION_INSERT);
                doInsertInset(cur, cur.text(), cmd_caption, true, false);
-               bv->buffer().updateBuffer();
+               cur.forceBufferUpdate();
                cur.screenUpdateFlags(Update::Force);
                // FIXME: When leaving the Float (or Wrap) inset we should
                // delete any empty paragraph left above or below the
@@ -1647,7 +1694,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        p["symbol"] = bv->cursor().innerText()->getStringToIndex(bv->cursor());
                else
                        p["symbol"] = cmd.argument();
-               string const data = InsetCommand::params2string("nomenclature", p);
+               string const data = InsetCommand::params2string(p);
                bv->showDialog("nomenclature", data);
                break;
        }
@@ -1658,15 +1705,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        p["type"] = from_ascii("idx");
                else
                        p["type"] = cmd.argument();
-               string const data = InsetCommand::params2string("index_print", p);
+               string const data = InsetCommand::params2string(p);
                FuncRequest fr(LFUN_INSET_INSERT, data);
                dispatch(cur, fr);
                break;
        }
        
        case LFUN_NOMENCL_PRINT:
-       case LFUN_TOC_INSERT:
-       case LFUN_LINE_INSERT:
        case LFUN_NEWPAGE_INSERT:
                // do nothing fancy
                doInsertInset(cur, this, cmd, false, false);
@@ -1938,6 +1983,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                if (!cmd.argument().empty())
                        // FIXME: Are all these characters encoded in one byte in utf8?
                        bv->translateAndInsert(cmd.argument()[0], this, cur);
+               cur.screenUpdateFlags(Update::FitCursor);
                break;
 
        case LFUN_FLOAT_LIST_INSERT: {
@@ -2038,6 +2084,25 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_SPELLING_REMOVE: {
+               docstring word = from_utf8(cmd.getArg(0));
+               Language * lang;
+               if (word.empty()) {
+                       word = cur.selectionAsString(false);
+                       // FIXME
+                       if (word.size() > 100 || word.empty()) {
+                               // Get word or selection
+                               selectWordWhenUnderCursor(cur, WHOLE_WORD);
+                               word = cur.selectionAsString(false);
+                       }
+                       lang = const_cast<Language *>(cur.getFont().language());
+               } else
+                       lang = const_cast<Language *>(languages.getLanguage(cmd.getArg(1)));
+               WordLangTuple wl(word, lang);
+               theSpellChecker()->remove(wl);
+               break;
+       }
+
        case LFUN_PARAGRAPH_PARAMS_APPLY: {
                // Given data, an encoding of the ParagraphParameters
                // generated in the Paragraph dialog, this function sets
@@ -2074,26 +2139,26 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_OUTLINE_UP:
                outline(OutlineUp, cur);
                setCursor(cur, cur.pit(), 0);
-               cur.buffer()->updateBuffer();
+               cur.forceBufferUpdate();
                needsUpdate = true;
                break;
 
        case LFUN_OUTLINE_DOWN:
                outline(OutlineDown, cur);
                setCursor(cur, cur.pit(), 0);
-               cur.buffer()->updateBuffer();
+               cur.forceBufferUpdate();
                needsUpdate = true;
                break;
 
        case LFUN_OUTLINE_IN:
                outline(OutlineIn, cur);
-               cur.buffer()->updateBuffer();
+               cur.forceBufferUpdate();
                needsUpdate = true;
                break;
 
        case LFUN_OUTLINE_OUT:
                outline(OutlineOut, cur);
-               cur.buffer()->updateBuffer();
+               cur.forceBufferUpdate();
                needsUpdate = true;
                break;
 
@@ -2110,7 +2175,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        // for now only Text::erase() and Text::backspace() do that.
        // The plan is to verify all the LFUNs and then to remove this
        // singleParUpdate boolean altogether.
-       if (cur.result().update() & Update::Force) {
+       if (cur.result().screenUpdate() & Update::Force) {
                singleParUpdate = false;
                needsUpdate = true;
        }
@@ -2204,6 +2269,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                        code = NOMENCL_PRINT_CODE;
                else if (cmd.argument() == "label")
                        code = LABEL_CODE;
+               else if (cmd.argument() == "line")
+                       code = LINE_CODE;
                else if (cmd.argument() == "note")
                        code = NOTE_CODE;
                else if (cmd.argument() == "phantom")
@@ -2335,9 +2402,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_LABEL_INSERT:
                code = LABEL_CODE;
                break;
-       case LFUN_LINE_INSERT:
-               code = LINE_CODE;
-               break;
        case LFUN_INFO_INSERT:
                code = INFO_CODE;
                break;
@@ -2368,11 +2432,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                // not allowed in description items
                enable = !inDescriptionItem(cur);
                break;
-       case LFUN_TOC_INSERT:
-               code = TOC_CODE;
-               // not allowed in description items
-               enable = !inDescriptionItem(cur);
-               break;
        case LFUN_HYPERLINK_INSERT:
                if (cur.selIsMultiCell() || cur.selIsMultiLine()) {
                        enable = false;
@@ -2395,6 +2454,9 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_PREVIEW_INSERT:
                code = PREVIEW_CODE;
                break;
+       case LFUN_SCRIPT_INSERT:
+               code = SCRIPT_CODE;
+               break;
 
        case LFUN_MATH_INSERT:
        case LFUN_MATH_AMS_MATRIX:
@@ -2585,6 +2647,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        
        case LFUN_SPELLING_ADD:
        case LFUN_SPELLING_IGNORE:
+       case LFUN_SPELLING_REMOVE:
                enable = theSpellChecker();
                break;
 
@@ -2673,7 +2736,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_LINE_END:
        case LFUN_CHAR_DELETE_FORWARD:
        case LFUN_CHAR_DELETE_BACKWARD:
-       case LFUN_INSET_INSERT:
        case LFUN_WORD_UPCASE:
        case LFUN_WORD_LOWCASE:
        case LFUN_WORD_CAPITALIZE:
@@ -2689,6 +2751,19 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                enable = true;
                break;
 
+       case LFUN_INSET_INSERT: {
+               string const type = cmd.getArg(0);
+               if (type == "toc") {
+                       code = TOC_CODE;
+                       // not allowed in description items
+                       //FIXME: couldn't this be merged in Inset::insetAllowed()?
+                       enable = !inDescriptionItem(cur);
+               } else {
+                       enable = true;
+               }
+               break;
+       }
+
        default:
                return false;
        }