]> git.lyx.org Git - lyx.git/blobdiff - src/Text3.cpp
* GuiDocument.cpp:
[lyx.git] / src / Text3.cpp
index c4c4524a96cc9d4606d260f8ce6cebfd1d8ccc58..29f1d2154f79d64cbd0e66cf156ddce4e29dce37 100644 (file)
@@ -297,6 +297,59 @@ string const freefont2string()
 }
 
 
+static void dragMove(Cursor & cur, int moveid, int movetoid)
+{
+       // Create pointers to buffers
+       Buffer & buf_move = *cur.buffer();
+       DocIterator dit_move = buf_move.getParFromID(moveid);
+       DocIterator dit_dest = buf_move.getParFromID(movetoid);
+
+       pit_type & pit_move = dit_move.pit();
+       pit_type & pit_dest = dit_dest.pit();
+       ParagraphList & pars = dit_move.text()->paragraphs();
+
+       // Create references to the paragraphs to be moved
+       ParagraphList::iterator const bgn = pars.begin();
+       ParagraphList::iterator dest_start = boost::next(bgn, pit_dest);
+
+       // The first paragraph of the area to be copied:
+       ParagraphList::iterator start = boost::next(bgn, pit_move);
+       // The final paragraph of area to be copied:
+       ParagraphList::iterator finish = start;
+       ParagraphList::iterator const end = pars.end();
+
+       // Move out (down) from this section header
+       if (finish != end)
+               ++finish;
+
+       // Seek the one (on same level) below
+       int const thistoclevel = start->layout().toclevel;
+       for (; finish != end; ++finish) {
+               int const toclevel = finish->layout().toclevel;
+               if (toclevel != Layout::NOT_IN_TOC
+                   && toclevel <= thistoclevel)
+                       break;
+       }
+
+       if (start == pars.begin() || start == dest_start)
+               // Nothing to move
+               return;
+
+       pars.insert(dest_start, start, finish);
+       pars.erase(start, finish);
+
+       // FIXME: This only really needs doing for the newly
+       // introduced paragraphs. Something like:
+       //      pit_type const numpars = distance(start, finish);
+       //      start = boost::next(bgn, pit);
+       //      finish = boost::next(start, numpars);
+       //      for (; start != finish; ++start)
+       //              start->setBuffer(buf);
+       // But while this seems to work, it is kind of fragile.
+       buf_move.inset().setBuffer(buf_move);
+}
+
+
 /// the type of outline operation
 enum OutlineOp {
        OutlineUp, // Move this header with text down
@@ -311,12 +364,12 @@ static void outline(OutlineOp mode, Cursor & cur)
        Buffer & buf = *cur.buffer();
        pit_type & pit = cur.pit();
        ParagraphList & pars = buf.text().paragraphs();
-       ParagraphList::iterator bgn = pars.begin();
+       ParagraphList::iterator const bgn = pars.begin();
        // The first paragraph of the area to be copied:
        ParagraphList::iterator start = boost::next(bgn, pit);
        // The final paragraph of area to be copied:
        ParagraphList::iterator finish = start;
-       ParagraphList::iterator end = pars.end();
+       ParagraphList::iterator const end = pars.end();
 
        DocumentClass const & tc = buf.params().documentClass();
 
@@ -326,6 +379,7 @@ static void outline(OutlineOp mode, Cursor & cur)
        // Move out (down) from this section header
        if (finish != end)
                ++finish;
+
        // Seek the one (on same level) below
        for (; finish != end; ++finish) {
                toclevel = finish->layout().toclevel;
@@ -333,6 +387,10 @@ static void outline(OutlineOp mode, Cursor & cur)
                        break;
        }
 
+       // Do we need to set insets' buffer_ members, because we copied
+       // some stuff? We'll assume we do and reset it otherwise.
+       bool set_buffers = true;
+
        switch (mode) {
                case OutlineUp: {
                        if (start == pars.begin())
@@ -360,7 +418,7 @@ static void outline(OutlineOp mode, Cursor & cur)
                        start = boost::next(pars.begin(), deletepit);
                        pit = newpit;
                        pars.erase(start, finish);
-                       return;
+                       break;
                }
                case OutlineDown: {
                        if (finish == end)
@@ -383,7 +441,7 @@ static void outline(OutlineOp mode, Cursor & cur)
                        start = boost::next(bgn, pit);
                        pit = newpit - len;
                        pars.erase(start, finish);
-                       return;
+                       break;
                }
                case OutlineIn: {
                        pit_type const len = distance(start, finish);
@@ -402,7 +460,8 @@ static void outline(OutlineOp mode, Cursor & cur)
                                        }
                                }
                        }
-                       return;
+                       set_buffers = false;
+                       break;
                }
                case OutlineOut: {
                        pit_type const len = distance(start, finish);
@@ -421,9 +480,20 @@ static void outline(OutlineOp mode, Cursor & cur)
                                        }
                                }
                        }
-                       return;
+                       set_buffers = false;
+                       break;
                }
        }
+       if (set_buffers)
+               // FIXME This only really needs doing for the newly introduced 
+               // paragraphs. Something like:
+               //      pit_type const numpars = distance(start, finish);
+               //      start = boost::next(bgn, pit);
+               //      finish = boost::next(start, numpars);
+               //      for (; start != finish; ++start)
+               //              start->setBuffer(buf);
+               // But while this seems to work, it is kind of fragile.
+               buf.inset().setBuffer(buf);
 }
 
 
@@ -446,10 +516,10 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        LYXERR(Debug::ACTION, "Text::dispatch: cmd: " << cmd);
 
        BufferView * bv = &cur.bv();
-       TextMetrics & tm = bv->textMetrics(this);
-       if (!tm.contains(cur.pit())) {
+       TextMetrics * tm = &bv->textMetrics(this);
+       if (!tm->contains(cur.pit())) {
                lyx::dispatch(FuncRequest(LFUN_SCREEN_SHOW_CURSOR));
-               tm = bv->textMetrics(this);
+               tm = &bv->textMetrics(this);
        }
 
        // FIXME: We use the update flag to indicates wether a singlePar or a
@@ -537,7 +607,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                if (cur.selection())
                        cutSelection(cur, true, false);
                else
-                       tm.deleteLineForward(cur);
+                       tm->deleteLineForward(cur);
                finishChange(cur, false);
                break;
 
@@ -591,6 +661,19 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                                && 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;
+                               cur.bv().checkDepm(dummy, cur);
+                       }
                }
                break;
 
@@ -604,6 +687,19 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        && 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();
+                               cur.bv().checkDepm(dummy, cur);
+                       }
                }
                break;
 
@@ -698,18 +794,18 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_LINE_BEGIN:
        case LFUN_LINE_BEGIN_SELECT:
                needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT);
-               needsUpdate |= tm.cursorHome(cur);
+               needsUpdate |= tm->cursorHome(cur);
                break;
 
        case LFUN_LINE_END:
        case LFUN_LINE_END_SELECT:
                needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT);
-               needsUpdate |= tm.cursorEnd(cur);
+               needsUpdate |= tm->cursorEnd(cur);
                break;
 
        case LFUN_SECTION_SELECT: {
-               Buffer & buf = *cur.buffer();
-               pit_type & pit = cur.pit();
+               Buffer const & buf = *cur.buffer();
+               pit_type const pit = cur.pit();
                ParagraphList & pars = buf.text().paragraphs();
                ParagraphList::iterator bgn = pars.begin();
                // The first paragraph of the area to be selected:
@@ -718,26 +814,25 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                ParagraphList::iterator finish = start;
                ParagraphList::iterator end = pars.end();
 
-               setCursor(cur, cur.pit(), 0);
-               Cursor old_cur = cur;
-               needsUpdate |= cur.selHandle(true);
-               
                int const thistoclevel = start->layout().toclevel;
                if (thistoclevel == Layout::NOT_IN_TOC)
                        break;
 
+               cur.pos() = 0;
+               Cursor const old_cur = cur;
+               needsUpdate |= cur.selHandle(true);
+
                // Move out (down) from this section header
                if (finish != end)
                        ++finish;
 
-               int toclevel;
                // Seek the one (on same level) below
-               for (; finish != end; ++finish, cur.forwardPar()) {
-                       toclevel = finish->layout().toclevel;
+               for (; finish != end; ++finish, ++cur.pit()) {
+                       int const toclevel = finish->layout().toclevel;
                        if (toclevel != Layout::NOT_IN_TOC && toclevel <= thistoclevel)
                                break;
                }
-               setCursor(cur, cur.pit(), cur.lastpos());
+               cur.pos() = cur.lastpos();
                
                needsUpdate |= cur != old_cur;
                break;
@@ -1109,8 +1204,8 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_SERVER_GET_XY:
                cur.message(from_utf8(
-                       convert<string>(tm.cursorX(cur.top(), cur.boundary()))
-                       + ' ' + convert<string>(tm.cursorY(cur.top(), cur.boundary()))));
+                       convert<string>(tm->cursorX(cur.top(), cur.boundary()))
+                       + ' ' + convert<string>(tm->cursorY(cur.top(), cur.boundary()))));
                break;
 
        case LFUN_SERVER_SET_XY: {
@@ -1122,7 +1217,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                        lyxerr << "SETXY: Could not parse coordinates in '"
                               << to_utf8(cmd.argument()) << endl;
                else
-                       tm.setCursorFromCoordinates(cur, x, y);
+                       tm->setCursorFromCoordinates(cur, x, y);
                break;
        }
 
@@ -1268,9 +1363,9 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_MOUSE_TRIPLE:
                if (cmd.button() == mouse_button::button1) {
-                       tm.cursorHome(cur);
+                       tm->cursorHome(cur);
                        cur.resetAnchor();
-                       tm.cursorEnd(cur);
+                       tm->cursorEnd(cur);
                        cur.setSelection();
                        bv->cursor() = cur;
                }
@@ -1339,7 +1434,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                int const wh = bv->workHeight();
                int const y = max(0, min(wh - 1, cmd.y));
 
-               tm.setCursorFromCoordinates(cur, cmd.x, y);
+               tm->setCursorFromCoordinates(cur, cmd.x, y);
                cur.setTargetX(cmd.x);
                if (cmd.y >= wh)
                        lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT));
@@ -1482,6 +1577,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                }
                if (!inset)
                        break;
+               cur.recordUndo();
                insertInset(cur, inset);
                cur.posForward();
                break;
@@ -1588,7 +1684,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                dispatch(cur, fr);
                break;
        }
-
+       
        case LFUN_NOMENCL_PRINT:
        case LFUN_TOC_INSERT:
        case LFUN_LINE_INSERT:
@@ -1723,6 +1819,27 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       case LFUN_FONT_STRIKEOUT: {
+               Font font(ignore_font, ignore_language);
+               font.fontInfo().setStrikeout(FONT_TOGGLE);
+               toggleAndShow(cur, this, font);
+               break;
+       }
+
+       case LFUN_FONT_UULINE: {
+               Font font(ignore_font, ignore_language);
+               font.fontInfo().setUuline(FONT_TOGGLE);
+               toggleAndShow(cur, this, font);
+               break;
+       }
+
+       case LFUN_FONT_UWAVE: {
+               Font font(ignore_font, ignore_language);
+               font.fontInfo().setUwave(FONT_TOGGLE);
+               toggleAndShow(cur, this, font);
+               break;
+       }
+
        case LFUN_FONT_UNDERLINE: {
                Font font(ignore_font, ignore_language);
                font.fontInfo().setUnderbar(FONT_TOGGLE);
@@ -1960,6 +2077,16 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                cur.buffer()->updateLabels();
                needsUpdate = true;
                break;
+       
+       case LFUN_OUTLINE_DRAGMOVE: {
+               int const move_id = convert<int>(cmd.getArg(0));
+               int const move_to_id = convert<int>(cmd.getArg(1));
+               dragMove(cur, move_id, move_to_id);
+               setCursor(cur, cur.pit(), 0);
+               cur.buffer()->updateLabels();
+               needsUpdate = true;
+               break;
+       }
 
        default:
                LYXERR(Debug::ACTION, "Command " << cmd << " not DISPATCHED by Text");
@@ -1967,6 +2094,10 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
+       if (lyxrc.spellcheck_continuously && cur.inTexted())
+               // Take this opportunity to spellcheck current word.
+               cur.paragraph().isMisspelled(cur.pos());
+
        needsUpdate |= (cur.pos() != cur.lastpos()) && cur.selection();
 
        // FIXME: The cursor flag is reset two lines below
@@ -2035,8 +2166,11 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_DIALOG_SHOW_NEW_INSET:
                if (cmd.argument() == "bibitem")
                        code = BIBITEM_CODE;
-               else if (cmd.argument() == "bibtex")
+               else if (cmd.argument() == "bibtex") {
                        code = BIBTEX_CODE;
+                       // not allowed in description items
+                       enable = !inDescriptionItem(cur);
+               }
                else if (cmd.argument() == "box")
                        code = BOX_CODE;
                else if (cmd.argument() == "branch")
@@ -2061,6 +2195,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                        code = INDEX_PRINT_CODE;
                else if (cmd.argument() == "nomenclature")
                        code = NOMENCL_CODE;
+               else if (cmd.argument() == "nomencl_print")
+                       code = NOMENCL_PRINT_CODE;
                else if (cmd.argument() == "label")
                        code = LABEL_CODE;
                else if (cmd.argument() == "note")
@@ -2111,6 +2247,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                break;
        case LFUN_FLOAT_LIST_INSERT:
                code = FLOAT_LIST_CODE;
+               // not allowed in description items
+               enable = !inDescriptionItem(cur);
                break;
        case LFUN_CAPTION_INSERT:
                code = CAPTION_CODE;
@@ -2142,7 +2280,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                break;
        case LFUN_BRANCH_INSERT:
                code = BRANCH_CODE;
-               if (cur.buffer()->masterBuffer()->params().branchlist().empty())
+               if (cur.buffer()->masterBuffer()->params().branchlist().empty()
+                   && cur.buffer()->params().branchlist().empty())
                        enable = false;
                break;
        case LFUN_PHANTOM_INSERT:
@@ -2164,6 +2303,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                break;
        case LFUN_INDEX_PRINT:
                code = INDEX_PRINT_CODE;
+               // not allowed in description items
+               enable = !inDescriptionItem(cur);
                break;
        case LFUN_NOMENCL_INSERT:
                if (cur.selIsMultiCell() || cur.selIsMultiLine()) {
@@ -2174,9 +2315,13 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
                break;
        case LFUN_NOMENCL_PRINT:
                code = NOMENCL_PRINT_CODE;
+               // 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()) {
@@ -2330,6 +2475,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_OUTLINE_DOWN:
        case LFUN_OUTLINE_IN:
        case LFUN_OUTLINE_OUT:
+       case LFUN_OUTLINE_DRAGMOVE:
                // FIXME: LyX is not ready for outlining within inset.
                enable = isMainText(cur.bv().buffer())
                        && cur.paragraph().layout().toclevel != Layout::NOT_IN_TOC;
@@ -2424,6 +2570,9 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_MATH_SUPERSCRIPT:
        case LFUN_FONT_DEFAULT:
        case LFUN_FONT_UNDERLINE:
+       case LFUN_FONT_STRIKEOUT:
+       case LFUN_FONT_UULINE:
+       case LFUN_FONT_UWAVE:
        case LFUN_FONT_SIZE:
        case LFUN_LANGUAGE:
        case LFUN_TEXTSTYLE_APPLY: