]> git.lyx.org Git - lyx.git/blobdiff - src/text2.C
Call an update before setting the_locking_inset = 0 as otherwise we
[lyx.git] / src / text2.C
index f9d2a574d6fa65b3dc144d7cca2d1ea2ca3c0568..08d31a00fb063ac8e2fcc967ba1cc0a73ded9a34 100644 (file)
@@ -500,14 +500,16 @@ Paragraph * LyXText::setLayout(BufferView * bview,
        // ok we have a selection. This is always between sstart_cur
        // and sel_end cursor
        cur = sstart_cur;
+       Paragraph * par = sstart_cur.par();
+       Paragraph * epar = send_cur.par()->next();
 
        LyXLayout const & lyxlayout =
                textclasslist[bview->buffer()->params.textclass][layout];
 
        do {
-               cur.par()->applyLayout(layout);
-               makeFontEntriesLayoutSpecific(bview->buffer(), cur.par());
-               Paragraph * fppar = cur.par();
+               par->applyLayout(layout);
+               makeFontEntriesLayoutSpecific(bview->buffer(), par);
+               Paragraph * fppar = par;
                fppar->params().spaceTop(lyxlayout.fill_top ?
                                         VSpace(VSpace::VFILL)
                                         : VSpace(VSpace::NONE));
@@ -515,15 +517,15 @@ Paragraph * LyXText::setLayout(BufferView * bview,
                                            VSpace(VSpace::VFILL)
                                            : VSpace(VSpace::NONE));
                if (lyxlayout.margintype == MARGIN_MANUAL)
-                       cur.par()->setLabelWidthString(lyxlayout.labelstring());
+                       par->setLabelWidthString(lyxlayout.labelstring());
                if (lyxlayout.labeltype != LABEL_BIBLIO
                    && fppar->bibkey) {
                        delete fppar->bibkey;
                        fppar->bibkey = 0;
                }
-               if (cur.par() != send_cur.par())
-                       cur.par(cur.par()->next());
-       } while (cur.par() != send_cur.par());
+               cur.par(par);
+               par = par->next();
+       } while (par != epar);
 
        return endpar;
 }
@@ -909,7 +911,7 @@ bool LyXText::fullRebreak(BufferView * bview)
                need_break_row = 0;
                return true;
        }
-       return false;
+       return true;
 }
 
 
@@ -1647,13 +1649,12 @@ void LyXText::insertInset(BufferView * bview, Inset * inset)
 {
        if (!cursor.par()->insetAllowed(inset->lyxCode()))
                return;
-       // I don't know if this is necessary here (Jug 20020102)
-       setUndo(bview, Undo::INSERT, cursor.par(), cursor.par()->next());
+       setUndo(bview, Undo::FINISH, cursor.par(), cursor.par()->next());
+       freezeUndo();
        cursor.par()->insertInset(cursor.pos(), inset);
        // Just to rebreak and refresh correctly.
        // The character will not be inserted a second time
        insertChar(bview, Paragraph::META_INSET);
-#if 1
        // If we enter a highly editable inset the cursor should be to before
        // the inset. This couldn't happen before as Undo was not handled inside
        // inset now after the Undo LyX tries to call inset->Edit(...) again
@@ -1662,7 +1663,7 @@ void LyXText::insertInset(BufferView * bview, Inset * inset)
        if (isHighlyEditableInset(inset)) {
                cursorLeft(bview, true);
        }
-#endif
+       unFreezeUndo();
 }
 
 
@@ -2061,34 +2062,31 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par,
        cur.pos(pos);
        cur.boundary(boundary);
 
-#if 0
-       if (pos && par->getChar(pos) == Paragraph::META_INSET &&
-               par->getInset(pos)) {
-               Inset * ins = par->getInset(pos);
-               if (ins->needFullRow() || ins->display()) {
-                       --pos;
-                       boundary = true;
-               }
-       }
-#endif
-
        // get the cursor y position in text
        int y = 0;
        Row * row = getRow(par, pos, y);
+       Row * old_row = row;
+       cur.irow(row);
+       // if we are before the first char of this row and are still in the
+       // same paragraph and there is a previous row then put the cursor on
+       // the end of the previous row
+       cur.iy(y + row->baseline());
+       Inset * ins;
+       if (row->previous() && pos &&
+               par->getChar(pos) == Paragraph::META_INSET &&
+               (ins=par->getInset(pos)) && (ins->needFullRow() || ins->display()))
+       {
+               row = row->previous();
+               y -= row->height();
+       }
+
+       cur.row(row);
        // y is now the beginning of the cursor row
        y += row->baseline();
        // y is now the cursor baseline
        cur.y(y);
 
-       // now get the cursors x position
-       float x;
-       float fill_separator;
-       float fill_hfill;
-       float fill_label_hfill;
-       prepareToPrint(bview, row, x, fill_separator, fill_hfill,
-                      fill_label_hfill);
-       pos_type cursor_vpos = 0;
-       pos_type last = rowLastPrintable(row);
+       pos_type last = rowLastPrintable(old_row);
 
        if (pos > last + 1) {
                // This shouldn't happen.
@@ -2099,6 +2097,30 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par,
                cur.pos(pos);
        }
 
+       // now get the cursors x position
+       float x = getCursorX(bview, row, pos, last, boundary);
+       cur.x(int(x));
+       cur.x_fix(cur.x());
+       if (old_row != row) {
+               x = getCursorX(bview, old_row, pos, last, boundary);
+               cur.ix(int(x));
+       } else
+               cur.ix(cur.x());
+}
+
+
+float LyXText::getCursorX(BufferView * bview, Row * row,
+                                                 pos_type pos, pos_type last, bool boundary) const
+{
+       pos_type cursor_vpos = 0;
+       float x;
+       float fill_separator;
+       float fill_hfill;
+       float fill_label_hfill;
+       // This call HAS to be here because of the BidiTables!!!
+       prepareToPrint(bview, row, x, fill_separator, fill_hfill,
+                      fill_label_hfill);
+
        if (last < row->pos())
                cursor_vpos = row->pos();
        else if (pos > last && !boundary)
@@ -2122,7 +2144,7 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par,
                main_body = 0;
 
        for (pos_type vpos = row->pos(); vpos < cursor_vpos; ++vpos) {
-               pos = vis2log(vpos);
+               pos_type pos = vis2log(vpos);
                if (main_body > 0 && pos == main_body - 1) {
                        x += fill_label_hfill +
                                lyxfont::width(textclasslist[
@@ -2146,10 +2168,7 @@ void LyXText::setCursor(BufferView * bview, LyXCursor & cur, Paragraph * par,
                } else
                        x += singleWidth(bview, row->par(), pos);
        }
-
-       cur.x(int(x));
-       cur.x_fix(cur.x());
-       cur.row(row);
+       return x;
 }
 
 
@@ -2248,6 +2267,26 @@ void LyXText::setCursorFromCoordinates(BufferView * bview, LyXCursor & cur,
        cur.x(x);
        cur.y(y + row->baseline());
        cur.row(row);
+       Inset * ins;
+       if (row->next() && row->next()->pos() == cur.pos() &&
+               cur.par() == row->next()->par() &&
+               cur.par()->getChar(cur.pos()) == Paragraph::META_INSET &&
+               (ins=cur.par()->getInset(cur.pos())) &&
+               (ins->needFullRow() || ins->display()))
+       {
+               // we enter here if we put the cursor on the end of the row before
+               // a inset which uses a full row and in that case we HAVE to calculate
+               // the right (i) values.
+               pos_type last = rowLastPrintable(row);
+               float x = getCursorX(bview, row->next(), cur.pos(), last, bound);
+               cur.ix(int(x));
+               cur.iy(y + row->height() + row->next()->baseline());
+               cur.irow(row->next());
+       } else {
+               cur.iy(cur.y());
+               cur.ix(cur.x());
+               cur.irow(row);
+       }
        cur.boundary(bound);
 }
 
@@ -2282,18 +2321,51 @@ void LyXText::cursorRight(BufferView * bview, bool internal) const
 }
 
 
-void LyXText::cursorUp(BufferView * bview) const
+void LyXText::cursorUp(BufferView * bview, bool selecting) const
 {
+#if 1
+       int x = cursor.x_fix();
+       int y = cursor.y() - cursor.row()->baseline() - 1;
+       setCursorFromCoordinates(bview, x, y);
+       if (!selecting) {
+               int y1 = cursor.iy() - first_y;
+               int y2 = y1;
+               y -= first_y;
+               Inset * inset_hit =
+                       bview->checkInsetHit(const_cast<LyXText *>(this), x, y1);
+               if (inset_hit && isHighlyEditableInset(inset_hit)) {
+                       inset_hit->edit(bview, x, y - (y2 - y1), 0);
+               }
+       }
+#else
        setCursorFromCoordinates(bview, cursor.x_fix(),
                                 cursor.y() - cursor.row()->baseline() - 1);
+#endif
 }
 
 
-void LyXText::cursorDown(BufferView * bview) const
+void LyXText::cursorDown(BufferView * bview, bool selecting) const
 {
+#if 1
+       int x = cursor.x_fix();
+       int y = cursor.y() - cursor.row()->baseline() +
+               cursor.row()->height() + 1;
+       setCursorFromCoordinates(bview, x, y);
+       if (!selecting && cursor.row() == cursor.irow()) {
+               int y1 = cursor.iy() - first_y;
+               int y2 = y1;
+               y -= first_y;
+               Inset * inset_hit =
+                       bview->checkInsetHit(const_cast<LyXText *>(this), x, y1);
+               if (inset_hit && isHighlyEditableInset(inset_hit)) {
+                       inset_hit->edit(bview, x, y - (y2 - y1), 0);
+               }
+       }
+#else
        setCursorFromCoordinates(bview, cursor.x_fix(),
                                 cursor.y() - cursor.row()->baseline()
                                 + cursor.row()->height() + 1);
+#endif
 }