]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView_pimpl.C
Call an update before setting the_locking_inset = 0 as otherwise we
[lyx.git] / src / BufferView_pimpl.C
index 56548fbca349b941f8de85ff871ed97aeb767be3..e0e0556d80472192ff04e7f1cf023c09291f71b6 100644 (file)
@@ -412,7 +412,7 @@ void BufferView::Pimpl::updateScrollbar()
 
        lyxerr[Debug::GUI] << "text_height now " << text_height << endl;
        lyxerr[Debug::GUI] << "work_height " << work_height << endl;
+
        /* If the text is smaller than the working area, the scrollbar
         * maximum must be the working area height. No scrolling will
         * be possible */
@@ -435,7 +435,7 @@ void BufferView::Pimpl::updateScrollbar()
 void BufferView::Pimpl::scrollCB(double value)
 {
        lyxerr[Debug::GUI] << "scrollCB of " << value << endl;
+
        if (!buffer_) return;
 
        current_scrollbar_value = long(value);
@@ -547,12 +547,12 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state)
                                                  cursor.par(), cursor.pos());
                int width = bv_->theLockingInset()->width(bv_, font);
                int inset_x = font.isVisibleRightToLeft()
-                       ? cursor.x() - width : cursor.x();
+                       ? cursor.ix() - width : cursor.ix();
                int start_x = inset_x + bv_->theLockingInset()->scroll();
                bv_->theLockingInset()->
                        insetMotionNotify(bv_,
                                          x - start_x,
-                                         y - cursor.y() + bv_->text->first_y,
+                                         y - cursor.iy() + bv_->text->first_y,
                                          state);
                return;
        }
@@ -564,8 +564,27 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state)
                return;
 
        screen_->hideCursor();
-
+#if 0
+       int y_before = bv_->text->cursor.y();
+#endif
+       Row * cursorrow = bv_->text->cursor.row();
        bv_->text->setCursorFromCoordinates(bv_, x, y + bv_->text->first_y);
+#if 0
+       // sorry for this but I have a strange error that the y value jumps at
+       // a certain point. This seems like an error in my xforms library or
+       // in some other local environment, but I would like to leave this here
+       // for the moment until I can remove this (Jug 20020418)
+       if (y_before < bv_->text->cursor.y())
+               lyxerr << y_before << ":" << bv_->text->cursor.y() << endl;
+#endif
+       // This is to allow jumping over large insets
+       if (cursorrow == bv_->text->cursor.row()) {
+               if (y >= int(workarea_.height())) {
+                       bv_->text->cursorDown(bv_, false);
+               } else if (y < 0) {
+                       bv_->text->cursorUp(bv_, false);
+               }
+       }
 
        if (!bv_->text->selection.set())
                update(bv_->text, BufferView::UPDATE); // Maybe an empty line was deleted
@@ -651,6 +670,7 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos,
                inset->insetButtonPress(bv_, xpos, ypos, button);
                return;
        }
+       // I'm not sure we should continue here if we hit an inset (Jug20020403)
 
        // Right click on a footnote flag opens float menu
        if (button == 3) {
@@ -911,13 +931,13 @@ Box BufferView::Pimpl::insetDimensions(LyXText const & text,
 
        int const width = inset.width(bv_, font);
        int const inset_x = font.isVisibleRightToLeft()
-               ? (cursor.x() - width) : cursor.x();
+               ? (cursor.ix() - width) : cursor.ix();
 
        return Box(
                inset_x + inset.scroll(),
                inset_x + width,
-               cursor.y() - inset.ascent(bv_, font),
-               cursor.y() + inset.descent(bv_, font));
+               cursor.iy() - inset.ascent(bv_, font),
+               cursor.iy() + inset.descent(bv_, font));
 }
 
 
@@ -950,7 +970,7 @@ Inset * BufferView::Pimpl::checkInset(LyXText const & text,
 
        x -= b.x1;
        // The origin of an inset is on the baseline
-       y -= (text.cursor.y());
+       y -= text.cursor.iy();
 
        return inset;
 }
@@ -1160,50 +1180,105 @@ void BufferView::Pimpl::cursorToggle()
 
 void BufferView::Pimpl::cursorPrevious(LyXText * text)
 {
-       if (!text->cursor.row()->previous())
+       if (!text->cursor.row()->previous()) {
+               if (text->first_y > 0) {
+                       int new_y = bv_->text->first_y - workarea_.height();
+                       screen_->draw(bv_->text, bv_, new_y < 0 ? 0 : new_y);
+                       updateScrollbar();
+               }
                return;
+       }
 
        int y = text->first_y;
        Row * cursorrow = text->cursor.row();
 
-       text->setCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y);
+       text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y);
        finishUndo();
-       // This is to allow jumping over large insets
-       if ((cursorrow == text->cursor.row()))
-               text->cursorUp(bv_);
-
-       if (text->inset_owner ||
-           text->cursor.row()->height() < workarea_.height())
-               screen_->draw(bv_->text, bv_,
-                             text->cursor.y()
-                             - text->cursor.row()->baseline()
-                             + text->cursor.row()->height()
-                             - workarea_.height() + 1);
+
+       int new_y;
+       if (cursorrow == bv_->text->cursor.row()) {
+               // we have a row which is higher than the workarea so we leave the
+               // cursor on the start of the row and move only the draw up as soon
+               // as we move the cursor or do something while inside the row (it may
+               // span several workarea-heights) we'll move to the top again, but this
+               // is better than just jump down and only display part of the row.
+               new_y = bv_->text->first_y - workarea_.height();
+       } else {
+               if (text->inset_owner) {
+                       new_y = bv_->text->cursor.iy()
+                               + bv_->theLockingInset()->insetInInsetY() + y
+                               + text->cursor.row()->height()
+                               - workarea_.height() + 1;
+               } else {
+                       new_y = text->cursor.y()
+                               - text->cursor.row()->baseline()
+                               + text->cursor.row()->height()
+                               - workarea_.height() + 1;
+               }
+       }
+       screen_->draw(bv_->text, bv_,  new_y < 0 ? 0 : new_y);
+       if (text->cursor.row()->previous()) {
+               LyXCursor cur;
+               text->setCursor(bv_, cur, text->cursor.row()->previous()->par(),
+                                               text->cursor.row()->previous()->pos(), false);
+               if (cur.y() > text->first_y) {
+                       text->cursorUp(bv_, true);
+               }
+       }
        updateScrollbar();
 }
 
 
 void BufferView::Pimpl::cursorNext(LyXText * text)
 {
-       if (!text->cursor.row()->next())
+       if (!text->cursor.row()->next()) {
+               int y = text->cursor.y() - text->cursor.row()->baseline() +
+                       text->cursor.row()->height();
+               if (y > int(text->first_y + workarea_.height())) {
+                       screen_->draw(bv_->text, bv_,
+                                                 bv_->text->first_y + workarea_.height());
+                       updateScrollbar();
+               }
                return;
+       }
 
        int y = text->first_y + workarea_.height();
-//     if (text->inset_owner)
-//             y += bv_->text->first;
+       if (text->inset_owner && !text->first_y) {
+               y -= (bv_->text->cursor.iy()
+                         - bv_->text->first_y
+                         + bv_->theLockingInset()->insetInInsetY());
+       }
        text->getRowNearY(y);
 
        Row * cursorrow = text->cursor.row();
        text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y); // + workarea_->height());
        finishUndo();
-       // This is to allow jumping over large insets
-       if ((cursorrow == bv_->text->cursor.row()))
-               text->cursorDown(bv_);
-
-       if (text->inset_owner ||
-           text->cursor.row()->height() < workarea_.height())
-               screen_->draw(bv_->text, bv_, text->cursor.y() -
-                             text->cursor.row()->baseline());
+       int new_y;
+       if (cursorrow == bv_->text->cursor.row()) {
+               // we have a row which is higher than the workarea so we leave the
+               // cursor on the start of the row and move only the draw down as soon
+               // as we move the cursor or do something while inside the row (it may
+               // span several workarea-heights) we'll move to the top again, but this
+               // is better than just jump down and only display part of the row.
+               new_y = bv_->text->first_y + workarea_.height();
+       } else {                
+               if (text->inset_owner) {
+                       new_y = bv_->text->cursor.iy()
+                               + bv_->theLockingInset()->insetInInsetY()
+                               + y - text->cursor.row()->baseline();
+               } else {
+                       new_y =  text->cursor.y() - text->cursor.row()->baseline();
+               }
+       }
+       screen_->draw(bv_->text, bv_, new_y);
+       if (text->cursor.row()->next()) {
+               LyXCursor cur;
+               text->setCursor(bv_, cur, text->cursor.row()->next()->par(),
+                                               text->cursor.row()->next()->pos(), false);
+               if (cur.y() < int(text->first_y + workarea_.height())) {
+                       text->cursorDown(bv_, true);
+               }
+       }
        updateScrollbar();
 }
 
@@ -1437,7 +1512,7 @@ void BufferView::Pimpl::stuffClipboard(string const & stuff) const
 
 
 inline
-void BufferView::Pimpl::moveCursorUpdate(bool selecting)
+void BufferView::Pimpl::moveCursorUpdate(bool selecting, bool fitcur)
 {
        LyXText * lt = bv_->getLyXText();
 
@@ -1449,7 +1524,10 @@ void BufferView::Pimpl::moveCursorUpdate(bool selecting)
                        updateInset(lt->inset_owner, false);
        }
        if (lt->bv_owner) {
-               update(lt, BufferView::SELECT|BufferView::FITCUR);
+               if (fitcur)
+                       update(lt, BufferView::SELECT|BufferView::FITCUR);
+               else
+                       update(lt, BufferView::SELECT);
                showCursor();
        }
 
@@ -1711,8 +1789,21 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
                        break;
                }
 
-               if (current_layout != layout) {
-                       LyXText * lt = bv_->getLyXText();
+               bool change_layout = (current_layout != layout);
+               LyXText * lt = bv_->getLyXText();
+               if (!change_layout && lt->selection.set() &&
+                       lt->selection.start.par() != lt->selection.end.par())
+               {
+                       Paragraph * spar = lt->selection.start.par();
+                       Paragraph * epar = lt->selection.end.par()->next();
+                       while(spar != epar) {
+                               if (spar->layout() != current_layout) {
+                                       change_layout = true;
+                                       break;
+                               }
+                       }
+               }
+               if (change_layout) {
                        hideCursor();
                        current_layout = layout;
                        update(lt,
@@ -2025,7 +2116,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
                update(lt, BufferView::UPDATE);
                cursorPrevious(lt);
                finishUndo();
-               moveCursorUpdate(false);
+               moveCursorUpdate(false, false);
                owner_->showState();
        }
        break;
@@ -2039,7 +2130,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
                update(lt, BufferView::UPDATE);
                cursorNext(lt);
                finishUndo();
-               moveCursorUpdate(false);
+               moveCursorUpdate(false, false);
                owner_->showState();
        }
        break;
@@ -2192,7 +2283,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
 
                update(lt,
                       BufferView::SELECT|BufferView::FITCUR);
-               lt->cursorUp(bv_);
+               lt->cursorUp(bv_, true);
                finishUndo();
                moveCursorUpdate(true);
                owner_->showState();
@@ -2205,7 +2296,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
 
                update(lt,
                       BufferView::SELECT|BufferView::FITCUR);
-               lt->cursorDown(bv_);
+               lt->cursorDown(bv_, true);
                finishUndo();
                moveCursorUpdate(true);
                owner_->showState();