]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView_pimpl.C
Switch from SigC signals to boost::signals
[lyx.git] / src / BufferView_pimpl.C
index 1a43fd4abc4050bdf1ec6dd6084f3968a9a4dca5..e0a6b0157c7ba363054001552e6be7770a18d58f 100644 (file)
@@ -5,16 +5,15 @@
 #endif
 
 #include "BufferView_pimpl.h"
-#include "WorkArea.h"
-#include "lyxscreen.h"
+#include "frontends/WorkArea.h"
+#include "frontends/screen.h"
 #include "lyxtext.h"
 #include "lyxrow.h"
 #include "paragraph.h"
-#include "LyXView.h"
+#include "frontends/LyXView.h"
 #include "commandtags.h"
 #include "lyxfunc.h"
 #include "debug.h"
-#include "font.h"
 #include "bufferview_funcs.h"
 #include "TextCache.h"
 #include "bufferlist.h"
@@ -67,6 +66,8 @@
 #include "support/filetools.h"
 #include "support/lyxfunctional.h"
 
+#include <boost/bind.hpp>
+
 #include <ctime>
 #include <unistd.h>
 #include <sys/wait.h>
@@ -82,7 +83,6 @@ using std::pair;
 using std::endl;
 using std::make_pair;
 using std::min;
-using SigC::slot;
 
 using lyx::pos_type;
 using lyx::textclass_type;
@@ -132,33 +132,31 @@ BufferView::Pimpl::Pimpl(BufferView * b, LyXView * o,
          inset_slept(false)
 {
        // Setup the signals
-       workarea_.scrollCB.connect(slot(this, &BufferView::Pimpl::scrollCB));
+       workarea_.scrollCB.connect(boost::bind(&BufferView::Pimpl::scrollCB, this, _1));
        workarea_.workAreaExpose
-               .connect(slot(this, &BufferView::Pimpl::workAreaExpose));
+               .connect(boost::bind(&BufferView::Pimpl::workAreaExpose, this));
        workarea_.workAreaEnter
-               .connect(slot(this, &BufferView::Pimpl::enterView));
+               .connect(boost::bind(&BufferView::Pimpl::enterView, this));
        workarea_.workAreaLeave
-               .connect(slot(this, &BufferView::Pimpl::leaveView));
+               .connect(boost::bind(&BufferView::Pimpl::leaveView, this));
        workarea_.workAreaButtonPress
-               .connect(slot(this, &BufferView::Pimpl::workAreaButtonPress));
+               .connect(boost::bind(&BufferView::Pimpl::workAreaButtonPress, this, _1, _2, _3));
        workarea_.workAreaButtonRelease
-               .connect(slot(this,
-                             &BufferView::Pimpl::workAreaButtonRelease));
+               .connect(boost::bind(&BufferView::Pimpl::workAreaButtonRelease, this, _1, _2, _3));
        workarea_.workAreaMotionNotify
-               .connect(slot(this, &BufferView::Pimpl::workAreaMotionNotify));
+               .connect(boost::bind(&BufferView::Pimpl::workAreaMotionNotify, this, _1, _2, _3));
        workarea_.workAreaDoubleClick
-               .connect(slot(this, &BufferView::Pimpl::doubleClick));
+               .connect(boost::bind(&BufferView::Pimpl::doubleClick, this, _1, _2, _3));
        workarea_.workAreaTripleClick
-               .connect(slot(this, &BufferView::Pimpl::tripleClick));
+               .connect(boost::bind(&BufferView::Pimpl::tripleClick, this, _1, _2, _3));
        workarea_.workAreaKeyPress
-               .connect(slot(this, &BufferView::Pimpl::workAreaKeyPress));
+               .connect(boost::bind(&BufferView::Pimpl::workAreaKeyPress, this, _1, _2));
        workarea_.selectionRequested
-               .connect(slot(this, &BufferView::Pimpl::selectionRequested));
+               .connect(boost::bind(&BufferView::Pimpl::selectionRequested, this));
        workarea_.selectionLost
-               .connect(slot(this, &BufferView::Pimpl::selectionLost));
+               .connect(boost::bind(&BufferView::Pimpl::selectionLost, this));
 
-       cursor_timeout.timeout.connect(slot(this,
-                                           &BufferView::Pimpl::cursorToggle));
+       cursor_timeout.timeout.connect(boost::bind(&BufferView::Pimpl::cursorToggle, this));
        cursor_timeout.start();
        workarea_.setFocus();
        saved_positions.resize(saved_positions_num);
@@ -176,7 +174,9 @@ void BufferView::Pimpl::buffer(Buffer * b)
        lyxerr[Debug::INFO] << "Setting buffer in BufferView ("
                            << b << ")" << endl;
        if (buffer_) {
+#if 0
                insetSleep();
+#endif
                buffer_->delUser(bv_);
 
                // Put the old text into the TextCache, but
@@ -222,7 +222,9 @@ void BufferView::Pimpl::buffer(Buffer * b)
                // require bv_->text.
                owner_->getDialogs()->updateBufferDependent(true);
                redraw();
+#if 0
                insetWakeup();
+#endif
        } else {
                lyxerr[Debug::INFO] << "  No Buffer!" << endl;
                owner_->updateMenubar();
@@ -326,10 +328,12 @@ int BufferView::Pimpl::resizeCurrentBuffer()
                selection = bv_->text->selection.set();
                mark_set = bv_->text->selection.mark();
                the_locking_inset = bv_->theLockingInset();
+               buffer_->resizeInsets(bv_);
+               // I don't think the delete and new are necessary here we just could
+               // call only init! (Jug 20020419)
                delete bv_->text;
                bv_->text = new LyXText(bv_);
                bv_->text->init(bv_);
-               buffer_->resizeInsets(bv_);
        } else {
                // See if we have a text in TextCache that fits
                // the new buffer_ with the correct width.
@@ -470,19 +474,24 @@ void BufferView::Pimpl::scrollCB(double value)
 
 int BufferView::Pimpl::scrollUp(long time)
 {
-       if (!buffer_) return 0;
-       if (!screen_.get()) return 0;
+       if (!buffer_ || !screen_.get())
+               return 0;
 
        double value = workarea_.getScrollbarValue();
 
-       if (value == 0) return 0;
+       if (value == 0)
+               return 0;
 
+#if 1
        float add_value =  (bv_->text->defaultHeight()
                            + float(time) * float(time) * 0.125);
 
        if (add_value > workarea_.height())
                add_value = float(workarea_.height() -
                                  bv_->text->defaultHeight());
+#else
+       float add_value =  float(workarea_.height()) * float(time) / 100;
+#endif
 
        value -= add_value;
 
@@ -498,21 +507,26 @@ int BufferView::Pimpl::scrollUp(long time)
 
 int BufferView::Pimpl::scrollDown(long time)
 {
-       if (!buffer_) return 0;
-       if (!screen_.get()) return 0;
+       if (!buffer_ || !screen_.get())
+               return 0;
 
        double value = workarea_.getScrollbarValue();
        pair<float, float> p = workarea_.getScrollbarBounds();
        double const max = p.second;
 
-       if (value == max) return 0;
+       if (value == max)
+               return 0;
 
+#if 1
        float add_value =  (bv_->text->defaultHeight()
                            + float(time) * float(time) * 0.125);
 
        if (add_value > workarea_.height())
                add_value = float(workarea_.height() -
                                  bv_->text->defaultHeight());
+#else
+       float add_value =  float(workarea_.height()) * float(time) / 100;
+#endif
 
        value += add_value;
 
@@ -526,16 +540,16 @@ int BufferView::Pimpl::scrollDown(long time)
 }
 
 
-void BufferView::Pimpl::workAreaKeyPress(KeySym keysym, unsigned int state)
+void BufferView::Pimpl::workAreaKeyPress(KeySym keysym, key_modifier::state state)
 {
        bv_->owner()->getLyXFunc()->processKeySym(keysym, state);
 }
 
 
-void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state)
+void BufferView::Pimpl::workAreaMotionNotify(int x, int y, mouse_button::state state)
 {
        // Only use motion with button 1
-       if (!(state & Button1MotionMask))
+       if (!(state & mouse_button::button1))
                return;
 
        if (!buffer_ || !screen_.get()) return;
@@ -564,8 +578,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
@@ -579,31 +612,35 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state)
 
 // Single-click on work area
 void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos,
-                                           unsigned int button)
+                                           mouse_button::state button)
 {
        if (!buffer_ || !screen_.get())
                return;
 
-       Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos);
-
        // ok ok, this is a hack.
-       if (button == 4 || button == 5) {
-               switch (button) {
-               case 4:
-                       scrollUp(lyxrc.wheel_jump); // default 100, set in lyxrc
-                       break;
-               case 5:
-                       scrollDown(lyxrc.wheel_jump);
-                       break;
-               }
+
+       if (button == mouse_button::button4) {
+               scrollUp(lyxrc.wheel_jump);
+               // We shouldn't go further down as we really should only do the
+               // scrolling and be done with this. Otherwise we may open some
+               // dialogs (Jug 20020424).
+               return;
+       } else if (button == mouse_button::button5) {
+               scrollDown(lyxrc.wheel_jump);
+               // We shouldn't go further down as we really should only do the
+               // scrolling and be done with this. Otherwise we may open some
+               // dialogs (Jug 20020424).
+               return;
        }
 
+       Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos);
+
        // Middle button press pastes if we have a selection
        // We do this here as if the selection was inside an inset
        // it could get cleared on the unlocking of the inset so
        // we have to check this first
        bool paste_internally = false;
-       if (button == 2 && bv_->getLyXText()->selection.set()) {
+       if (button == mouse_button::button2 && bv_->getLyXText()->selection.set()) {
                owner_->getLyXFunc()->dispatch(LFUN_COPY);
                paste_internally = true;
        }
@@ -654,7 +691,7 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos,
        // 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) {
+       if (button == mouse_button::button3) {
                selection_possible = false;
                return;
        }
@@ -673,7 +710,7 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos,
        // Insert primary selection with middle mouse
        // if there is a local selection in the current buffer,
        // insert this
-       if (button == 2) {
+       if (button == mouse_button::button2) {
                if (paste_internally)
                        owner_->getLyXFunc()->dispatch(LFUN_PASTE);
                else
@@ -685,9 +722,8 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos,
 }
 
 
-void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, unsigned int button)
+void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, mouse_button::state button)
 {
-       // select a word
        if (!buffer_)
                return;
 
@@ -696,7 +732,7 @@ void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, unsigned int button)
        if (text->bv_owner && bv_->theLockingInset())
                return;
 
-       if (screen_.get() && button == 1) {
+       if (screen_.get() && button == mouse_button::button1) {
                if (text->bv_owner) {
                        screen_->hideCursor();
                        screen_->toggleSelection(text, bv_);
@@ -712,9 +748,8 @@ void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, unsigned int button)
 }
 
 
-void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, unsigned int button)
+void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, mouse_button::state button)
 {
-       // select a line
        if (!buffer_)
                return;
 
@@ -723,7 +758,7 @@ void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, unsigned int button)
        if (text->bv_owner && bv_->theLockingInset())
            return;
 
-       if (screen_.get() && (button == 1)) {
+       if (screen_.get() && (button == mouse_button::button1)) {
                if (text->bv_owner) {
                        screen_->hideCursor();
                        screen_->toggleSelection(text, bv_);
@@ -799,9 +834,11 @@ void BufferView::Pimpl::leaveView()
 
 
 void BufferView::Pimpl::workAreaButtonRelease(int x, int y,
-                                             unsigned int button)
+                                             mouse_button::state button)
 {
-       if (!buffer_ || !screen_.get()) return;
+       // do nothing if we used the mouse wheel
+       if (!buffer_ || !screen_.get() || button == mouse_button::button4 || button == mouse_button::button5)
+               return;
 
        // If we hit an inset, we have the inset coordinates in these
        // and inset_hit points to the inset.  If we do not hit an
@@ -821,11 +858,11 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y,
 
        selection_possible = false;
 
-       if (button == 2)
+       if (button == mouse_button::button2)
                return;
 
        // finish selection
-       if (button == 1) {
+       if (button == mouse_button::button1) {
                workarea_.haveSelection(bv_->getLyXText()->selection.set());
        }
 
@@ -891,7 +928,7 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y,
        // Maybe we want to edit a bibitem ale970302
        if (bv_->text->cursor.par()->bibkey && x < 20 +
            bibitemMaxWidth(bv_, textclasslist[buffer_->params.textclass].defaultfont())) {
-               bv_->text->cursor.par()->bibkey->edit(bv_, 0, 0, 0);
+               bv_->text->cursor.par()->bibkey->edit(bv_, 0, 0, mouse_button::none);
        }
 
        return;
@@ -1050,12 +1087,19 @@ void BufferView::Pimpl::update()
                screen_->update(bv_->text, bv_);
                bool fitc = false;
                while (bv_->text->status() == LyXText::CHANGED_IN_DRAW) {
-                       if (bv_->text->fullRebreak(bv_)) {
-                               st = LyXText::NEED_MORE_REFRESH;
-                               bv_->text->setCursor(bv_, bv_->text->cursor.par(),
-                                                                        bv_->text->cursor.pos());
-                               fitc = true;
+                       bv_->text->fullRebreak(bv_);
+                       st = LyXText::NEED_MORE_REFRESH;
+                       bv_->text->setCursor(bv_, bv_->text->cursor.par(),
+                                            bv_->text->cursor.pos());
+                       if (bv_->text->selection.set()) {
+                               bv_->text->setCursor(bv_, bv_->text->selection.start,
+                                                    bv_->text->selection.start.par(),
+                                                    bv_->text->selection.start.pos());
+                               bv_->text->setCursor(bv_, bv_->text->selection.end,
+                                                    bv_->text->selection.end.par(),
+                                                    bv_->text->selection.end.pos());
                        }
+                       fitc = true;
                        bv_->text->status(bv_, st);
                        screen_->update(bv_->text, bv_);
                }
@@ -1161,32 +1205,50 @@ 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_, 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) {
-               int new_y = bv_->text->cursor.iy()
-                       + bv_->theLockingInset()->insetInInsetY()
-                       + y
-                       + text->cursor.row()->height()
-                       - workarea_.height() + 1;
-
-               screen_->draw(bv_->text, bv_, new_y < 0 ? 0 : new_y);
-       } else if (text->cursor.row()->height() < workarea_.height()) {
-               screen_->draw(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();
 }
@@ -1194,8 +1256,16 @@ void BufferView::Pimpl::cursorPrevious(LyXText * text)
 
 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 && !text->first_y) {
@@ -1208,18 +1278,31 @@ void BufferView::Pimpl::cursorNext(LyXText * text)
        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) {
-               screen_->draw(bv_->text, bv_,
-                             bv_->text->cursor.iy()
-                                 + bv_->theLockingInset()->insetInInsetY()
-                                 + y - text->cursor.row()->baseline());
-       } else if (text->cursor.row()->height() < workarea_.height()) {
-               screen_->draw(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();
 }
@@ -1302,7 +1385,10 @@ void BufferView::Pimpl::setState()
                return;
 
        LyXText * text = bv_->getLyXText();
-       if (text->real_current_font.isRightToLeft()) {
+       if (text->real_current_font.isRightToLeft()
+           && !(bv_->theLockingInset()
+                && bv_->theLockingInset()->lyxCode()== Inset::ERT_CODE))
+       {
                if (owner_->getIntl()->keymap == Intl::PRIMARY)
                        owner_->getIntl()->KeyMapSec();
        } else {
@@ -1312,6 +1398,7 @@ void BufferView::Pimpl::setState()
 }
 
 
+#if 0
 void BufferView::Pimpl::insetSleep()
 {
        if (bv_->theLockingInset() && !inset_slept) {
@@ -1329,6 +1416,7 @@ void BufferView::Pimpl::insetWakeup()
                inset_slept = false;
        }
 }
+#endif
 
 
 void BufferView::Pimpl::insetUnlock()
@@ -1437,6 +1525,7 @@ void BufferView::Pimpl::pasteClipboard(bool asPara)
        } else {
                bv_->getLyXText()->insertStringAsLines(bv_, clip);
        }
+       bv_->getLyXText()->clearSelection();
        update(bv_->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
 }
 
@@ -1454,7 +1543,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();
 
@@ -1466,7 +1555,14 @@ 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();
+       } else if (bv_->text->status() != LyXText::UNCHANGED) {
+               bv_->theLockingInset()->hideInsetCursor(bv_);
+               update(bv_->text, BufferView::SELECT|BufferView::FITCUR);
                showCursor();
        }
 
@@ -1561,6 +1657,8 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
        lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch: action["
                              << action <<"] arg[" << argument << "]" << endl;
 
+       LyXTextClass const & tclass = textclasslist[buffer_->params.textclass];
+
        switch (action) {
                // --- Misc -------------------------------------------
        case LFUN_APPENDIX:
@@ -1581,7 +1679,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
                InsetCommandParams p;
                p.setCmdName("tableofcontents");
                Inset * inset = new InsetTOC(p);
-               if (!insertInset(inset, "Standard"))
+               if (!insertInset(inset, tclass.defaultLayoutName()))
                        delete inset;
                break;
        }
@@ -1706,17 +1804,25 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
                lyxerr[Debug::INFO] << "LFUN_LAYOUT: (arg) "
                                    << argument << endl;
 
+               // This is not the good solution to the empty argument
+               // problem, but it will hopefully suffice for 1.2.0.
+               // The correct solution would be to augument the
+               // function list/array with information about what
+               // functions needs arguments and their type.
+               if (argument.empty()) {
+                       owner_->getLyXFunc()->setErrorMessage(
+                               _("LyX function 'layout' needs an argument."));
+                       break;
+               }
+
                // Derive layout number from given argument (string)
                // and current buffer's textclass (number). */
-               textclass_type tclass = buffer_->params.textclass;
-               bool hasLayout =
-                       textclasslist[tclass].hasLayout(argument);
+               bool hasLayout = tclass.hasLayout(argument);
                string layout = argument;
 
                // If the entry is obsolete, use the new one instead.
                if (hasLayout) {
-                       string const & obs = textclasslist[tclass][layout]
-                               .obsoleted_by();
+                       string const & obs = tclass[layout].obsoleted_by();
                        if (!obs.empty())
                                layout = obs;
                }
@@ -1728,8 +1834,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,
@@ -2042,7 +2161,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;
@@ -2056,7 +2175,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;
@@ -2209,7 +2328,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();
@@ -2222,7 +2341,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();
@@ -2373,6 +2492,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
                       BufferView::SELECT
                       | BufferView::FITCUR
                       | BufferView::CHANGE);
+               lt->setCursor(bv_, lt->cursor.par(), lt->cursor.pos());
                moveCursorUpdate(false);
        }
        break;
@@ -2381,7 +2501,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
        {
                LyXText * lt = bv_->getLyXText();
 
-               LyXLayout const & style = textclasslist[buffer_->params.textclass][lt->cursor.par()->layout()];
+               LyXLayout const & style = tclass[lt->cursor.par()->layout()];
 
                if (style.free_spacing) {
                        lt->insertChar(bv_, ' ');
@@ -2821,23 +2941,17 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
                break;
 
        case LFUN_INSET_WIDE_FLOAT:
-       {
                // check if the float type exist
                if (floatList.typeExist(argument)) {
                        InsetFloat * new_inset =
                                new InsetFloat(buffer_->params, argument);
                        new_inset->wide(true);
-                       if (insertInset(new_inset))
-                               new_inset->edit(bv_);
-                       else
-                               delete new_inset;
+                       insertAndEditInset(new_inset);
                } else {
                        lyxerr << "Non-existent float type: "
                               << argument << endl;
                }
-
-       }
-       break;
+               break;
 
 #if 0
        case LFUN_INSET_LIST:
@@ -3108,7 +3222,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
        {
                InsetCommandParams p("printindex");
                Inset * inset = new InsetPrintIndex(p);
-               if (!insertInset(inset, "Standard"))
+               if (!insertInset(inset, tclass.defaultLayoutName()))
                        delete inset;
        }
        break;
@@ -3117,7 +3231,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
        {
                InsetCommandParams p("lyxparent", argument);
                Inset * inset = new InsetParent(p, *buffer_);
-               if (!insertInset(inset, "Standard"))
+               if (!insertInset(inset, tclass.defaultLayoutName()))
                        delete inset;
        }
 
@@ -3140,13 +3254,15 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument)
        break;
 
        case LFUN_FLOAT_LIST:
-       {
-               // We should check the argument for validity. (Lgb)
-               Inset * inset = new InsetFloatList(argument);
-               if (!insertInset(inset, "Standard"))
-                       delete inset;
-       }
-       break;
+               if (floatList.typeExist(argument)) {
+                       Inset * inset = new InsetFloatList(argument);
+                       if (!insertInset(inset, tclass.defaultLayoutName()))
+                               delete inset;
+               } else {
+                       lyxerr << "Non-existent float type: "
+                              << argument << endl;
+               }
+               break;
 
        case LFUN_THESAURUS_ENTRY:
        {