#include <boost/bind.hpp>
-using bv_funcs::bold;
-using bv_funcs::code;
using bv_funcs::currentState;
-using bv_funcs::emph;
-using bv_funcs::fontSize;
-using bv_funcs::lang;
-using bv_funcs::noun;
-using bv_funcs::roman;
-using bv_funcs::sans;
-using bv_funcs::styleReset;
-using bv_funcs::underline;
using lyx::pos_type;
resizeCurrentBuffer();
// FIXME: needed when ?
- top_y(screen().topCursorVisible(bv_->text));
+ fitCursor();
// Buffer-dependent dialogs should be updated or
// hidden. This should go here because some dialogs (eg ToC)
owner_->updateLayoutChoice();
owner_->updateWindowTitle();
- if (buffer_) {
- // Don't forget to update the Layout
- string const layoutname =
- bv_->text->cursorPar()->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_);
+ lyxerr << "BufferView::Pimpl::fitCursor." << endl;
+ 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;
}
resizeCurrentBuffer();
updateScrollbar();
owner_->updateLayoutChoice();
- update();
}
}
int par = -1;
int selstartpar = -1;
int selendpar = -1;
- UpdatableInset * the_locking_inset = 0;
pos_type pos = 0;
pos_type selstartpos = 0;
selendpos = bv_->text->selection.end.pos();
selection = bv_->text->selection.set();
mark_set = bv_->text->selection.mark();
- the_locking_inset = bv_->theLockingInset();
bv_->text->fullRebreak();
update();
} else {
- bv_->text = new LyXText(bv_, 0, false, bv_->buffer()->paragraphs());
- bv_->text->init(bv_);
+ bv_->text = new LyXText(bv_, 0, false, bv_->buffer()->paragraphs());
+ bv_->text->init(bv_);
}
if (par != -1) {
bv_->text->selection.cursor = bv_->text->cursor;
bv_->text->selection.set(false);
}
- // remake the inset locking
- bv_->theLockingInset(the_locking_inset);
}
- top_y(screen().topCursorVisible(bv_->text));
+ fitCursor();
switchKeyMap();
owner_->busy(false);
void BufferView::Pimpl::scroll(int lines)
{
- if (!buffer_) {
+ if (!buffer_)
return;
- }
LyXText const * t = bv_->text;
int const line_height = defaultRowHeight();
{
//lyxerr << "BufferView::update()" << endl;
// fix cursor coordinate cache in case something went wrong
+
+ // check needed to survive LyX startup
if (bv_->getLyXText()) {
- // check needed to survive LyX startup
+ // 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);
bv_->getLyXText()->redoCursor();
+ 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;
}
}
-void BufferView::Pimpl::beforeChange(LyXText * text)
-{
- text->clearSelection();
-}
-
-
void BufferView::Pimpl::savePosition(unsigned int i)
{
if (i >= saved_positions_num)
string const fname = saved_positions[i].filename;
- beforeChange(bv_->text);
+ bv_->text->clearSelection();
if (fname != buffer_->fileName()) {
Buffer * b = 0;
bv_->text->setCursor(par.pit(),
min(par->size(), saved_positions[i].par_pos));
- update();
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();
- }
-}
-
-
-void BufferView::Pimpl::insetUnlock()
-{
- if (bv_->theLockingInset()) {
- bv_->theLockingInset()->insetUnlock(bv_);
- bv_->theLockingInset(0);
- finishUndo();
+ if (intl.keymap == Intl::SECONDARY)
+ intl.KeyMapPrim();
}
}
{
LyXText * text = bv_->text;
- beforeChange(text);
+ text->clearSelection();
int const half_height = workarea().workHeight() / 2;
int new_y = std::max(0, text->cursor.y() - half_height);
// 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
// updateScrollbar() currently. Never mind that this is a
// pretty obfuscated way of updating t->top_y()
top_y(new_y);
- //screen().draw();
- update();
}
}
-/*
- * Dispatch functions for actions which can be valid for BufferView->text
- * and/or InsetText->text!!!
- */
-
-
InsetOld * BufferView::Pimpl::getInsetByCode(InsetOld::Code code)
{
#if 0
update();
bv_->text->setCursor(0, 0);
#warning changes FIXME
- //moveCursorUpdate(false);
-
bool found = lyx::find::findNextChange(bv_);
if (found) {
owner_->getDialogs().show("changes");
buf->redostack().clear();
}
+#warning remove me
+LCursor theTempCursor(0);
-bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & ev)
+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)
+ break;
+ inset = inset_hit;
+ if (!inset_hit->descendable())
+ break;
+ text = inset_hit->getText(0);
+ lyxerr << "Hit inset: " << inset << " at x: " << x
+ << " text: " << text << " y: " << y << endl;
+ theTempCursor.push(static_cast<UpdatableInset*>(inset));
+ }
+ return inset;
+ }
+
+}
+
+
+bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd)
{
- switch (ev.action) {
+ switch (cmd.action) {
case LFUN_MOUSE_PRESS:
case LFUN_MOUSE_MOTION:
case LFUN_MOUSE_RELEASE:
case LFUN_MOUSE_DOUBLE:
- case LFUN_MOUSE_TRIPLE:
- {
+ case LFUN_MOUSE_TRIPLE: {
// We pass those directly to the Bufferview, since
// otherwise selection handling breaks down
screen().hideCursor();
- bool const res = dispatch(ev);
+ // 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;
+ }
+ }
+
+ // 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;
+ 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_);
- // FIXME: we should skip these when selecting
- owner_->updateLayoutChoice();
- owner_->updateToolbar();
- fitCursor();
+ // 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 res;
+ return true;
}
+
default:
- owner_->dispatch(ev);
+ owner_->dispatch(cmd);
return true;
}
}
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();
- break;
-
case LFUN_FONT_STATE:
owner_->getLyXFunc().setMessage(currentState(bv_));
break;
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));
InsetBase * inset = owner_->getDialogs().getOpenInset(name);
if (inset) {
// This works both for 'original' and 'mathed' insets.
- // Note that the localDispatch performs updateInset
- // also.
+ // Note that the localDispatch performs update also.
FuncRequest fr(bv_, LFUN_INSET_MODIFY, ev.argument);
inset->dispatch(fr);
} else {
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 check whether the update() is needed at all
- bv_->update();
- }
- } else {
+ if (!inset || !insertInset(inset))
delete inset;
- }
+ break;
}
- break;
case LFUN_FLOAT_LIST:
if (tclass.floats().typeExist(ev.argument)) {
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: {
- if (!bv_->owner()->getDialogs().visible("paragraph"))
- break;
- 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);
+ case LFUN_PARAGRAPH_UPDATE:
+ updateParagraphDialog();
break;
- }
case LFUN_PARAGRAPH_APPLY:
setParagraphParams(*bv_, ev.argument);
break;
- case LFUN_THESAURUS_ENTRY:
- {
+ case LFUN_THESAURUS_ENTRY: {
string arg = ev.argument;
if (arg.empty()) {
}
bv_->owner()->getDialogs().show("thesaurus", arg);
- }
break;
+ }
case LFUN_TRACK_CHANGES:
trackChanges();
case LFUN_ACCEPT_ALL_CHANGES: {
bv_->text->setCursor(0, 0);
#warning FIXME changes
- //moveCursorUpdate(false);
-
while (lyx::find::findNextChange(bv_))
bv_->getLyXText()->acceptChange();
-
update();
break;
}
case LFUN_REJECT_ALL_CHANGES: {
bv_->text->setCursor(0, 0);
#warning FIXME changes
- //moveCursorUpdate(false);
-
while (lyx::find::findNextChange(bv_))
bv_->getLyXText()->rejectChange();
-
update();
break;
}
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()) {
return bv_->theLockingInset()->insertInset(bv_, inset);
return false;
}
+#endif
// not quite sure if we want this...
bv_->text->recUndo(bv_->text->cursor.par());
freezeUndo();
- beforeChange(bv_->text);
+ bv_->text->clearSelection();
if (!lout.empty()) {
bv_->text->breakParagraph(bv_->buffer()->paragraphs());
string lres = lout;
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->setLayout(hasLayout ? lres : tclass.defaultLayoutName());
bv_->text->setParagraph(
VSpace(VSpace::NONE), VSpace(VSpace::NONE),
string(),
0);
}
-
- bv_->text->insertInset(inset);
- update();
-
+ bv_->cursor().innerText()->insertInset(inset);
unFreezeUndo();
return true;
}
-void BufferView::Pimpl::updateInset(InsetOld const * inset)
-{
- if (!available())
- return;
-
- bv_->text->redoParagraph(outerPar(*bv_->buffer(), inset));
-
- // this should not be needed, but it is...
- // bv_->text->redoParagraph(bv_->text->cursorPar());
- // bv_->text->fullRebreak();
-
- update();
- updateScrollbar();
-}
-
-
bool BufferView::Pimpl::ChangeInsets(InsetOld::Code code,
string const & from, string const & to)
{
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);
+}
+
+