/**
* \file BufferView_pimpl.C
- * Copyright 2002 the LyX Team
- * Read the file COPYING
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
*
+ * \author Asger Alstrup
+ * \author Alfredo Braunstein
* \author Lars Gullik Bjønnes
- * \author various
+ * \author Jean-Marc Lasgouttes
+ * \author Angus Leeming
+ * \author John Levon
+ * \author André Pönitz
+ * \author Dekel Tsur
+ * \author Jürgen Vigna
+ *
+ * Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "BufferView_pimpl.h"
-#include "bufferlist.h"
#include "buffer.h"
#include "buffer_funcs.h"
-#include "bufferview_funcs.h"
-#include "lfuns.h"
+#include "bufferlist.h"
+#include "bufferparams.h"
+#include "cursor.h"
#include "debug.h"
+#include "dispatchresult.h"
#include "factory.h"
#include "FloatList.h"
#include "funcrequest.h"
#include "gettext.h"
#include "intl.h"
#include "iterators.h"
-#include "Lsstream.h"
#include "lyx_cb.h" // added for Dispatch functions
#include "lyx_main.h"
#include "lyxfind.h"
#include "lyxfunc.h"
#include "lyxtext.h"
#include "lyxrc.h"
-#include "lyxrow.h"
#include "lastfiles.h"
#include "paragraph.h"
+#include "paragraph_funcs.h"
#include "ParagraphParameters.h"
-#include "TextCache.h"
-#include "undo_funcs.h"
+#include "undo.h"
+#include "vspace.h"
#include "insets/insetfloatlist.h"
-#include "insets/insetgraphics.h"
-#include "insets/insetinclude.h"
#include "insets/insetref.h"
-#include "insets/insettext.h"
#include "frontends/Alert.h"
#include "frontends/Dialogs.h"
#include "frontends/FileDialog.h"
#include "frontends/LyXView.h"
#include "frontends/LyXScreenFactory.h"
-#include "frontends/mouse_state.h"
#include "frontends/screen.h"
#include "frontends/WorkArea.h"
#include "frontends/WorkAreaFactory.h"
-#include "mathed/formulabase.h"
-
#include "graphics/Previews.h"
-#include "support/LAssert.h"
-#include "support/tostr.h"
#include "support/filetools.h"
+#include "support/globbing.h"
#include "support/path_defines.h"
+#include "support/tostr.h"
#include <boost/bind.hpp>
-#include <boost/signals/connection.hpp>
-#include <unistd.h>
-#include <sys/wait.h>
+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::IsDirWriteable;
+using lyx::support::MakeDisplayPath;
+using lyx::support::strToUnsignedInt;
+using lyx::support::system_lyxdir;
-using std::vector;
-using std::find_if;
-using std::find;
-using std::pair;
using std::endl;
using std::make_pair;
using std::min;
+using std::string;
-using lyx::pos_type;
-using namespace lyx::support;
-using namespace bv_funcs;
extern BufferList bufferlist;
} // 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),
- using_xterm_cursor(false)
+ : 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()));
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::buffer, this, (Buffer *)0));
}
// get absolute path of file and add ".lyx" to the filename if
// necessary
string s = FileSearch(string(), filename, "lyx");
-
+
bool const found = !s.empty();
- if (!found)
+ if (!found)
s = filename;
// file already open?
bv_->showErrorList(_("Parse"));
if (tolastfiles)
- lastfiles->newFile(b->fileName());
+ LyX::ref().lastfiles().newFile(b->fileName());
return true;
}
}
+void BufferView::Pimpl::top_y(int y)
+{
+ top_y_ = y;
+}
+
+
+int BufferView::Pimpl::top_y() const
+{
+ return top_y_;
+}
+
+
void BufferView::Pimpl::buffer(Buffer * b)
{
lyxerr[Debug::INFO] << "Setting buffer in BufferView ("
<< b << ')' << endl;
if (buffer_) {
disconnectBuffer();
- // Put the old text into the TextCache, but
- // only if the buffer is still loaded.
- // Also set the owner of the test to 0
- // bv_->text->owner(0);
- textcache.add(buffer_, workarea().workWidth(), bv_->text);
- if (lyxerr.debugging())
- textcache.show(lyxerr, "BufferView::buffer");
-
- bv_->text = 0;
+ //delete bv_->text();
+ //bv_->setText(0);
}
+ // reset old cursor
+ cursor_.reset();
+
// set current buffer
buffer_ = b;
+ top_y_ = 0;
+
// if we're quitting lyx, don't bother updating stuff
if (quitting)
return;
lyxerr[Debug::INFO] << "Buffer addr: " << buffer_ << endl;
connectBuffer(*buffer_);
+ buffer_->text().init(bv_);
+ buffer_->text().textwidth_ = workarea().workWidth();
+ buffer_->text().fullRebreak();
+
// If we don't have a text object for this, we make one
- if (bv_->text == 0)
+ if (bv_->text() == 0)
resizeCurrentBuffer();
- // FIXME: needed when ?
- bv_->text->top_y(screen().topCursorVisible(bv_->text));
-
// Buffer-dependent dialogs should be updated or
// hidden. This should go here because some dialogs (eg ToC)
// require bv_->text.
} else {
lyxerr[Debug::INFO] << " No Buffer!" << endl;
owner_->getDialogs().hideBufferDependent();
-
- // Also remove all remaining text's from the testcache.
- // (there should not be any!) (if there is any it is a
- // bug!)
- if (lyxerr.debugging())
- textcache.show(lyxerr, "buffer delete all");
- textcache.clear();
}
- repaint();
+ update();
updateScrollbar();
owner_->updateMenubar();
owner_->updateToolbar();
owner_->updateLayoutChoice();
owner_->updateWindowTitle();
- if (buffer_) {
- // Don't forget to update the Layout
- string const layoutname =
- bv_->text->cursor.par()->layout()->name();
- owner_->setLayout(layoutname);
- }
+ // Don't forget to update the Layout
+ if (buffer_)
+ owner_->setLayout(bv_->text()->cursorPar()->layout()->name());
if (lyx::graphics::Previews::activated() && buffer_)
lyx::graphics::Previews::get().generateBufferPreviews(*buffer_);
bool BufferView::Pimpl::fitCursor()
{
- bool ret;
-
- if (bv_->theLockingInset()) {
- bv_->theLockingInset()->fitInsetCursor(bv_);
- ret = true;
- } else {
- ret = screen().fitCursor(bv_->text, bv_);
+ if (screen().fitCursor(bv_)) {
+ updateScrollbar();
+ return true;
}
-
- dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
-
- // We need to always update, in case we did a
- // paste and we stayed anchored to a row, but
- // the actual height of the doc changed ...
- updateScrollbar();
- return ret;
+ return false;
}
void BufferView::Pimpl::redoCurrentBuffer()
{
lyxerr[Debug::INFO] << "BufferView::redoCurrentBuffer" << endl;
- if (buffer_ && bv_->text) {
+ if (buffer_ && bv_->text()) {
resizeCurrentBuffer();
updateScrollbar();
owner_->updateLayoutChoice();
- repaint();
}
}
-int BufferView::Pimpl::resizeCurrentBuffer()
+void BufferView::Pimpl::resizeCurrentBuffer()
{
lyxerr[Debug::INFO] << "resizeCurrentBuffer" << endl;
- ParagraphList::iterator par;
- ParagraphList::iterator selstartpar;
- ParagraphList::iterator selendpar;
- UpdatableInset * the_locking_inset = 0;
+ 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 sel = 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();
- the_locking_inset = bv_->theLockingInset();
- resizeInsets(bv_);
- bv_->text->fullRebreak();
- update();
- } else {
- lyxerr << "text not available!\n";
- // See if we have a text in TextCache that fits
- // the new buffer_ with the correct width.
- bv_->text = textcache.findFit(buffer_, workarea().workWidth());
- if (bv_->text) {
- lyxerr << "text in cache!\n";
- if (lyxerr.debugging()) {
- lyxerr << "Found a LyXText that fits:\n";
- textcache.show(lyxerr, make_pair(buffer_, make_pair(workarea().workWidth(), bv_->text)));
- }
- // Set the owner of the newly found text
- // bv_->text->owner(bv_);
- if (lyxerr.debugging())
- textcache.show(lyxerr, "resizeCurrentBuffer");
-
- resizeInsets(bv_);
- } else {
- lyxerr << "no text in cache!\n";
- bv_->text = new LyXText(bv_);
- resizeInsets(bv_);
- bv_->text->init(bv_);
- }
-
- par = bv_->text->ownerParagraphs().end();
- selstartpar = bv_->text->ownerParagraphs().end();
- selendpar = bv_->text->ownerParagraphs().end();
- }
+ LyXText * text = bv_->text();
+ lyxerr << "### resizeCurrentBuffer: text " << text << endl;
+ if (!text)
+ return;
- if (par != bv_->text->ownerParagraphs().end()) {
- bv_->text->selection.set(true);
+ LCursor & cur = bv_->cursor();
+ par = cur.par();
+ pos = cur.pos();
+ selstartpar = cur.selBegin().par();
+ selstartpos = cur.selBegin().pos();
+ selendpar = cur.selEnd().par();
+ selendpos = cur.selEnd().pos();
+ sel = cur.selection();
+ mark_set = cur.mark();
+ text->textwidth_ = bv_->workWidth();
+ text->fullRebreak();
+ update();
+
+ if (par != -1) {
+ cur.selection() = 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);
+ cur.mark() = mark_set;
+ if (sel) {
+ text->setCursor(selstartpar, selstartpos);
+ cur.resetAnchor();
+ text->setCursor(selendpar, selendpos);
+ cur.setSelection();
+ text->setCursor(par, pos);
} else {
- bv_->text->setCursor(par, pos);
- bv_->text->selection.cursor = bv_->text->cursor;
- bv_->text->selection.set(false);
+ text->setCursor(par, pos);
+ cur.resetAnchor();
+ cur.selection() = false;
}
- // remake the inset locking
- bv_->theLockingInset(the_locking_inset);
}
- bv_->text->top_y(screen().topCursorVisible(bv_->text));
+ fitCursor();
switchKeyMap();
owner_->busy(false);
owner_->clearMessage();
updateScrollbar();
-
- return 0;
-}
-
-
-void BufferView::Pimpl::repaint()
-{
- // Regenerate the screen.
- screen().redraw(bv_, bv_->text);
}
void BufferView::Pimpl::updateScrollbar()
{
- if (!bv_->text) {
+ if (!bv_->text()) {
lyxerr[Debug::GUI] << "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() "
- << t.top_y() << ", default height " << defaultRowHeight() << endl;
+ << top_y() << ", default height " << defaultRowHeight() << endl;
- workarea().setScrollbarParams(t.height, t.top_y(), defaultRowHeight());
+ workarea().setScrollbarParams(t.height, top_y(), defaultRowHeight());
}
screen().hideCursor();
- screen().draw(bv_->text, bv_, value);
+ top_y(value);
+ screen().redraw(*bv_);
if (!lyxrc.cursor_follows_scrollbar)
return;
- LyXText * vbt = bv_->text;
-
int const height = defaultRowHeight();
- int const first = static_cast<int>((bv_->text->top_y() + height));
- int const last = static_cast<int>((bv_->text->top_y() + workarea().workHeight() - height));
+ int const first = top_y() + height;
+ int const last = top_y() + workarea().workHeight() - height;
- if (vbt->cursor.y() < first)
- vbt->setCursorFromCoordinates(0, first);
- else if (vbt->cursor.y() > last)
- vbt->setCursorFromCoordinates(0, last);
+ LyXText * text = bv_->text();
+ int y = text->cursorY(bv_->cursor().cursor_.front());
+ if (y < first)
+ text->setCursorFromCoordinates(0, first);
+ else if (y > last)
+ text->setCursorFromCoordinates(0, last);
owner_->updateLayoutChoice();
}
void BufferView::Pimpl::scroll(int lines)
{
- if (!buffer_) {
+ 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 = t->top_y() + lines * line_height;
+ 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);
scrollDocView(new_top_y);
// Update the scrollbar.
- workarea().setScrollbarParams(t->height, t->top_y(), defaultRowHeight());
+ workarea().setScrollbarParams(t->height, top_y(), defaultRowHeight());
}
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 (!sel.empty()) {
- workarea().putClipboard(sel);
+ if (!cur.selection()) {
+ xsel_cache_.set = false;
+ return;
}
+
+ if (!xsel_cache_.set ||
+ cur.cursor_.back() != xsel_cache_.cursor ||
+ cur.anchor_.back() != xsel_cache_.anchor)
+ {
+ xsel_cache_.cursor = cur.cursor_.back();
+ xsel_cache_.anchor = cur.anchor_.back();
+ xsel_cache_.set = cur.selection();
+ sel = bv_->getLyXText()->selectionAsString(*bv_->buffer(), false);
+ if (!sel.empty())
+ workarea().putClipboard(sel);
+ }
}
{
if (available()) {
screen().hideCursor();
- toggleSelection();
- bv_->getLyXText()->clearSelection();
- bv_->text->xsel_cache.set(false);
+ bv_->cursor().clearSelection();
+ xsel_cache_.set = false;
}
}
if (widthChange) {
// The visible LyXView need a resize
resizeCurrentBuffer();
-
- // Remove all texts from the textcache
- // This is not _really_ what we want to do. What
- // we really want to do is to delete in textcache
- // that does not have a BufferView with matching
- // width, but as long as we have only one BufferView
- // deleting all gives the same result.
- if (lyxerr.debugging())
- textcache.show(lyxerr, "Expose delete all");
- textcache.clear();
- // FIXME: this is already done in resizeCurrentBuffer() ??
- resizeInsets(bv_);
- } else if (heightChange) {
- // fitCursor() ensures we don't jump back
- // to the start of the document on vertical
- // resize
- fitCursor();
}
}
- if (widthChange || heightChange) {
- repaint();
- }
+ if (widthChange || heightChange)
+ update();
// always make sure that the scrollbar is sane.
updateScrollbar();
owner_->updateLayoutChoice();
- return;
}
void BufferView::Pimpl::update()
{
- lyxerr << "BufferView::update()\n";
- screen().update(*bv_);
- bv_->text->clearPaint();
-}
-
-
-void BufferView::Pimpl::update(LyXText * text, BufferView::UpdateCodes f)
-{
- if (!text->selection.set() && (f & SELECT)) {
- text->selection.cursor = text->cursor;
- }
-
- text->partialRebreak();
-
- if (text->inset_owner) {
- text->inset_owner->setUpdateStatus(InsetText::NONE);
- updateInset(text->inset_owner);
- } else {
- update();
- }
-}
-
-
-void BufferView::Pimpl::update(BufferView::UpdateCodes f)
-{
- LyXText * text = bv_->text;
-
- if (!text->selection.set() && (f & SELECT)) {
- text->selection.cursor = text->cursor;
- }
-
- text->partialRebreak();
-
- if (text->inset_owner) {
- text->inset_owner->setUpdateStatus(InsetText::NONE);
- updateInset(text->inset_owner);
- } else {
- update();
+ //lyxerr << "BufferView::update()" << endl;
+ // fix cursor coordinate cache in case something went wrong
+
+ // check needed to survive LyX startup
+ if (bv_->getLyXText()) {
+ // update all 'visible' paragraphs
+ ParagraphList::iterator beg;
+ ParagraphList::iterator end;
+ getParsInRange(buffer_->paragraphs(),
+ top_y(), top_y() + workarea().workHeight(),
+ beg, end);
+ bv_->text()->redoParagraphs(beg, end);
+ updateScrollbar();
}
+ screen().redraw(*bv_);
}
}
screen().toggleCursor(*bv_);
-
cursor_timeout.restart();
}
bool BufferView::Pimpl::available() const
{
- if (buffer_ && bv_->text)
- return true;
- return false;
+ return buffer_ && bv_->text();
}
Change const BufferView::Pimpl::getCurrentChange()
{
- if (!bv_->buffer()->params.tracking_changes)
+ if (!bv_->buffer()->params().tracking_changes)
return Change(Change::UNCHANGED);
- LyXText * t(bv_->getLyXText());
+ LyXText * text = bv_->getLyXText();
+ LCursor & cur = bv_->cursor();
- if (!t->selection.set())
+ if (!cur.selection())
return Change(Change::UNCHANGED);
- LyXCursor const & cur(t->selection.start);
- return cur.par()->lookupChangeFull(cur.pos());
-}
-
-
-void BufferView::Pimpl::beforeChange(LyXText * text)
-{
- toggleSelection();
- text->clearSelection();
+ return text->getPar(cur.selBegin())
+ ->lookupChangeFull(cur.selBegin().pos());
}
if (i >= saved_positions_num)
return;
saved_positions[i] = Position(buffer_->fileName(),
- bv_->text->cursor.par()->id(),
- bv_->text->cursor.pos());
+ bv_->text()->cursorPar()->id(),
+ bv_->text()->cursor().pos());
if (i > 0)
owner_->message(bformat(_("Saved bookmark %1$s"), tostr(i)));
}
string const fname = saved_positions[i].filename;
- beforeChange(bv_->text);
+ bv_->cursor().clearSelection();
if (fname != buffer_->fileName()) {
- Buffer * b;
+ Buffer * b = 0;
if (bufferlist.exists(fname))
b = bufferlist.getBuffer(fname);
else {
b = bufferlist.newBuffer(fname);
::loadLyXFile(b, fname); // don't ask, just load it
}
- if (b != 0)
+ if (b)
buffer(b);
}
if (par == buffer_->par_iterator_end())
return;
- bv_->text->setCursor(par.pit(),
+ bv_->text()->setCursor(par.pit(),
min(par->size(), saved_positions[i].par_pos));
- update(BufferView::SELECT);
if (i > 0)
owner_->message(bformat(_("Moved to bookmark %1$s"), tostr(i)));
}
bool BufferView::Pimpl::isSavedPosition(unsigned int i)
{
- if (i >= saved_positions_num)
- return false;
-
- return !saved_positions[i].filename.empty();
+ return i < saved_positions_num && !saved_positions[i].filename.empty();
}
if (!lyxrc.rtl_support)
return;
- LyXText * text = bv_->getLyXText();
- if (text->real_current_font.isRightToLeft()
- && !(bv_->theLockingInset()
- && bv_->theLockingInset()->lyxCode() == InsetOld::ERT_CODE))
- {
- if (owner_->getIntl().keymap == Intl::PRIMARY)
- owner_->getIntl().KeyMapSec();
+ Intl & intl = owner_->getIntl();
+ if (bv_->getLyXText()->real_current_font.isRightToLeft()) {
+ if (intl.keymap == Intl::PRIMARY)
+ intl.KeyMapSec();
} else {
- if (owner_->getIntl().keymap == Intl::SECONDARY)
- owner_->getIntl().KeyMapPrim();
+ if (intl.keymap == Intl::SECONDARY)
+ intl.KeyMapPrim();
}
}
-void BufferView::Pimpl::insetUnlock()
-{
- if (bv_->theLockingInset()) {
- bv_->theLockingInset()->insetUnlock(bv_);
- bv_->theLockingInset(0);
- finishUndo();
- }
-}
-
-
-void BufferView::Pimpl::toggleSelection(bool b)
-{
- screen().toggleSelection(bv_->text, bv_, b);
-}
-
-
void BufferView::Pimpl::center()
{
- LyXText * t = bv_->text;
+ LyXText * text = bv_->text();
- beforeChange(t);
+ bv_->cursor().clearSelection();
int const half_height = workarea().workHeight() / 2;
- int new_y = 0;
-
- if (t->cursor.y() > half_height) {
- new_y = t->cursor.y() - half_height;
- }
+ int new_y = text->cursorY(bv_->cursor().cursor_.front()) - half_height;
+ if (new_y < 0)
+ new_y = 0;
// FIXME: look at this comment again ...
-
- // FIXME: can we do this w/o calling screen directly ?
// This updates top_y() but means the fitCursor() call
// from the update(FITCUR) doesn't realise that we might
// have moved (e.g. from GOTOPARAGRAPH), so doesn't cause
// 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()
- screen().draw(t, bv_, new_y);
-
- update(BufferView::SELECT);
+ // pretty obfuscated way of updating text->top_y()
+ top_y(new_y);
}
}
-/*
- * Dispatch functions for actions which can be valid for BufferView->text
- * and/or InsetText->text!!!
- */
-
-
-InsetOld * BufferView::Pimpl::getInsetByCode(InsetOld::Code code)
+InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code code)
{
#if 0
- LyXCursor cursor = bv_->getLyXText()->cursor;
+ CursorSlice cursor = bv_->getLyXText()->cursor;
Buffer::inset_iterator it =
find_if(Buffer::inset_iterator(
- cursor.par(), cursor.pos()),
+ cursorPar(), cursor().pos()),
buffer_->inset_iterator_end(),
lyx::compare_memfun(&Inset::lyxCode, code));
return it != buffer_->inset_iterator_end() ? (*it) : 0;
#else
// Ok, this is a little bit too brute force but it
- // should work for now. Better infrastructure is comming. (Lgb)
+ // should work for now. Better infrastructure is coming. (Lgb)
Buffer * b = bv_->buffer();
- LyXCursor cursor = bv_->getLyXText()->cursor;
+ LyXText * text = bv_->getLyXText();
Buffer::inset_iterator beg = b->inset_iterator_begin();
Buffer::inset_iterator end = b->inset_iterator_end();
bool cursor_par_seen = false;
for (; beg != end; ++beg) {
- if (beg.getPar() == cursor.par()) {
+ if (beg.getPar() == text->cursorPar()) {
cursor_par_seen = true;
}
if (cursor_par_seen) {
- if (beg.getPar() == cursor.par()
- && beg.getPos() >= cursor.pos()) {
+ if (beg.getPar() == text->cursorPar()
+ && beg.getPos() >= text->cursor().pos()) {
break;
- } else if (beg.getPar() != cursor.par()) {
+ }
+ 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) {
+ if (beg->lyxCode() == code)
return &(*beg);
- }
}
}
return 0;
}
-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
FileDialog::Result result =
fileDlg.open(initpath,
- _("*.lyx| LyX Documents (*.lyx)"));
+ FileFilterList(_("LyX Documents (*.lyx)")),
+ string());
if (result.first == FileDialog::Later)
return;
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();
for (ParIterator it = buf->par_iterator_begin(); it != end; ++it)
it->trackChanges();
- buf->params.tracking_changes = true;
+ buf->params().tracking_changes = true;
// we cannot allow undos beyond the freeze point
- buf->undostack.clear();
+ buf->undostack().clear();
} else {
- update(BufferView::SELECT);
- bv_->text->setCursor(buf->paragraphs.begin(), 0);
+ update();
+ bv_->text()->setCursor(0, 0);
#warning changes FIXME
- //moveCursorUpdate(false);
-
bool found = lyx::find::findNextChange(bv_);
if (found) {
owner_->getDialogs().show("changes");
ParIterator const end = buf->par_iterator_end();
for (ParIterator it = buf->par_iterator_begin(); it != end; ++it)
it->untrackChanges();
- buf->params.tracking_changes = false;
+ buf->params().tracking_changes = false;
}
- buf->redostack.clear();
+ buf->redostack().clear();
}
-// Doesn't go through lyxfunc, so we need to update the
-// layout choice etc. ourselves
-bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & ev_in)
+bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
{
- // e.g. Qt mouse press when no buffer
- if (!available())
- return false;
+ //
+ // this is only called for mouse related events.
+ //
+ FuncRequest cmd = cmd0;
+ cmd.y += bv_->top_y();
+ lyxerr << "*** workAreaDispatch: request: " << cmd << std::endl;
+ LCursor cur(*bv_);
+ switch (cmd.action) {
+#if 0
+ case LFUN_MOUSE_MOTION: {
+ if (!available())
+ return false;
+ FuncRequest cmd1 = cmd;
+ InsetBase * inset = cur.inset();
+ DispatchResult res;
+ if (inset) {
+ res = inset->dispatch(cur, cmd);
+ } else {
+ res = bv_->text()->dispatch(cur, cmd);
+ }
- screen().hideCursor();
+ if (fitCursor() || res.update()) {
+ bv_->update();
+ cur.updatePos();
+ }
+ return true;
+ }
+#endif
- // Make sure that the cached BufferView is correct.
- FuncRequest ev = ev_in;
- ev.setView(bv_);
+ case LFUN_MOUSE_MOTION:
+ 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
- bool const res = dispatch(ev);
+ // Doesn't go through lyxfunc, so we need to update
+ // the layout choice etc. ourselves
- // see workAreaKeyPress
- cursor_timeout.restart();
- screen().showCursor(*bv_);
+ // e.g. Qt mouse press when no buffer
+ if (!available())
+ return false;
+
+ screen().hideCursor();
- // FIXME: we should skip these when selecting
- bv_->owner()->updateLayoutChoice();
- bv_->owner()->updateToolbar();
- bv_->fitCursor();
+ // either the inset under the cursor or the
+ // surrounding LyXText will handle this event.
- // slight hack: this is only called currently when
- // we clicked somewhere, so we force through the display
- // of the new status here.
- bv_->owner()->clearMessage();
+ // built temporary path to inset
+ LyXText * text = bv_->text();
+ InsetBase * const inset_hit = text->checkInsetHit(cmd.x, cmd.y);
+ if (inset_hit)
+ inset_hit->edit(cur, cmd.x, cmd.y);
+ else
+ text->setCursorFromCoordinates(cur.current(), cmd.x, cmd.y);
+ lyxerr << "created temp cursor: " << cur << endl;
+
+ // Dispatch to the temp cursor.
+ // An inset (or LyXText) can assign this to bv->cursor()
+ // if it wishes to do so.
+ DispatchResult res = cur.dispatch(cmd);
- return res;
+ if (fitCursor() || res.update())
+ bv_->update();
+
+ // see workAreaKeyPress
+ cursor_timeout.restart();
+ screen().showCursor(*bv_);
+
+ // skip these when selecting
+ if (cmd.action != LFUN_MOUSE_MOTION) {
+ owner_->updateLayoutChoice();
+ owner_->updateToolbar();
+ }
+
+ // 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;
+ }
+
+ default:
+ lyxerr << "*** UNDISPATCHED: " << cmd;
+ //owner_->dispatch(cmd);
+ }
+ return true;
}
-bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
+bool BufferView::Pimpl::dispatch(FuncRequest const & cmd)
{
+ lyxerr << "*** BufferView::Pimpl: request: " << 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();
+ 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
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);
- break;
-
- case LFUN_LANGUAGE:
- lang(bv_, ev.argument);
- switchKeyMap();
- owner_->view_state_changed();
- break;
-
- case LFUN_EMPH:
- emph(bv_);
- owner_->view_state_changed();
- break;
-
- case LFUN_BOLD:
- bold(bv_);
- owner_->view_state_changed();
- break;
-
- case LFUN_NOUN:
- noun(bv_);
- owner_->view_state_changed();
- break;
-
- case LFUN_CODE:
- code(bv_);
- owner_->view_state_changed();
- break;
-
- case LFUN_SANS:
- sans(bv_);
- owner_->view_state_changed();
- break;
-
- case LFUN_ROMAN:
- roman(bv_);
- owner_->view_state_changed();
- break;
-
- case LFUN_DEFAULT:
- styleReset(bv_);
- owner_->view_state_changed();
- break;
-
- case LFUN_UNDERLINE:
- underline(bv_);
- owner_->view_state_changed();
- break;
-
- case LFUN_FONT_SIZE:
- fontSize(bv_, ev.argument);
- owner_->view_state_changed();
+ InsertAsciiFile(bv_, cmd.argument, false);
break;
case LFUN_FONT_STATE:
case LFUN_INSERT_LABEL: {
// Try and generate a valid label
- string const contents = ev.argument.empty() ?
- getPossibleLabel(*bv_) : ev.argument;
+ string const contents = cmd.argument.empty() ?
+ getPossibleLabel(*bv_) : cmd.argument;
InsetCommandParams icp("label", contents);
string data = InsetCommandMailer::params2string("label", icp);
owner_->getDialogs().show("label", data, 0);
+ break;
}
- 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);
case LFUN_HUNG_UMLAUT:
case LFUN_CIRCLE:
case LFUN_OGONEK:
- if (ev.argument.empty()) {
+ if (cmd.argument.empty()) {
// As always...
- owner_->getLyXFunc().handleKeyFunc(ev.action);
+ owner_->getLyXFunc().handleKeyFunc(cmd.action);
} else {
- owner_->getLyXFunc().handleKeyFunc(ev.action);
+ owner_->getLyXFunc().handleKeyFunc(cmd.action);
owner_->getIntl().getTransManager()
- .TranslateAndInsert(ev.argument[0], bv_->getLyXText());
- update(bv_->getLyXText(), BufferView::SELECT);
+ .TranslateAndInsert(cmd.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: {
- 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 updateInset
- // also.
- FuncRequest fr(bv_, LFUN_INSET_MODIFY, ev.argument);
- inset->localDispatch(fr);
- } else {
- FuncRequest fr(bv_, LFUN_INSET_INSERT, ev.argument);
- dispatch(fr);
- }
- }
- break;
-
case LFUN_INSET_INSERT: {
- InsetOld * inset = createInset(ev);
- if (inset && insertInset(inset)) {
- updateInset(inset);
-
- string const name = ev.getArg(0);
- if (name == "bibitem") {
- // We need to do a redraw because the maximum
- // InsetBibitem width could have changed
-#warning please check you mean repaint() not update(),
-#warning and whether the repaint() is needed at all
- bv_->repaint();
- bv_->fitCursor();
- }
- } else {
+ // Same as above.
+ BOOST_ASSERT(false);
+ InsetBase * inset = createInset(bv_, cmd);
+ if (!inset || !insertInset(inset))
delete inset;
- }
+ break;
}
- break;
case LFUN_FLOAT_LIST:
- if (tclass.floats().typeExist(ev.argument)) {
- InsetOld * inset = new InsetFloatList(ev.argument);
+ if (tclass.floats().typeExist(cmd.argument)) {
+ InsetBase * inset = new InsetFloatList(cmd.argument);
if (!insertInset(inset, tclass.defaultLayoutName()))
delete inset;
} else {
lyxerr << "Non-existent float type: "
- << ev.argument << endl;
+ << cmd.argument << endl;
}
break;
case LFUN_LAYOUT_PARAGRAPH: {
- Paragraph const * par = &*bv_->getLyXText()->cursor.par();
- if (!par)
- break;
-
string data;
- params2string(*par, data);
-
+ params2string(*bv_->getLyXText()->cursorPar(), data);
data = "show\n" + data;
bv_->owner()->getDialogs().show("paragraph", data);
break;
}
- case LFUN_PARAGRAPH_UPDATE: {
- if (!bv_->owner()->getDialogs().visible("paragraph"))
- break;
- Paragraph const * par = &*bv_->getLyXText()->cursor.par();
- if (!par)
- break;
-
- 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);
+ case LFUN_PARAGRAPH_UPDATE:
+ updateParagraphDialog();
break;
- }
case LFUN_PARAGRAPH_APPLY:
- setParagraphParams(*bv_, ev.argument);
+ setParagraphParams(*bv_, cmd.argument);
break;
- case LFUN_THESAURUS_ENTRY:
- {
- string arg = ev.argument;
+ case LFUN_THESAURUS_ENTRY: {
+ string arg = cmd.argument;
if (arg.empty()) {
- arg = bv_->getLyXText()->selectionAsString(buffer_,
+ 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);
+ arg = bv_->getLyXText()->selectionAsString(*buffer_, false);
// FIXME: where is getLyXText()->unselect(bv_) ?
}
}
bv_->owner()->getDialogs().show("thesaurus", arg);
- }
break;
+ }
case LFUN_TRACK_CHANGES:
trackChanges();
break;
case LFUN_ACCEPT_ALL_CHANGES: {
- update(BufferView::SELECT);
- bv_->text->setCursor(bv_->buffer()->paragraphs.begin(), 0);
+ bv_->text()->setCursor(0, 0);
#warning FIXME changes
- //moveCursorUpdate(false);
-
- while (lyx::find::findNextChange(bv_)) {
+ while (lyx::find::findNextChange(bv_))
bv_->getLyXText()->acceptChange();
- }
- update(BufferView::SELECT);
+ update();
break;
}
case LFUN_REJECT_ALL_CHANGES: {
- update(BufferView::SELECT);
- bv_->text->setCursor(bv_->buffer()->paragraphs.begin(), 0);
+ bv_->text()->setCursor(0, 0);
#warning FIXME changes
- //moveCursorUpdate(false);
-
- while (lyx::find::findNextChange(bv_)) {
+ while (lyx::find::findNextChange(bv_))
bv_->getLyXText()->rejectChange();
- }
- update(BufferView::SELECT);
+ update();
break;
}
case LFUN_ACCEPT_CHANGE: {
bv_->getLyXText()->acceptChange();
- update(BufferView::SELECT);
+ update();
break;
}
case LFUN_REJECT_CHANGE: {
bv_->getLyXText()->rejectChange();
- update(BufferView::SELECT);
+ update();
break;
}
+ case LFUN_WORD_FIND:
+ lyx::find::find(bv_, cmd);
+ break;
+
+ case LFUN_WORD_REPLACE:
+ lyx::find::replace(bv_, cmd);
+ break;
+
+ case LFUN_MARK_OFF:
+ cur.clearSelection();
+ bv_->update();
+ cur.resetAnchor();
+ cur.message(N_("Mark off"));
+ break;
+
+ case LFUN_MARK_ON:
+ cur.clearSelection();
+ cur.mark() = true;
+ bv_->update();
+ cur.resetAnchor();
+ cur.message(N_("Mark on"));
+ break;
+
+ case LFUN_SETMARK:
+ cur.clearSelection();
+ if (cur.mark()) {
+ cur.message(N_("Mark removed"));
+ } else {
+ cur.mark() = true;
+ cur.message(N_("Mark set"));
+ }
+ cur.resetAnchor();
+ bv_->update();
+ break;
+
case LFUN_UNKNOWN_ACTION:
- ev.errorMessage(N_("Unknown function!"));
+ cur.errorMessage(N_("Unknown function!"));
break;
default:
- return bv_->getLyXText()->dispatch(FuncRequest(ev, bv_));
- } // end of switch
+ return false;
+ }
return true;
}
-bool BufferView::Pimpl::insertInset(InsetOld * inset, string const & lout)
+bool BufferView::Pimpl::insertInset(InsetBase * inset, string const & lout)
{
- // 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;
- }
-
// not quite sure if we want this...
- recordUndo(bv_, Undo::ATOMIC);
+ bv_->text()->recUndo(bv_->text()->cursor().par());
freezeUndo();
- beforeChange(bv_->text);
+ bv_->cursor().clearSelection();
if (!lout.empty()) {
- update(BufferView::SELECT);
- bv_->text->breakParagraph(bv_->buffer()->paragraphs);
- update(BufferView::SELECT);
-
- if (!bv_->text->cursor.par()->empty()) {
- bv_->text->cursorLeft(bv_);
+ bv_->text()->breakParagraph(bv_->buffer()->paragraphs());
- bv_->text->breakParagraph(bv_->buffer()->paragraphs);
- update(BufferView::SELECT);
+ if (!bv_->text()->cursorPar()->empty()) {
+ bv_->text()->cursorLeft(bv_);
+ bv_->text()->breakParagraph(bv_->buffer()->paragraphs());
}
string lres = lout;
- LyXTextClass const & tclass =
- buffer_->params.getLyXTextClass();
+ LyXTextClass const & tclass = buffer_->params().getLyXTextClass();
bool hasLayout = tclass.hasLayout(lres);
- string lay = tclass.defaultLayoutName();
- if (hasLayout != false) {
- // layout found
- lay = lres;
- } else {
- // layout not fount using default
- lay = tclass.defaultLayoutName();
- }
-
- bv_->text->setLayout(lay);
-
- bv_->text->setParagraph(0, 0,
- 0, 0,
- VSpace(VSpace::NONE), VSpace(VSpace::NONE),
- Spacing(),
- LYX_ALIGN_LAYOUT,
- string(),
- 0);
- update(BufferView::SELECT);
+ bv_->text()->setLayout(hasLayout ? lres : tclass.defaultLayoutName());
+ bv_->text()->setParagraph(Spacing(), LYX_ALIGN_LAYOUT, string(), 0);
}
-
- bv_->text->insertInset(inset);
- update(BufferView::SELECT);
-
+ bv_->cursor().innerText()->insertInset(inset);
unFreezeUndo();
return true;
}
-void BufferView::Pimpl::updateInset(InsetOld * inset)
+bool BufferView::Pimpl::ChangeInsets(InsetBase::Code code,
+ string const & from, string const & to)
{
- if (!inset || !available())
- return;
-
- // first check for locking insets
- if (bv_->theLockingInset()) {
- if (bv_->theLockingInset() == inset) {
- if (bv_->text->updateInset(inset)) {
- update();
- updateScrollbar();
- return;
- }
- } else if (bv_->theLockingInset()->updateInsetInInset(bv_, inset)) {
- if (bv_->text->updateInset(bv_->theLockingInset())) {
- update();
- updateScrollbar();
- return;
+ bool need_update = false;
+ CursorSlice cur = bv_->text()->cursor();
+
+ 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;
- // then check if the inset is a top_level inset (has no owner)
- // if yes do the update as always otherwise we have to update the
- // toplevel inset where this inset is inside
- InsetOld * tl_inset = inset;
- while (tl_inset->owner())
- tl_inset = tl_inset->owner();
- if (tl_inset == inset) {
- update(BufferView::UPDATE);
- if (bv_->text->updateInset(inset)) {
- update(BufferView::SELECT);
- return;
- }
- } else if (static_cast<UpdatableInset *>(tl_inset)
- ->updateInsetInInset(bv_, inset))
- {
- if (bv_->text->updateInset(tl_inset)) {
- update();
- updateScrollbar();
+ // FIXME
+
+ // 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());
+ }
}
}
+ bv_->text()->setCursorIntern(cur.par(), cur.pos());
+ return need_update;
+}
+
+
+void BufferView::Pimpl::updateParagraphDialog()
+{
+ if (!bv_->owner()->getDialogs().visible("paragraph"))
+ return;
+ CursorSlice const & cur = bv_->cursor().innerTextSlice();
+ LyXText * text = bv_->cursor().innerText();
+ Paragraph const & par = *text->getPar(cur.par());
+ string data;
+ params2string(par, data);
+
+ // Will the paragraph accept changes from the dialog?
+ InsetBase * const inset = cur.inset();
+ bool const accept =
+ !(inset && inset->forceDefaultParagraphs(inset));
+
+ data = "update " + tostr(accept) + '\n' + data;
+ bv_->owner()->getDialogs().update("paragraph", data);
}