]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView_pimpl.C
fix arabtex-related problems (bug 1225 and bug 1404)
[lyx.git] / src / BufferView_pimpl.C
index 72bc9ec1547c28ea5f03a22292d927e250355138..8144d511db9e24e0b42bd82ad1f4d0b78a362095 100644 (file)
@@ -4,7 +4,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Asger Alstrup
- * \author Alfredo Braustein
+ * \author Alfredo Braunstein
  * \author Lars Gullik Bjønnes
  * \author Jean-Marc Lasgouttes
  * \author Angus Leeming
 #include "factory.h"
 #include "FloatList.h"
 #include "funcrequest.h"
+#include "FuncStatus.h"
 #include "gettext.h"
 #include "intl.h"
-#include "iterators.h"
+#include "insetiterator.h"
 #include "lyx_cb.h" // added for Dispatch functions
 #include "lyx_main.h"
 #include "lyxfind.h"
 #include "paragraph.h"
 #include "paragraph_funcs.h"
 #include "ParagraphParameters.h"
+#include "pariterator.h"
+#include "rowpainter.h"
 #include "undo.h"
 #include "vspace.h"
 
-#include "insets/insetfloatlist.h"
 #include "insets/insetref.h"
+#include "insets/insettext.h"
 
 #include "frontends/Alert.h"
 #include "frontends/Dialogs.h"
 
 #include "graphics/Previews.h"
 
-#include "mathed/formulabase.h"
-
 #include "support/filetools.h"
+#include "support/forkedcontr.h"
+#include "support/globbing.h"
 #include "support/path_defines.h"
 #include "support/tostr.h"
+#include "support/types.h"
 
 #include <boost/bind.hpp>
 
-using bv_funcs::currentState;
-
 using lyx::pos_type;
 
 using lyx::support::AddPath;
 using lyx::support::bformat;
+using lyx::support::FileFilterList;
 using lyx::support::FileSearch;
+using lyx::support::ForkedcallsController;
 using lyx::support::IsDirWriteable;
 using lyx::support::MakeDisplayPath;
 using lyx::support::strToUnsignedInt;
 using lyx::support::system_lyxdir;
 
 using std::endl;
+using std::istringstream;
 using std::make_pair;
 using std::min;
 using std::string;
@@ -109,11 +114,13 @@ boost::signals::connection lostcon;
 } // anon namespace
 
 
-BufferView::Pimpl::Pimpl(BufferView * bv, LyXView * owner,
+BufferView::Pimpl::Pimpl(BufferView & bv, LyXView * owner,
             int xpos, int ypos, int width, int height)
-       : bv_(bv), owner_(owner), buffer_(0), cursor_timeout(400),
+       : bv_(&bv), owner_(owner), buffer_(0), cursor_timeout(400),
          using_xterm_cursor(false), cursor_(bv)
 {
+       xsel_cache_.set = false;
+
        workarea_.reset(WorkAreaFactory::create(xpos, ypos, width, height));
        screen_.reset(LyXScreenFactory::create(workarea()));
 
@@ -156,13 +163,33 @@ void BufferView::Pimpl::connectBuffer(Buffer & buf)
        if (errorConnection_.connected())
                disconnectBuffer();
 
-       errorConnection_ = buf.error.connect(boost::bind(&BufferView::Pimpl::addError, this, _1));
-       messageConnection_ = buf.message.connect(boost::bind(&LyXView::message, owner_, _1));
-       busyConnection_ = buf.busy.connect(boost::bind(&LyXView::busy, owner_, _1));
-       titleConnection_ = buf.updateTitles.connect(boost::bind(&LyXView::updateWindowTitle, owner_));
-       timerConnection_ = buf.resetAutosaveTimers.connect(boost::bind(&LyXView::resetAutosaveTimer, owner_));
-       readonlyConnection_ = buf.readonly.connect(boost::bind(&BufferView::Pimpl::showReadonly, this, _1));
-       closingConnection_ = buf.closing.connect(boost::bind(&BufferView::Pimpl::buffer, this, (Buffer *)0));
+       errorConnection_ =
+               buf.error.connect(
+                       boost::bind(&BufferView::Pimpl::addError, this, _1));
+
+       messageConnection_ =
+               buf.message.connect(
+                       boost::bind(&LyXView::message, owner_, _1));
+
+       busyConnection_ =
+               buf.busy.connect(
+                       boost::bind(&LyXView::busy, owner_, _1));
+
+       titleConnection_ =
+               buf.updateTitles.connect(
+                       boost::bind(&LyXView::updateWindowTitle, owner_));
+
+       timerConnection_ =
+               buf.resetAutosaveTimers.connect(
+                       boost::bind(&LyXView::resetAutosaveTimer, owner_));
+
+       readonlyConnection_ =
+               buf.readonly.connect(
+                       boost::bind(&BufferView::Pimpl::showReadonly, this, _1));
+
+       closingConnection_ =
+               buf.closing.connect(
+                       boost::bind(&BufferView::Pimpl::setBuffer, this, (Buffer *)0));
 }
 
 
@@ -178,13 +205,10 @@ void BufferView::Pimpl::disconnectBuffer()
 }
 
 
-bool BufferView::Pimpl::newFile(string const & filename,
-                               string const & tname,
-                               bool isNamed)
+void BufferView::Pimpl::newFile(string const & filename, string const & tname,
+       bool isNamed)
 {
-       Buffer * b = ::newFile(filename, tname, isNamed);
-       buffer(b);
-       return true;
+       setBuffer(::newFile(filename, tname, isNamed));
 }
 
 
@@ -209,14 +233,13 @@ bool BufferView::Pimpl::loadLyXFile(string const & filename, bool tolastfiles)
                        text, 0, 1,  _("&Revert"), _("&Switch to document"));
 
                if (ret != 0) {
-                       buffer(bufferlist.getBuffer(s));
+                       setBuffer(bufferlist.getBuffer(s));
                        return true;
-               } else {
-                       // FIXME: should be LFUN_REVERT
-                       if (!bufferlist.close(bufferlist.getBuffer(s), false))
-                               return false;
-                       // Fall through to new load. (Asger)
                }
+               // FIXME: should be LFUN_REVERT
+               if (!bufferlist.close(bufferlist.getBuffer(s), false))
+                       return false;
+               // Fall through to new load. (Asger)
        }
 
        Buffer * b;
@@ -241,7 +264,7 @@ bool BufferView::Pimpl::loadLyXFile(string const & filename, bool tolastfiles)
                        return false;
        }
 
-       buffer(b);
+       setBuffer(b);
        bv_->showErrorList(_("Parse"));
 
        if (tolastfiles)
@@ -281,46 +304,45 @@ int BufferView::Pimpl::top_y() const
 }
 
 
-void BufferView::Pimpl::buffer(Buffer * b)
+void BufferView::Pimpl::setBuffer(Buffer * b)
 {
        lyxerr[Debug::INFO] << "Setting buffer in BufferView ("
                            << b << ')' << endl;
-       if (buffer_) {
+       if (buffer_)
                disconnectBuffer();
-               delete bv_->text;
-               bv_->text = 0;
-       }
 
        // set current buffer
        buffer_ = b;
 
+       // reset old cursor
        top_y_ = 0;
+       cursor_ = LCursor(*bv_);
 
        // if we're quitting lyx, don't bother updating stuff
        if (quitting)
                return;
 
-       // if we are closing the buffer, use the first buffer as current
-       if (!buffer_)
-               buffer_ = bufferlist.first();
-
        if (buffer_) {
                lyxerr[Debug::INFO] << "Buffer addr: " << buffer_ << endl;
                connectBuffer(*buffer_);
 
-               // If we don't have a text object for this, we make one
-               if (bv_->text == 0)
-                       resizeCurrentBuffer();
+               cursor_.push(buffer_->inset());
+               cursor_.resetAnchor();
+               buffer_->text().init(bv_);
 
-               // FIXME: needed when ?
-               fitCursor();
+               // If we don't have a text object for this, we make one
+               //if (bv_->text() == 0)
+               //      resizeCurrentBuffer();
 
                // Buffer-dependent dialogs should be updated or
                // hidden. This should go here because some dialogs (eg ToC)
                // require bv_->text.
                owner_->getDialogs().updateBufferDependent(true);
+               owner_->setLayout(bv_->text()->getPar(0).layout()->name());
        } else {
                lyxerr[Debug::INFO] << "  No Buffer!" << endl;
+               // we are closing the buffer, use the first buffer as current
+               buffer_ = bufferlist.first();
                owner_->getDialogs().hideBufferDependent();
        }
 
@@ -331,30 +353,30 @@ void BufferView::Pimpl::buffer(Buffer * b)
        owner_->updateLayoutChoice();
        owner_->updateWindowTitle();
 
-       // Don't forget to update the Layout
-       if (buffer_)
-               owner_->setLayout(bv_->text->cursorPar()->layout()->name());
-
-       if (lyx::graphics::Previews::activated() && buffer_)
+       if (buffer_ && lyx::graphics::Previews::status() != LyXRC::PREVIEW_OFF)
                lyx::graphics::Previews::get().generateBufferPreviews(*buffer_);
 }
 
 
 bool BufferView::Pimpl::fitCursor()
 {
-       lyxerr << "BufferView::Pimpl::fitCursor." << endl;
-       if (screen().fitCursor(bv_)) {
-               updateScrollbar();
-               return true;
-       }
-       return false;
+       // to get the correct y cursor info
+       lyxerr << "BufferView::fitCursor" << std::endl;
+       lyx::par_type const pit = bv_->cursor().bottom().par();
+       bv_->text()->redoParagraph(pit);
+       refreshPar(*bv_, *bv_->text(), pit);
+
+       if (!screen().fitCursor(bv_))
+               return false;
+       updateScrollbar();
+       return true;
 }
 
 
 void BufferView::Pimpl::redoCurrentBuffer()
 {
        lyxerr[Debug::INFO] << "BufferView::redoCurrentBuffer" << endl;
-       if (buffer_ && bv_->text) {
+       if (buffer_ && bv_->text()) {
                resizeCurrentBuffer();
                updateScrollbar();
                owner_->updateLayoutChoice();
@@ -365,55 +387,15 @@ void BufferView::Pimpl::redoCurrentBuffer()
 void BufferView::Pimpl::resizeCurrentBuffer()
 {
        lyxerr[Debug::INFO] << "resizeCurrentBuffer" << endl;
-
-       int par = -1;
-       int selstartpar = -1;
-       int selendpar = -1;
-
-       pos_type pos = 0;
-       pos_type selstartpos = 0;
-       pos_type selendpos = 0;
-       bool selection = false;
-       bool mark_set  = false;
-
        owner_->busy(true);
-
        owner_->message(_("Formatting document..."));
 
-       if (bv_->text) {
-               par = bv_->text->cursor.par();
-               pos = bv_->text->cursor.pos();
-               selstartpar = bv_->text->selection.start.par();
-               selstartpos = bv_->text->selection.start.pos();
-               selendpar = bv_->text->selection.end.par();
-               selendpos = bv_->text->selection.end.pos();
-               selection = bv_->text->selection.set();
-               mark_set = bv_->text->selection.mark();
-               bv_->text->fullRebreak();
-               update();
-       } else {
-               bv_->text = new LyXText(bv_, 0, false, bv_->buffer()->paragraphs());
-               bv_->text->init(bv_);
-       }
-
-       if (par != -1) {
-               bv_->text->selection.set(true);
-               // At this point just to avoid the Delete-Empty-Paragraph-
-               // Mechanism when setting the cursor.
-               bv_->text->selection.mark(mark_set);
-               if (selection) {
-                       bv_->text->setCursor(selstartpar, selstartpos);
-                       bv_->text->selection.cursor = bv_->text->cursor;
-                       bv_->text->setCursor(selendpar, selendpos);
-                       bv_->text->setSelection();
-                       bv_->text->setCursor(par, pos);
-               } else {
-                       bv_->text->setCursor(par, pos);
-                       bv_->text->selection.cursor = bv_->text->cursor;
-                       bv_->text->selection.set(false);
-               }
-       }
+       LyXText * text = bv_->text();
+       if (!text)
+               return;
 
+       text->init(bv_);
+       update();
        fitCursor();
 
        switchKeyMap();
@@ -428,18 +410,21 @@ void BufferView::Pimpl::resizeCurrentBuffer()
 
 void BufferView::Pimpl::updateScrollbar()
 {
-       if (!bv_->text) {
+       if (!bv_->text()) {
                lyxerr[Debug::GUI] << "no text in updateScrollbar" << endl;
+               lyxerr << "no text in updateScrollbar" << endl;
                workarea().setScrollbarParams(0, 0, 0);
                return;
        }
 
-       LyXText const & t = *bv_->text;
+       LyXText const & t = *bv_->text();
 
-       lyxerr[Debug::GUI] << "Updating scrollbar: h " << t.height << ", top_y() "
-               << top_y() << ", default height " << defaultRowHeight() << endl;
+       lyxerr[Debug::GUI]
+               << "Updating scrollbar: height: " << t.height()
+               << " top_y: " << top_y()
+               << " default height " << defaultRowHeight() << endl;
 
-       workarea().setScrollbarParams(t.height, top_y(), defaultRowHeight());
+       workarea().setScrollbarParams(t.height(), top_y(), defaultRowHeight());
 }
 
 
@@ -462,11 +447,14 @@ void BufferView::Pimpl::scrollDocView(int value)
        int const first = top_y() + height;
        int const last = top_y() + workarea().workHeight() - height;
 
-       LyXText * text = bv_->text;
-       if (text->cursor.y() < first)
-               text->setCursorFromCoordinates(0, first);
-       else if (text->cursor.y() > last)
-               text->setCursorFromCoordinates(0, last);
+       bv_->cursor().reset(bv_->buffer()->inset());
+       LyXText * text = bv_->text();
+       int y = text->cursorY(bv_->cursor().front());
+       if (y < first)
+               y = first;
+       if (y > last)
+               y = last;
+       text->setCursorFromCoordinates(bv_->cursor(), 0, y);
 
        owner_->updateLayoutChoice();
 }
@@ -477,20 +465,20 @@ void BufferView::Pimpl::scroll(int lines)
        if (!buffer_)
                return;
 
-       LyXText const * t = bv_->text;
+       LyXText const * t = bv_->text();
        int const line_height = defaultRowHeight();
 
        // The new absolute coordinate
        int new_top_y = top_y() + lines * line_height;
 
        // Restrict to a valid value
-       new_top_y = std::min(t->height - 4 * line_height, new_top_y);
+       new_top_y = std::min(t->height() - 4 * line_height, new_top_y);
        new_top_y = std::max(0, new_top_y);
 
        scrollDocView(new_top_y);
 
        // Update the scrollbar.
-       workarea().setScrollbarParams(t->height, top_y(), defaultRowHeight());
+       workarea().setScrollbarParams(t->height(), top_y(), defaultRowHeight());
 }
 
 
@@ -520,21 +508,23 @@ void BufferView::Pimpl::selectionRequested()
        if (!available())
                return;
 
-       LyXText * text = bv_->getLyXText();
+       LCursor & cur = bv_->cursor();
 
-       if (text->selection.set() &&
-               (!bv_->text->xsel_cache.set() ||
-                text->selection.start != bv_->text->xsel_cache.start ||
-                text->selection.end != bv_->text->xsel_cache.end))
-       {
-               bv_->text->xsel_cache = text->selection;
-               sel = text->selectionAsString(*bv_->buffer(), false);
-       } else if (!text->selection.set()) {
-               sel = string();
-               bv_->text->xsel_cache.set(false);
+       if (!cur.selection()) {
+               xsel_cache_.set = false;
+               return;
        }
-       if (!sel.empty()) {
-               workarea().putClipboard(sel);
+
+       if (!xsel_cache_.set ||
+           cur.back() != xsel_cache_.cursor ||
+           cur.anchor_.back() != xsel_cache_.anchor)
+       {
+               xsel_cache_.cursor = cur.back();
+               xsel_cache_.anchor = cur.anchor_.back();
+               xsel_cache_.set = cur.selection();
+               sel = cur.selectionAsString(false);
+               if (!sel.empty())
+                       workarea().putClipboard(sel);
        }
 }
 
@@ -543,8 +533,8 @@ void BufferView::Pimpl::selectionLost()
 {
        if (available()) {
                screen().hideCursor();
-               bv_->getLyXText()->clearSelection();
-               bv_->text->xsel_cache.set(false);
+               bv_->cursor().clearSelection();
+               xsel_cache_.set = false;
        }
 }
 
@@ -561,11 +551,9 @@ void BufferView::Pimpl::workAreaResize()
        work_area_width = workarea().workWidth();
        work_area_height = workarea().workHeight();
 
-       if (buffer_ != 0) {
-               if (widthChange) {
-                       // The visible LyXView need a resize
-                       resizeCurrentBuffer();
-               }
+       if (buffer_ && widthChange) {
+               // The visible LyXView need a resize
+               resizeCurrentBuffer();
        }
 
        if (widthChange || heightChange)
@@ -579,41 +567,50 @@ void BufferView::Pimpl::workAreaResize()
 
 void BufferView::Pimpl::update()
 {
-       //lyxerr << "BufferView::update()" << endl;
+       //lyxerr << "BufferView::Pimpl::update(), buffer: " << buffer_ << endl;
        // fix cursor coordinate cache in case something went wrong
 
        // check needed to survive LyX startup
-       if (bv_->getLyXText()) {
+       if (buffer_) {
+               // update macro store
+               buffer_->buildMacros();
+
                // update all 'visible' paragraphs
-               ParagraphList::iterator beg;
-               ParagraphList::iterator end;
+               lyx::par_type beg, end;
                getParsInRange(buffer_->paragraphs(),
                               top_y(), top_y() + workarea().workHeight(),
                               beg, end);
-               bv_->text->redoParagraphs(beg, end);
-               bv_->getLyXText()->redoCursor();
+               bv_->text()->redoParagraphs(beg, end);
+
+               // and the scrollbar
                updateScrollbar();
        }
        screen().redraw(*bv_);
+       bv_->owner()->view_state_changed();
 }
 
 
 // Callback for cursor timer
 void BufferView::Pimpl::cursorToggle()
 {
-       if (!buffer_) {
-               cursor_timeout.restart();
-               return;
+       if (buffer_) {
+               screen().toggleCursor(*bv_);
+
+               // Use this opportunity to deal with any child processes that
+               // have finished but are waiting to communicate this fact
+               // to the rest of LyX.
+               ForkedcallsController & fcc = ForkedcallsController::get();
+               if (fcc.processesCompleted())
+                       fcc.handleCompletedProcesses();
        }
 
-       screen().toggleCursor(*bv_);
        cursor_timeout.restart();
 }
 
 
 bool BufferView::Pimpl::available() const
 {
-       return buffer_ && bv_->text;
+       return buffer_ && bv_->text();
 }
 
 
@@ -623,12 +620,13 @@ Change const BufferView::Pimpl::getCurrentChange()
                return Change(Change::UNCHANGED);
 
        LyXText * text = bv_->getLyXText();
+       LCursor & cur = bv_->cursor();
 
-       if (!text->selection.set())
+       if (!cur.selection())
                return Change(Change::UNCHANGED);
 
-       return text->getPar(text->selection.start)
-               ->lookupChangeFull(text->selection.start.pos());
+       return text->getPar(cur.selBegin().par()).
+                       lookupChangeFull(cur.selBegin().pos());
 }
 
 
@@ -636,9 +634,10 @@ void BufferView::Pimpl::savePosition(unsigned int i)
 {
        if (i >= saved_positions_num)
                return;
+       BOOST_ASSERT(bv_->cursor().inTexted());
        saved_positions[i] = Position(buffer_->fileName(),
-                                     bv_->text->cursorPar()->id(),
-                                     bv_->text->cursor.pos());
+                                     bv_->cursor().paragraph().id(),
+                                     bv_->cursor().pos());
        if (i > 0)
                owner_->message(bformat(_("Saved bookmark %1$s"), tostr(i)));
 }
@@ -651,7 +650,7 @@ void BufferView::Pimpl::restorePosition(unsigned int i)
 
        string const fname = saved_positions[i].filename;
 
-       bv_->text->clearSelection();
+       bv_->cursor().clearSelection();
 
        if (fname != buffer_->fileName()) {
                Buffer * b = 0;
@@ -662,15 +661,15 @@ void BufferView::Pimpl::restorePosition(unsigned int i)
                        ::loadLyXFile(b, fname); // don't ask, just load it
                }
                if (b)
-                       buffer(b);
+                       setBuffer(b);
        }
 
        ParIterator par = buffer_->getParFromID(saved_positions[i].par_id);
        if (par == buffer_->par_iterator_end())
                return;
 
-       bv_->text->setCursor(par.pit(),
-                            min(par->size(), saved_positions[i].par_pos));
+       bv_->text()->setCursor(bv_->cursor(), par.pit(),
+               min(par->size(), saved_positions[i].par_pos));
 
        if (i > 0)
                owner_->message(bformat(_("Moved to bookmark %1$s"), tostr(i)));
@@ -701,11 +700,13 @@ void BufferView::Pimpl::switchKeyMap()
 
 void BufferView::Pimpl::center()
 {
-       LyXText * text = bv_->text;
+       LyXText * text = bv_->text();
 
-       text->clearSelection();
+       bv_->cursor().clearSelection();
        int const half_height = workarea().workHeight() / 2;
-       int new_y = std::max(0, text->cursor.y() - half_height);
+       int new_y = text->cursorY(bv_->cursor().front()) - half_height;
+       if (new_y < 0)
+               new_y = 0;
 
        // FIXME: look at this comment again ...
        // This updates top_y() but means the fitCursor() call
@@ -715,7 +716,7 @@ void BufferView::Pimpl::center()
        // to do it manually. Any operation that does a center()
        // and also might have moved top_y() must make sure to call
        // updateScrollbar() currently. Never mind that this is a
-       // pretty obfuscated way of updating t->top_y()
+       // pretty obfuscated way of updating text->top_y()
        top_y(new_y);
 }
 
@@ -726,58 +727,27 @@ void BufferView::Pimpl::stuffClipboard(string const & stuff) const
 }
 
 
-InsetOld * BufferView::Pimpl::getInsetByCode(InsetOld::Code code)
+InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code code)
 {
-#if 0
-       LyXCursor cursor = bv_->getLyXText()->cursor;
-       Buffer::inset_iterator it =
-               find_if(Buffer::inset_iterator(
-                       cursorPar(), cursor.pos()),
-                       buffer_->inset_iterator_end(),
-                       lyx::compare_memfun(&Inset::lyxCode, code));
-       return it != buffer_->inset_iterator_end() ? (*it) : 0;
-#else
+#ifdef WITH_WARNINGS
+#warning Does not work for mathed. (Still true?)
+#endif
        // Ok, this is a little bit too brute force but it
        // should work for now. Better infrastructure is coming. (Lgb)
-
-       Buffer * b = bv_->buffer();
-       LyXText * text =  bv_->getLyXText();
-
-       Buffer::inset_iterator beg = b->inset_iterator_begin();
-       Buffer::inset_iterator end = b->inset_iterator_end();
-
-       bool cursorPar_seen = false;
-
-       for (; beg != end; ++beg) {
-               if (beg.getPar() == text->cursorPar()) {
-                       cursorPar_seen = true;
-               }
-               if (cursorPar_seen) {
-                       if (beg.getPar() == text->cursorPar()
-                           && beg.getPos() >= text->cursor.pos()) {
-                               break;
-                       } else if (beg.getPar() != text->cursorPar()) {
-                               break;
-                       }
-               }
-
-       }
-       if (beg != end) {
-               // Now find the first inset that matches code.
-               for (; beg != end; ++beg) {
-                       if (beg->lyxCode() == code) {
-                               return &(*beg);
-                       }
-               }
+       LCursor & cur = bv_->cursor();
+       DocIterator it = cur;
+       for (it.forwardInset(); it; it.forwardInset()) {
+               BOOST_ASSERT(it.nextInset());
+               if (it.nextInset()->lyxCode() == code)
+                               return it.nextInset();
        }
        return 0;
-#endif
 }
 
 
-void BufferView::Pimpl::MenuInsertLyXFile(string const & filen)
+void BufferView::Pimpl::MenuInsertLyXFile(string const & filenm)
 {
-       string filename = filen;
+       string filename = filenm;
 
        if (filename.empty()) {
                // Launch a file browser
@@ -799,7 +769,8 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen)
 
                FileDialog::Result result =
                        fileDlg.open(initpath,
-                                      _("*.lyx| LyX Documents (*.lyx)"));
+                                    FileFilterList(_("LyX Documents (*.lyx)")),
+                                    string());
 
                if (result.first == FileDialog::Later)
                        return;
@@ -830,8 +801,8 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen)
 
 void BufferView::Pimpl::trackChanges()
 {
-       Buffer * buf(bv_->buffer());
-       bool const tracking(buf->params().tracking_changes);
+       Buffer * buf = bv_->buffer();
+       bool const tracking = buf->params().tracking_changes;
 
        if (!tracking) {
                ParIterator const end = buf->par_iterator_end();
@@ -843,8 +814,10 @@ void BufferView::Pimpl::trackChanges()
                buf->undostack().clear();
        } else {
                update();
-               bv_->text->setCursor(0, 0);
+               bv_->text()->setCursor(bv_->cursor(), 0, 0);
+#ifdef WITH_WARNINGS
 #warning changes FIXME
+#endif
                bool found = lyx::find::findNextChange(bv_);
                if (found) {
                        owner_->getDialogs().show("changes");
@@ -860,218 +833,208 @@ void BufferView::Pimpl::trackChanges()
        buf->redostack().clear();
 }
 
-#warning remove me
-LCursor theTempCursor(0);
 
-namespace {
-
-       InsetOld * insetFromCoords(BufferView * bv, int x, int y)
-       {
-               LyXText * text = bv->text;
-               InsetOld * inset = 0;
-               theTempCursor = LCursor(bv);
-               while (true) {
-                       InsetOld * inset_hit = text->checkInsetHit(x, y);
-                       if (!inset_hit) {
-                               lyxerr << "no further inset hit" << endl;
-                               break;
-                       }
-                       inset = inset_hit;
-                       if (!inset_hit->descendable()) {
-                               lyxerr << "not descendable" << endl;
-                               break;
-                       }
-                       text = inset_hit->getText(0);
-                       lyxerr << "Hit inset: " << inset << " at x: " << x
-                               << " text: " << text << " y: " << y << endl;
-                       theTempCursor.push(static_cast<UpdatableInset*>(inset));
-               }
-               lyxerr << "theTempCursor: " << theTempCursor << endl;
-               return inset;
+bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
+{
+       //lyxerr << "BufferView::Pimpl::workAreaDispatch: request: "
+       //  << cmd << std::endl;
+       // this is only called for mouse related events including
+       // LFUN_FILE_OPEN generated by drag-and-drop.
+       FuncRequest cmd = cmd0;
+
+       // handle drag&drop
+       if (cmd.action == LFUN_FILE_OPEN) {
+               owner_->dispatch(cmd);
+               return true;
        }
 
-}
+       cmd.y += bv_->top_y();
+       if (!bv_->buffer())
+               return false;
 
+       LCursor cur(*bv_);
+       cur.push(bv_->buffer()->inset());
+       cur.selection() = bv_->cursor().selection();
 
-bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd)
-{
-       switch (cmd.action) {
-       case LFUN_MOUSE_MOTION: {
-               FuncRequest cmd1(cmd, bv_);
-               UpdatableInset * inset = bv_->cursor().innerInset();
-               DispatchResult res;
-               if (inset) {
-                       cmd1.x -= inset->x();
-                       cmd1.y -= inset->y();
-                       res = inset->dispatch(cmd1);
-               } else {
-                       cmd1.y += bv_->top_y();
-                       res = bv_->cursor().innerText()->dispatch(cmd1);
-               }
-                       
-               if (bv_->fitCursor() || res.update()) {
-                       bv_->update();
-                       bv_->cursor().updatePos();
-               }
-               
-               return true;
+       // Doesn't go through lyxfunc, so we need to update
+       // the layout choice etc. ourselves
+
+       // e.g. Qt mouse press when no buffer
+       if (!available())
+               return false;
+
+       screen().hideCursor();
+
+       // Either the inset under the cursor or the
+       // surrounding LyXText will handle this event.
+
+       // Build temporary cursor.
+       InsetBase * inset = bv_->text()->editXY(cur, cmd.x, cmd.y);
+       lyxerr << "hit inset at tip: " << inset << endl;
+       lyxerr << "created temp cursor:\n" << cur << endl;
+
+       // Put anchor at the same position.
+       cur.resetAnchor();
+
+       // Try to dispatch to an non-editable inset near this position
+       // via the temp cursor. If the inset wishes to change the real
+       // cursor it has to do so explicitly by using
+       //  cur.bv().cursor() = cur;  (or similar)'
+       DispatchResult res;
+       if (inset)
+               inset->dispatch(cur, cmd);
+
+       // Now dispatch to the temporary cursor. If the real cursor should
+       // be modified, the inset's dispatch has to do so explicitly.
+       if (!res.dispatched())
+               res = cur.dispatch(cmd);
+
+       if (res.dispatched()) {
+               // Redraw if requested or necessary.
+               if (fitCursor() || res.update())
+                       update();
        }
 
-       case LFUN_MOUSE_PRESS:
-       case LFUN_MOUSE_RELEASE:
-       case LFUN_MOUSE_DOUBLE:
-       case LFUN_MOUSE_TRIPLE: {
-               // We pass those directly to the Bufferview, since
-               // otherwise selection handling breaks down
+       // see workAreaKeyPress
+       cursor_timeout.restart();
+       screen().showCursor(*bv_);
 
-               // Doesn't go through lyxfunc, so we need to update
-               // the layout choice etc. ourselves
+       // skip these when selecting
+       if (cmd.action != LFUN_MOUSE_MOTION) {
+               owner_->updateLayoutChoice();
+               owner_->updateToolbar();
+       }
 
-               // e.g. Qt mouse press when no buffer
-               if (!available())
-                       return false;
+       // slight hack: this is only called currently when we
+       // clicked somewhere, so we force through the display
+       // of the new status here.
+       owner_->clearMessage();
+       return true;
+}
 
-               screen().hideCursor();
 
-               // either the inset under the cursor or the surrounding LyXText will
-               // handle this event.
-
-               // built temporary path to inset
-               InsetOld * inset = insetFromCoords(bv_, cmd.x, cmd.y); 
-               FuncRequest cmd1(cmd, bv_);
-               DispatchResult res;
-
-               // try to dispatch to that inset
-               if (inset) {
-                       FuncRequest cmd2 = cmd1;
-                       lyxerr << "dispatching action " << cmd2.action 
-                              << " to inset " << inset << endl;
-                       cmd2.x -= inset->x();
-                       cmd2.y -= inset->y();
-                       res = inset->dispatch(cmd2);
-                       if (res.update()) {
-                               bv_->update();
-                               bv_->cursor().updatePos();
-                       }
-                       res.update(false);
-                       switch (res.val()) {
-                               case FINISHED:
-                               case FINISHED_RIGHT:
-                               case FINISHED_UP: 
-                               case FINISHED_DOWN:
-                                       theTempCursor.pop();
-                                       bv_->cursor() = theTempCursor;
-                                       bv_->cursor().innerText()->setCursorFromCoordinates(cmd.x, top_y() + cmd.y);
-                                       if (bv_->fitCursor())
-                                               bv_->update();
-                                       return true;
-                               default:
-                                       lyxerr << "not dispatched by inner inset val: " << res.val() << endl;
-                                       break;
-                       }
-               }
+FuncStatus BufferView::Pimpl::getStatus(FuncRequest const & cmd)
+{
+       Buffer * buf = bv_->buffer();
 
-               // otherwise set cursor to surrounding LyXText
-               if (!res.dispatched()) {
-                       lyxerr << "temp cursor is: " << theTempCursor << endl;
-                       lyxerr << "dispatching " << cmd1
-                              << " to surrounding LyXText "
-                              << theTempCursor.innerText() << endl;
-                       bv_->cursor() = theTempCursor;
-                       cmd1.y += bv_->top_y();
-                       res = bv_->cursor().innerText()->dispatch(cmd1);
-                       if (bv_->fitCursor() || res.update())
-                               bv_->update();
-                       
-                       //return DispatchResult(true, true);
-               }
-               // see workAreaKeyPress
-               cursor_timeout.restart();
-               screen().showCursor(*bv_);
+       FuncStatus flag;
 
-               // skip these when selecting
-               if (cmd.action != LFUN_MOUSE_MOTION) {
-                       owner_->updateLayoutChoice();
-                       owner_->updateToolbar();
-               }
+       switch (cmd.action) {
 
-               // slight hack: this is only called currently when we
-               // clicked somewhere, so we force through the display
-               // of the new status here.
-               owner_->clearMessage();
-               return true;
-       }
+       case LFUN_UNDO:
+               flag.enabled(!buf->undostack().empty());
+               break;
+       case LFUN_REDO:
+               flag.enabled(!buf->redostack().empty());
+               break;
+       case LFUN_FILE_INSERT:
+       case LFUN_FILE_INSERT_ASCII_PARA:
+       case LFUN_FILE_INSERT_ASCII:
+       case LFUN_FONT_STATE:
+       case LFUN_INSERT_LABEL:
+       case LFUN_BOOKMARK_SAVE:
+       case LFUN_REF_GOTO:
+       case LFUN_WORD_FIND:
+       case LFUN_WORD_REPLACE:
+       case LFUN_MARK_OFF:
+       case LFUN_MARK_ON:
+       case LFUN_SETMARK:
+       case LFUN_CENTER:
+       case LFUN_BEGINNINGBUFSEL:
+       case LFUN_ENDBUFSEL:
+               flag.enabled(true);
+               break;
+       case LFUN_BOOKMARK_GOTO:
+               flag.enabled(bv_->isSavedPosition(strToUnsignedInt(cmd.argument)));
+               break;
+       case LFUN_TRACK_CHANGES:
+               flag.enabled(true);
+               flag.setOnOff(buf->params().tracking_changes);
+               break;
 
+       case LFUN_MERGE_CHANGES:
+       case LFUN_ACCEPT_CHANGE: // what about these two
+       case LFUN_REJECT_CHANGE: // what about these two
+       case LFUN_ACCEPT_ALL_CHANGES:
+       case LFUN_REJECT_ALL_CHANGES:
+               flag.enabled(buf && buf->params().tracking_changes);
+               break;
        default:
-               owner_->dispatch(cmd);
-               return true;
+               flag.enabled(false);
        }
+
+       return flag;
 }
 
 
-bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
+
+bool BufferView::Pimpl::dispatch(FuncRequest const & cmd)
 {
+       //lyxerr << "BufferView::Pimpl::dispatch  cmd: " << cmd << std::endl;
        // Make sure that the cached BufferView is correct.
-       FuncRequest ev = ev_in;
-       ev.setView(bv_);
-
        lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:"
-               << " action[" << ev.action << ']'
-               << " arg[" << ev.argument << ']'
-               << " x[" << ev.x << ']'
-               << " y[" << ev.y << ']'
-               << " button[" << ev.button() << ']'
+               << " action[" << cmd.action << ']'
+               << " arg[" << cmd.argument << ']'
+               << " x[" << cmd.x << ']'
+               << " y[" << cmd.y << ']'
+               << " button[" << cmd.button() << ']'
                << endl;
 
-       LyXTextClass const & tclass = buffer_->params().getLyXTextClass();
+       LCursor & cur = bv_->cursor();
 
-       switch (ev.action) {
+       switch (cmd.action) {
 
-       case LFUN_SCROLL_INSET:
-               // this is not handled here as this function is only active
-               // if we have a locking_inset and that one is (or contains)
-               // a tabular-inset
+       case LFUN_UNDO:
+               if (available()) {
+                       cur.message(_("Undo"));
+                       cur.clearSelection();
+                       if (!textUndo(*bv_))
+                               cur.message(_("No further undo information"));
+                       update();
+                       switchKeyMap();
+               }
+               break;
+
+       case LFUN_REDO:
+               if (available()) {
+                       cur.message(_("Redo"));
+                       cur.clearSelection();
+                       if (!textRedo(*bv_))
+                               cur.message(_("No further redo information"));
+                       update();
+                       switchKeyMap();
+               }
                break;
 
        case LFUN_FILE_INSERT:
-               MenuInsertLyXFile(ev.argument);
+               MenuInsertLyXFile(cmd.argument);
                break;
 
        case LFUN_FILE_INSERT_ASCII_PARA:
-               InsertAsciiFile(bv_, ev.argument, true);
+               InsertAsciiFile(bv_, cmd.argument, true);
                break;
 
        case LFUN_FILE_INSERT_ASCII:
-               InsertAsciiFile(bv_, ev.argument, false);
+               InsertAsciiFile(bv_, cmd.argument, false);
                break;
 
        case LFUN_FONT_STATE:
-               owner_->getLyXFunc().setMessage(currentState(bv_));
+               cur.message(cur.currentState());
                break;
 
-       case LFUN_INSERT_LABEL: {
-               // Try and generate a valid label
-               string const contents = ev.argument.empty() ?
-                       getPossibleLabel(*bv_) : ev.argument;
-               InsetCommandParams icp("label", contents);
-               string data = InsetCommandMailer::params2string("label", icp);
-               owner_->getDialogs().show("label", data, 0);
-               break;
-       }
-
        case LFUN_BOOKMARK_SAVE:
-               savePosition(strToUnsignedInt(ev.argument));
+               savePosition(strToUnsignedInt(cmd.argument));
                break;
 
        case LFUN_BOOKMARK_GOTO:
-               restorePosition(strToUnsignedInt(ev.argument));
+               restorePosition(strToUnsignedInt(cmd.argument));
                break;
 
        case LFUN_REF_GOTO: {
-               string label = ev.argument;
+               string label = cmd.argument;
                if (label.empty()) {
                        InsetRef * inset =
-                               static_cast<InsetRef*>(getInsetByCode(InsetOld::REF_CODE));
+                               static_cast<InsetRef*>(getInsetByCode(InsetBase::REF_CODE));
                        if (inset) {
                                label = inset->getContents();
                                savePosition(0);
@@ -1080,122 +1043,6 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
 
                if (!label.empty())
                        bv_->gotoLabel(label);
-       }
-       break;
-
-       // --- accented characters ---------------------------
-
-       case LFUN_UMLAUT:
-       case LFUN_CIRCUMFLEX:
-       case LFUN_GRAVE:
-       case LFUN_ACUTE:
-       case LFUN_TILDE:
-       case LFUN_CEDILLA:
-       case LFUN_MACRON:
-       case LFUN_DOT:
-       case LFUN_UNDERDOT:
-       case LFUN_UNDERBAR:
-       case LFUN_CARON:
-       case LFUN_SPECIAL_CARON:
-       case LFUN_BREVE:
-       case LFUN_TIE:
-       case LFUN_HUNG_UMLAUT:
-       case LFUN_CIRCLE:
-       case LFUN_OGONEK:
-               if (ev.argument.empty()) {
-                       // As always...
-                       owner_->getLyXFunc().handleKeyFunc(ev.action);
-               } else {
-                       owner_->getLyXFunc().handleKeyFunc(ev.action);
-                       owner_->getIntl().getTransManager()
-                               .TranslateAndInsert(ev.argument[0], bv_->getLyXText());
-                       update();
-               }
-               break;
-
-       case LFUN_MATH_MACRO:
-       case LFUN_MATH_DELIM:
-       case LFUN_INSERT_MATRIX:
-       case LFUN_INSERT_MATH:
-       case LFUN_MATH_IMPORT_SELECTION: // Imports LaTeX from the X selection
-       case LFUN_MATH_DISPLAY:          // Open or create a displayed math inset
-       case LFUN_MATH_MODE:             // Open or create an inlined math inset
-               mathDispatch(ev);
-               break;
-
-       case LFUN_INSET_APPLY: {
-#warning is this code ever called?
-               // Remove if not triggered. Mail lyx-devel if triggered.
-               // This code was replaced by code in text3.C.
-               BOOST_ASSERT(false);
-               string const name = ev.getArg(0);
-
-               InsetBase * inset = owner_->getDialogs().getOpenInset(name);
-               if (inset) {
-                       // This works both for 'original' and 'mathed' insets.
-                       // Note that the localDispatch performs update also.
-                       FuncRequest fr(bv_, LFUN_INSET_MODIFY, ev.argument);
-                       inset->dispatch(fr);
-               } else {
-                       FuncRequest fr(bv_, LFUN_INSET_INSERT, ev.argument);
-                       dispatch(fr);
-               }
-       }
-       break;
-
-       case LFUN_INSET_INSERT: {
-               // Same as above.
-               BOOST_ASSERT(false);
-               InsetOld * inset = createInset(ev);
-               if (!inset || !insertInset(inset))
-                       delete inset;
-               break;
-       }
-
-       case LFUN_FLOAT_LIST:
-               if (tclass.floats().typeExist(ev.argument)) {
-                       InsetOld * inset = new InsetFloatList(ev.argument);
-                       if (!insertInset(inset, tclass.defaultLayoutName()))
-                               delete inset;
-               } else {
-                       lyxerr << "Non-existent float type: "
-                              << ev.argument << endl;
-               }
-               break;
-
-       case LFUN_LAYOUT_PARAGRAPH: {
-               string data;
-               params2string(*bv_->getLyXText()->cursorPar(), data);
-               data = "show\n" + data;
-               bv_->owner()->getDialogs().show("paragraph", data);
-               break;
-       }
-
-       case LFUN_PARAGRAPH_UPDATE:
-               updateParagraphDialog();
-               break;
-
-       case LFUN_PARAGRAPH_APPLY:
-               setParagraphParams(*bv_, ev.argument);
-               break;
-
-       case LFUN_THESAURUS_ENTRY: {
-               string arg = ev.argument;
-
-               if (arg.empty()) {
-                       arg = bv_->getLyXText()->selectionAsString(*buffer_,
-                                                                  false);
-
-                       // FIXME
-                       if (arg.size() > 100 || arg.empty()) {
-                               // Get word or selection
-                               bv_->getLyXText()->selectWordWhenUnderCursor(lyx::WHOLE_WORD);
-                               arg = bv_->getLyXText()->selectionAsString(*buffer_, false);
-                               // FIXME: where is getLyXText()->unselect(bv_) ?
-                       }
-               }
-
-               bv_->owner()->getDialogs().show("thesaurus", arg);
                break;
        }
 
@@ -1208,147 +1055,82 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
                break;
 
        case LFUN_ACCEPT_ALL_CHANGES: {
-               bv_->text->setCursor(0, 0);
+               bv_->cursor().reset(bv_->buffer()->inset());
+#ifdef WITH_WARNINGS
 #warning FIXME changes
+#endif
                while (lyx::find::findNextChange(bv_))
-                       bv_->getLyXText()->acceptChange();
+                       bv_->getLyXText()->acceptChange(bv_->cursor());
                update();
                break;
        }
 
        case LFUN_REJECT_ALL_CHANGES: {
-               bv_->text->setCursor(0, 0);
+               bv_->cursor().reset(bv_->buffer()->inset());
+#ifdef WITH_WARNINGS
 #warning FIXME changes
+#endif
                while (lyx::find::findNextChange(bv_))
-                       bv_->getLyXText()->rejectChange();
-               update();
+                       bv_->getLyXText()->rejectChange(bv_->cursor());
                break;
        }
 
-       case LFUN_ACCEPT_CHANGE: {
-               bv_->getLyXText()->acceptChange();
-               update();
+       case LFUN_WORD_FIND:
+               lyx::find::find(bv_, cmd);
                break;
-       }
 
-       case LFUN_REJECT_CHANGE: {
-               bv_->getLyXText()->rejectChange();
-               update();
+       case LFUN_WORD_REPLACE:
+               lyx::find::replace(bv_, cmd);
                break;
-       }
 
-       case LFUN_UNKNOWN_ACTION:
-               ev.errorMessage(N_("Unknown function!"));
+       case LFUN_MARK_OFF:
+               cur.clearSelection();
+               cur.resetAnchor();
+               cur.message(N_("Mark off"));
                break;
 
-       default:
-               return bv_->getLyXText()->dispatch(FuncRequest(ev, bv_)).dispatched();
-       } // end of switch
-
-       return true;
-}
-
-
-bool BufferView::Pimpl::insertInset(InsetOld * inset, string const & lout)
-{
-#ifdef LOCK
-       // if we are in a locking inset we should try to insert the
-       // inset there otherwise this is a illegal function now
-       if (bv_->theLockingInset()) {
-               if (bv_->theLockingInset()->insetAllowed(inset))
-                       return bv_->theLockingInset()->insertInset(bv_, inset);
-               return false;
-       }
-#endif
-
-       // not quite sure if we want this...
-       bv_->text->recUndo(bv_->text->cursor.par());
-       freezeUndo();
-
-       bv_->text->clearSelection();
-       if (!lout.empty()) {
-               bv_->text->breakParagraph(bv_->buffer()->paragraphs());
+       case LFUN_MARK_ON:
+               cur.clearSelection();
+               cur.mark() = true;
+               cur.resetAnchor();
+               cur.message(N_("Mark on"));
+               break;
 
-               if (!bv_->text->cursorPar()->empty()) {
-                       bv_->text->cursorLeft(bv_);
-                       bv_->text->breakParagraph(bv_->buffer()->paragraphs());
+       case LFUN_SETMARK:
+               cur.clearSelection();
+               if (cur.mark()) {
+                       cur.mark() = false;
+                       cur.message(N_("Mark removed"));
+               } else {
+                       cur.mark() = true;
+                       cur.message(N_("Mark set"));
                }
+               cur.resetAnchor();
+               break;
 
-               string lres = lout;
-               LyXTextClass const & tclass = buffer_->params().getLyXTextClass();
-               bool hasLayout = tclass.hasLayout(lres);
-
-               bv_->text->setLayout(hasLayout ? lres : tclass.defaultLayoutName());
-
-               bv_->text->setParagraph(
-                                  VSpace(VSpace::NONE), VSpace(VSpace::NONE),
-                                  Spacing(),
-                                  LYX_ALIGN_LAYOUT,
-                                  string(),
-                                  0);
-       }
-       bv_->cursor().innerText()->insertInset(inset);
-       unFreezeUndo();
-       return true;
-}
-
+       case LFUN_CENTER:
+               bv_->center();
+               break;
 
-bool BufferView::Pimpl::ChangeInsets(InsetOld::Code code,
-                                    string const & from, string const & to)
-{
-       bool need_update = false;
-       LyXCursor cursor = bv_->text->cursor;
-       LyXCursor tmpcursor = cursor;
-       cursor.par(tmpcursor.par());
-       cursor.pos(tmpcursor.pos());
-
-       ParIterator end = bv_->buffer()->par_iterator_end();
-       for (ParIterator it = bv_->buffer()->par_iterator_begin();
-            it != end; ++it) {
-               bool changed_inset = false;
-               for (InsetList::iterator it2 = it->insetlist.begin();
-                    it2 != it->insetlist.end(); ++it2) {
-                       if (it2->inset->lyxCode() == code) {
-                               InsetCommand * inset = static_cast<InsetCommand *>(it2->inset);
-                               if (inset->getContents() == from) {
-                                       inset->setContents(to);
-                                       changed_inset = true;
-                               }
-                       }
-               }
-               if (changed_inset) {
-                       need_update = true;
+       case LFUN_BEGINNINGBUFSEL:
+               bv_->cursor().reset(bv_->buffer()->inset());
+               if (!cur.selection())
+                       cur.resetAnchor();
+               bv_->text()->cursorTop(cur);
+               finishUndo();
+               break;
 
-                       // FIXME
+       case LFUN_ENDBUFSEL:
+               bv_->cursor().reset(bv_->buffer()->inset());
+               if (!cur.selection())
+                       cur.resetAnchor();
+               bv_->text()->cursorBottom(cur);
+               finishUndo();
+               break;
 
-                       // The test it.size()==1 was needed to prevent crashes.
-                       // How to set the cursor correctly when it.size()>1 ??
-                       if (it.size() == 1) {
-                               bv_->text->setCursorIntern(bv_->text->parOffset(it.pit()), 0);
-                               bv_->text->redoParagraph(bv_->text->cursorPar());
-                       }
-               }
+       default:
+               return false;
        }
-       bv_->text->setCursorIntern(cursor.par(), cursor.pos());
-       return need_update;
-}
-
 
-void BufferView::Pimpl::updateParagraphDialog()
-{
-       if (!bv_->owner()->getDialogs().visible("paragraph"))
-               return;
-       Paragraph const & par = *bv_->getLyXText()->cursorPar();
-       string data;
-       params2string(par, data);
-
-       // Will the paragraph accept changes from the dialog?
-       InsetOld * const inset = par.inInset();
-       bool const accept =
-               !(inset && inset->forceDefaultParagraphs(inset));
-
-       data = "update " + tostr(accept) + '\n' + data;
-       bv_->owner()->getDialogs().update("paragraph", data);
+       return true;
 }
-
-