X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView_pimpl.C;h=62c17dbb500b0778d062713acdf99a9b2b192880;hb=10ba1b8918e7da14334bb5573ce2a707671c8b51;hp=8f3c60cd1a219c78108b9d248db78a18251652f6;hpb=6c9b23105c2753c91870f50f517edc7ffb8890e5;p=lyx.git diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 8f3c60cd1a..62c17dbb50 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -23,6 +23,7 @@ #include "buffer_funcs.h" #include "bufferlist.h" #include "bufferparams.h" +#include "coordcache.h" #include "cursor.h" #include "debug.h" #include "dispatchresult.h" @@ -44,6 +45,7 @@ #include "paragraph_funcs.h" #include "ParagraphParameters.h" #include "pariterator.h" +#include "rowpainter.h" #include "undo.h" #include "vspace.h" @@ -66,9 +68,12 @@ #include "support/globbing.h" #include "support/path_defines.h" #include "support/tostr.h" +#include "support/types.h" #include +#include + using lyx::pos_type; using lyx::support::AddPath; @@ -78,6 +83,7 @@ using lyx::support::FileSearch; using lyx::support::ForkedcallsController; using lyx::support::IsDirWriteable; using lyx::support::MakeDisplayPath; +using lyx::support::MakeAbsPath; using lyx::support::strToUnsignedInt; using lyx::support::system_lyxdir; @@ -86,6 +92,7 @@ using std::istringstream; using std::make_pair; using std::min; using std::string; +using std::mem_fun_ref; extern BufferList bufferlist; @@ -109,17 +116,31 @@ boost::signals::connection selectioncon; boost::signals::connection lostcon; +/// Get next inset of this class from current cursor position +template +T * getInsetByCode(LCursor & cur, InsetBase::Code code) +{ + T * inset = 0; + DocIterator it = cur; + if (it.nextInset() && + it.nextInset()->lyxCode() == code) { + inset = static_cast(it.nextInset()); + } + return inset; +} + + } // anon namespace BufferView::Pimpl::Pimpl(BufferView & bv, LyXView * owner, - int xpos, int ypos, int width, int height) + int width, int height) : 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)); + workarea_.reset(WorkAreaFactory::create(*owner_, width, height)); screen_.reset(LyXScreenFactory::create(workarea())); // Setup the signals @@ -309,8 +330,17 @@ void BufferView::Pimpl::setBuffer(Buffer * b) if (buffer_) disconnectBuffer(); - // set current buffer - buffer_ = b; + // if we are closing current buffer, switch to the first in + // buffer list. + if (!b) { + lyxerr[Debug::INFO] << " No Buffer!" << endl; + // we are closing the buffer, use the first buffer as current + buffer_ = bufferlist.first(); + owner_->getDialogs().hideBufferDependent(); + } else { + // set current buffer + buffer_ = b; + } // reset old cursor top_y_ = 0; @@ -327,6 +357,7 @@ void BufferView::Pimpl::setBuffer(Buffer * b) cursor_.push(buffer_->inset()); cursor_.resetAnchor(); buffer_->text().init(bv_); + buffer_->text().setCurrentFont(cursor_); // If we don't have a text object for this, we make one //if (bv_->text() == 0) @@ -336,28 +367,32 @@ void BufferView::Pimpl::setBuffer(Buffer * b) // 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(); } update(); updateScrollbar(); owner_->updateMenubar(); - owner_->updateToolbar(); + owner_->updateToolbars(); owner_->updateLayoutChoice(); owner_->updateWindowTitle(); - if (lyx::graphics::Previews::activated() && buffer_) + // This is done after the layout combox has been populated + if (buffer_) + owner_->setLayout(cursor_.paragraph().layout()->name()); + + if (buffer_ && lyx::graphics::Previews::status() != LyXRC::PREVIEW_OFF) lyx::graphics::Previews::get().generateBufferPreviews(*buffer_); } bool BufferView::Pimpl::fitCursor() { + // to get the correct y cursor info + lyxerr[Debug::DEBUG] << "BufferView::fitCursor" << std::endl; + lyx::pit_type const pit = bv_->cursor().bottom().pit(); + bv_->text()->redoParagraph(pit); + refreshPar(*bv_, *bv_->text(), pit); + if (!screen().fitCursor(bv_)) return false; updateScrollbar(); @@ -367,7 +402,7 @@ bool BufferView::Pimpl::fitCursor() void BufferView::Pimpl::redoCurrentBuffer() { - lyxerr[Debug::INFO] << "BufferView::redoCurrentBuffer" << endl; + lyxerr[Debug::DEBUG] << "BufferView::redoCurrentBuffer" << endl; if (buffer_ && bv_->text()) { resizeCurrentBuffer(); updateScrollbar(); @@ -378,7 +413,7 @@ void BufferView::Pimpl::redoCurrentBuffer() void BufferView::Pimpl::resizeCurrentBuffer() { - lyxerr[Debug::INFO] << "resizeCurrentBuffer" << endl; + lyxerr[Debug::DEBUG] << "resizeCurrentBuffer" << endl; owner_->busy(true); owner_->message(_("Formatting document...")); @@ -388,7 +423,6 @@ void BufferView::Pimpl::resizeCurrentBuffer() text->init(bv_); update(); - bv_->cursor().updatePos(); fitCursor(); switchKeyMap(); @@ -404,8 +438,7 @@ void BufferView::Pimpl::resizeCurrentBuffer() void BufferView::Pimpl::updateScrollbar() { if (!bv_->text()) { - lyxerr[Debug::GUI] << "no text in updateScrollbar" << endl; - lyxerr << "no text in updateScrollbar" << endl; + lyxerr[Debug::DEBUG] << "no text in updateScrollbar" << endl; workarea().setScrollbarParams(0, 0, 0); return; } @@ -565,15 +598,26 @@ void BufferView::Pimpl::update() // check needed to survive LyX startup if (buffer_) { + // update macro store + buffer_->buildMacros(); + // update all 'visible' paragraphs - lyx::par_type beg, end; + lyx::pit_type beg, end; getParsInRange(buffer_->paragraphs(), top_y(), top_y() + workarea().workHeight(), beg, end); bv_->text()->redoParagraphs(beg, end); + + // and the scrollbar updateScrollbar(); } + + // remove old position cache + theCoords.clear(); + + // The real, big redraw. screen().redraw(*bv_); + bv_->owner()->view_state_changed(); } @@ -613,7 +657,7 @@ Change const BufferView::Pimpl::getCurrentChange() if (!cur.selection()) return Change(Change::UNCHANGED); - return text->getPar(cur.selBegin().par()). + return text->getPar(cur.selBegin().pit()). lookupChangeFull(cur.selBegin().pos()); } @@ -715,47 +759,6 @@ void BufferView::Pimpl::stuffClipboard(string const & stuff) const } -InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code /*code*/) -{ -#ifdef WITH_WARNINGS -#warning Does not work for mathed -#endif - // Ok, this is a little bit too brute force but it - // should work for now. Better infrastructure is coming. (Lgb) - -#warning FIXME -#if 0 - Buffer * buf = bv_->buffer(); - InsetIterator beg = inset_iterator_begin(buf->inset()); - - bool cursor_par_seen = false; - - LCursor & cur = bv_->cursor(); - LyXText * = bv_->getLyXText(); - ParagraphList::iterator pit = text->getPar(cur.par()); - - for (; beg; ++beg) { - if (beg.par() == pit) - cursor_par_seen = true; - if (cursor_par_seen) { - if (beg.par() == pit && beg.pos() >= cur.pos()) - break; - if (beg.getPar() != pit) - break; - } - } - if (beg) { - // Now find the first inset that matches code. - for (; beg; ++beg) { - if (beg->lyxCode() == code) - return &(*beg); - } - } -#endif - return 0; -} - - void BufferView::Pimpl::MenuInsertLyXFile(string const & filenm) { string filename = filenm; @@ -801,12 +804,19 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filenm) string const disp_fn = MakeDisplayPath(filename); owner_->message(bformat(_("Inserting document %1$s..."), disp_fn)); - if (bv_->insertLyXFile(filename)) - owner_->message(bformat(_("Document %1$s inserted."), - disp_fn)); - else - owner_->message(bformat(_("Could not insert document %1$s"), - disp_fn)); + + bv_->cursor().clearSelection(); + bv_->text()->breakParagraph(bv_->cursor()); + + BOOST_ASSERT(bv_->cursor().inTexted()); + + string const fname = MakeAbsPath(filename); + bool const res = bv_->buffer()->readFile(fname, bv_->cursor().pit()); + bv_->resize(); + + string s = res ? _("Document %1$s inserted.") + : _("Could not insert document %1$s"); + owner_->message(bformat(s, disp_fn)); } @@ -816,9 +826,9 @@ void BufferView::Pimpl::trackChanges() 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(); + for_each(buf->par_iterator_begin(), + buf->par_iterator_end(), + bind(&Paragraph::trackChanges, _1, Change::UNCHANGED)); buf->params().tracking_changes = true; // we cannot allow undos beyond the freeze point @@ -835,9 +845,10 @@ void BufferView::Pimpl::trackChanges() return; } - ParIterator const end = buf->par_iterator_end(); - for (ParIterator it = buf->par_iterator_begin(); it != end; ++it) - it->untrackChanges(); + for_each(buf->par_iterator_begin(), + buf->par_iterator_end(), + mem_fun_ref(&Paragraph::untrackChanges)); + buf->params().tracking_changes = false; } @@ -847,18 +858,22 @@ void BufferView::Pimpl::trackChanges() bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) { + lyxerr << "BufferView::Pimpl::workAreaDispatch: request: " + << cmd0 << std::endl; // this is only called for mouse related events including // LFUN_FILE_OPEN generated by drag-and-drop. FuncRequest cmd = cmd0; - // handle drag&deop + // handle drag&drop if (cmd.action == LFUN_FILE_OPEN) { owner_->dispatch(cmd); return true; } cmd.y += bv_->top_y(); - //lyxerr << "*** workAreaDispatch: request: " << cmd << std::endl; + if (!bv_->buffer()) + return false; + LCursor cur(*bv_); cur.push(bv_->buffer()->inset()); cur.selection() = bv_->cursor().selection(); @@ -877,8 +892,9 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) // 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; + lyxerr << " * created temp cursor: " << inset << endl; + lyxerr << " * hit inset at tip: " << inset << endl; + lyxerr << " * created temp cursor:" << cur << endl; // Put anchor at the same position. cur.resetAnchor(); @@ -886,21 +902,20 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) // 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; + // cur.bv().cursor() = cur; (or similar) 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); + // be modified, the inset's dispatch has to do so explicitly. + if (!cur.result().dispatched()) + cur.dispatch(cmd); - // Redraw if requested or necessary. - if (res.update()) - update(); - if (fitCursor()) - update(); + if (cur.result().dispatched()) { + // Redraw if requested or necessary. + if (fitCursor() || cur.result().update()) + update(); + } // see workAreaKeyPress cursor_timeout.restart(); @@ -909,7 +924,7 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) // skip these when selecting if (cmd.action != LFUN_MOUSE_MOTION) { owner_->updateLayoutChoice(); - owner_->updateToolbar(); + owner_->updateToolbars(); } // slight hack: this is only called currently when we @@ -947,6 +962,8 @@ FuncStatus BufferView::Pimpl::getStatus(FuncRequest const & cmd) case LFUN_MARK_ON: case LFUN_SETMARK: case LFUN_CENTER: + case LFUN_BEGINNINGBUF: + case LFUN_ENDBUF: case LFUN_BEGINNINGBUFSEL: case LFUN_ENDBUFSEL: flag.enabled(true); @@ -1029,16 +1046,6 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) cur.message(cur.currentState()); break; - case LFUN_INSERT_LABEL: { - // Try and generate a valid label - string const contents = cmd.argument.empty() ? - cur.getPossibleLabel() : cmd.argument; - InsetCommandParams icp("label", contents); - string data = InsetCommandMailer::params2string("label", icp); - owner_->getDialogs().show("label", data, 0); - break; - } - case LFUN_BOOKMARK_SAVE: savePosition(strToUnsignedInt(cmd.argument)); break; @@ -1051,7 +1058,8 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) string label = cmd.argument; if (label.empty()) { InsetRef * inset = - static_cast(getInsetByCode(InsetBase::REF_CODE)); + getInsetByCode(bv_->cursor(), + InsetBase::REF_CODE); if (inset) { label = inset->getContents(); savePosition(0); @@ -1089,7 +1097,6 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) #endif while (lyx::find::findNextChange(bv_)) bv_->getLyXText()->rejectChange(bv_->cursor()); - update(); break; } @@ -1103,7 +1110,6 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) case LFUN_MARK_OFF: cur.clearSelection(); - update(); cur.resetAnchor(); cur.message(N_("Mark off")); break; @@ -1111,7 +1117,6 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) case LFUN_MARK_ON: cur.clearSelection(); cur.mark() = true; - update(); cur.resetAnchor(); cur.message(N_("Mark on")); break; @@ -1126,7 +1131,6 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) cur.message(N_("Mark set")); } cur.resetAnchor(); - update(); break; case LFUN_CENTER: