diff --git a/src/BufferView.C b/src/BufferView.C index 573da75b7a..1cce3fed18 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -43,7 +43,6 @@ #include "insets/insetcommand.h" // ChangeRefs #include "insets/updatableinset.h" -#include "insets/insettext.h" #include "support/filetools.h" #include "support/lyxalgo.h" // lyx_count @@ -103,15 +102,15 @@ Painter & BufferView::painter() const } -void BufferView::setBuffer(Buffer * b) +void BufferView::buffer(Buffer * b) { - pimpl_->setBuffer(b); + pimpl_->buffer(b); } -void BufferView::newFile(string const & fn, string const & tn, bool named) +bool BufferView::newFile(string const & fn, string const & tn, bool named) { - pimpl_->newFile(fn, tn, named); + return pimpl_->newFile(fn, tn, named); } @@ -333,9 +332,7 @@ void BufferView::hideCursor() LyXText * BufferView::getLyXText() const { - LyXText * text = cursor().innerText(); - BOOST_ASSERT(text); - return text; + return cursor().innerText(); } @@ -347,6 +344,19 @@ Language const * BufferView::getParentLanguage(InsetOld * inset) const } +Encoding const * BufferView::getEncoding() const +{ + LyXText * t = getLyXText(); + if (!t) + return 0; + CursorSlice const & cur = cursor().innerTextSlice(); + return t->getPar(cur.par())->getFont( + buffer()->params(), cur.pos(), + outerFont(t->getPar(cur.par()), t->paragraphs()) + ).language()->encoding(); +} + + void BufferView::haveSelection(bool sel) { pimpl_->workarea().haveSelection(sel); @@ -361,22 +371,22 @@ int BufferView::workHeight() const LyXText * BufferView::text() const { - return buffer() ? &buffer()->text() : 0; + return pimpl_->buffer_ ? &pimpl_->buffer_->text() : 0; } -void BufferView::setCursor(ParIterator const & par, lyx::pos_type pos) +void BufferView::setCursor(ParIterator const & par, + lyx::pos_type pos) { LCursor & cur = cursor(); cur.reset(); - cur.push(buffer()->inset()); ParIterator::PosHolder const & positions = par.positions(); int const last = par.size() - 1; for (int i = 0; i < last; ++i) (*positions[i].it)->inset->edit(cur, true); cur.resetAnchor(); - LyXText * text = par.text(*buffer()); - text->setCursor(cur, text->parOffset(par.pit()), pos); + LyXText * lt = par.text(*buffer()); + lt->setCursor(cur, lt->parOffset(par.pit()), pos); } diff --git a/src/BufferView.h b/src/BufferView.h index a8cae7000b..9c50f9597b 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -58,7 +58,7 @@ public: ~BufferView(); /// set the buffer we are viewing - void setBuffer(Buffer * b); + void buffer(Buffer * b); /// return the buffer being viewed Buffer * buffer() const; @@ -81,7 +81,7 @@ public: /// reload the contained buffer void reload(); /// create a new buffer based on template - void newFile(std::string const & fname, std::string const & tname, + bool newFile(std::string const & fname, std::string const & tname, bool named = true); /// load a buffer into the view bool loadLyXFile(std::string const & name, bool tolastfiles = true); @@ -111,6 +111,9 @@ public: /// return the lyxtext we are using LyXText * getLyXText() const; + /// return the current encoding at the cursor + Encoding const * getEncoding() const; + /// return the parent language of the given inset Language const * getParentLanguage(InsetOld * inset) const; diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 98ec94d012..c7d75389e9 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -46,7 +46,6 @@ #include "vspace.h" #include "insets/insetref.h" -#include "insets/insettext.h" #include "frontends/Alert.h" #include "frontends/Dialogs.h" @@ -158,32 +157,19 @@ void BufferView::Pimpl::connectBuffer(Buffer & buf) disconnectBuffer(); errorConnection_ = - buf.error.connect( - boost::bind(&BufferView::Pimpl::addError, this, _1)); - + buf.error.connect(boost::bind(&BufferView::Pimpl::addError, this, _1)); messageConnection_ = - buf.message.connect( - boost::bind(&LyXView::message, owner_, _1)); - + buf.message.connect(boost::bind(&LyXView::message, owner_, _1)); busyConnection_ = - buf.busy.connect( - boost::bind(&LyXView::busy, owner_, _1)); - + buf.busy.connect(boost::bind(&LyXView::busy, owner_, _1)); titleConnection_ = - buf.updateTitles.connect( - boost::bind(&LyXView::updateWindowTitle, owner_)); - + buf.updateTitles.connect(boost::bind(&LyXView::updateWindowTitle, owner_)); timerConnection_ = - buf.resetAutosaveTimers.connect( - boost::bind(&LyXView::resetAutosaveTimer, owner_)); - + buf.resetAutosaveTimers.connect(boost::bind(&LyXView::resetAutosaveTimer, owner_)); readonlyConnection_ = - buf.readonly.connect( - boost::bind(&BufferView::Pimpl::showReadonly, this, _1)); - + buf.readonly.connect(boost::bind(&BufferView::Pimpl::showReadonly, this, _1)); closingConnection_ = - buf.closing.connect( - boost::bind(&BufferView::Pimpl::setBuffer, this, (Buffer *)0)); + buf.closing.connect(boost::bind(&BufferView::Pimpl::buffer, this, (Buffer *)0)); } @@ -199,10 +185,13 @@ void BufferView::Pimpl::disconnectBuffer() } -void BufferView::Pimpl::newFile(string const & filename, string const & tname, - bool isNamed) +bool BufferView::Pimpl::newFile(string const & filename, + string const & tname, + bool isNamed) { - setBuffer(::newFile(filename, tname, isNamed)); + Buffer * b = ::newFile(filename, tname, isNamed); + buffer(b); + return true; } @@ -227,13 +216,14 @@ bool BufferView::Pimpl::loadLyXFile(string const & filename, bool tolastfiles) text, 0, 1, _("&Revert"), _("&Switch to document")); if (ret != 0) { - setBuffer(bufferlist.getBuffer(s)); + buffer(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; @@ -258,7 +248,7 @@ bool BufferView::Pimpl::loadLyXFile(string const & filename, bool tolastfiles) return false; } - setBuffer(b); + buffer(b); bv_->showErrorList(_("Parse")); if (tolastfiles) @@ -298,45 +288,48 @@ int BufferView::Pimpl::top_y() const } -void BufferView::Pimpl::setBuffer(Buffer * b) +void BufferView::Pimpl::buffer(Buffer * b) { lyxerr[Debug::INFO] << "Setting buffer in BufferView (" << b << ')' << endl; - if (buffer_) + if (buffer_) { disconnectBuffer(); + //delete bv_->text(); + //bv_->setText(0); + } + + // reset old cursor + cursor_.reset(); // 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_); - cursor_.push(buffer_->inset()); - cursor_.resetAnchor(); buffer_->text().init(bv_); // If we don't have a text object for this, we make one - //if (bv_->text() == 0) - // resizeCurrentBuffer(); + 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(); } @@ -347,6 +340,10 @@ void BufferView::Pimpl::setBuffer(Buffer * b) owner_->updateLayoutChoice(); owner_->updateWindowTitle(); + // Don't forget to update the Layout + if (buffer_) + owner_->setLayout(bv_->text()->getPar(0)->layout()->name()); + if (lyx::graphics::Previews::activated() && buffer_) lyx::graphics::Previews::get().generateBufferPreviews(*buffer_); } @@ -354,10 +351,11 @@ void BufferView::Pimpl::setBuffer(Buffer * b) bool BufferView::Pimpl::fitCursor() { - if (!screen().fitCursor(bv_)) - return false; - updateScrollbar(); - return true; + if (screen().fitCursor(bv_)) { + updateScrollbar(); + return true; + } + return false; } @@ -441,17 +439,15 @@ void BufferView::Pimpl::updateScrollbar() { 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(); - lyxerr[Debug::GUI] - << "Updating scrollbar: height: " << t.height() - << " top_y: " << top_y() - << " default height " << defaultRowHeight() << endl; + lyxerr[Debug::GUI] << "Updating scrollbar: h" << t.height() + << ", top_y()" << top_y() << ", default height " + << defaultRowHeight() << endl; workarea().setScrollbarParams(t.height(), top_y(), defaultRowHeight()); } @@ -596,11 +592,11 @@ void BufferView::Pimpl::workAreaResize() void BufferView::Pimpl::update() { - //lyxerr << "BufferView::Pimpl::update(), buffer: " << buffer_ << endl; + //lyxerr << "BufferView::update()" << endl; // fix cursor coordinate cache in case something went wrong // check needed to survive LyX startup - if (buffer_) { + if (bv_->getLyXText()) { // update all 'visible' paragraphs ParagraphList::iterator beg; ParagraphList::iterator end; @@ -676,7 +672,7 @@ void BufferView::Pimpl::restorePosition(unsigned int i) ::loadLyXFile(b, fname); // don't ask, just load it } if (b) - setBuffer(b); + buffer(b); } ParIterator par = buffer_->getParFromID(saved_positions[i].par_id); @@ -877,8 +873,6 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) cmd.y += bv_->top_y(); //lyxerr << "*** workAreaDispatch: request: " << cmd << std::endl; LCursor cur(*bv_); - cur.push(bv_->buffer()->inset()); - cur.resetAnchor(); cur.selection() = bv_->cursor().selection(); switch (cmd.action) { @@ -887,7 +881,14 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) if (!available()) return false; FuncRequest cmd1 = cmd; - DispatchResult res = cur.inset().dispatch(cur, cmd); + InsetBase * inset = cur.inset(); + DispatchResult res; + if (inset) { + res = inset->dispatch(cur, cmd); + } else { + res = bv_->text()->dispatch(cur, cmd); + } + if (fitCursor() || res.update()) { update(); cur.updatePos(); @@ -1122,22 +1123,6 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) bv_->center(); break; - case LFUN_BEGINNINGBUFSEL: - bv_->cursor().reset(); - if (!cur.selection()) - cur.resetAnchor(); - bv_->text()->cursorTop(cur); - finishUndo(); - break; - - case LFUN_ENDBUFSEL: - bv_->cursor().reset(); - if (!cur.selection()) - cur.resetAnchor(); - bv_->text()->cursorBottom(cur); - finishUndo(); - break; - default: return false; } diff --git a/src/BufferView_pimpl.h b/src/BufferView_pimpl.h index bb969dff47..33e21fd671 100644 --- a/src/BufferView_pimpl.h +++ b/src/BufferView_pimpl.h @@ -52,7 +52,7 @@ struct BufferView::Pimpl : public boost::signals::trackable { /// return the screen for this bview LyXScreen & screen() const; /// - void setBuffer(Buffer * buf); + void buffer(Buffer *); /// Return true if the cursor was fitted. bool fitCursor(); /// @@ -61,8 +61,12 @@ struct BufferView::Pimpl : public boost::signals::trackable { void resizeCurrentBuffer(); /// void update(); + /** + * Repaint pixmap. Used for when we've made a visible + * change but don't need the full update() logic + */ /// - void newFile(std::string const &, std::string const &, bool); + bool newFile(std::string const &, std::string const &, bool); /// bool loadLyXFile(std::string const &, bool); /// diff --git a/src/buffer.C b/src/buffer.C index e51d58b80a..45672b850a 100644 --- a/src/buffer.C +++ b/src/buffer.C @@ -180,15 +180,15 @@ struct Buffer::Impl */ bool file_fully_loaded; - /// our LyXText that should be wrapped in an InsetText - InsetText inset; + /// our text + LyXText text; }; Buffer::Impl::Impl(Buffer & parent, string const & file, bool readonly_) : lyx_clean(true), bak_clean(true), unnamed(false), read_only(readonly_), filename(file), filepath(OnlyPath(file)), file_fully_loaded(false), - inset(params) + text(0, 0) { lyxvc.buffer(&parent); temppath = createBufferTmpDir(); @@ -202,7 +202,6 @@ Buffer::Buffer(string const & file, bool ronly) : pimpl_(new Impl(*this, file, ronly)) { lyxerr[Debug::INFO] << "Buffer::Buffer()" << endl; - lyxerr << "Buffer::Buffer()" << endl; } @@ -226,13 +225,7 @@ Buffer::~Buffer() LyXText & Buffer::text() const { - return const_cast(pimpl_->inset.text_); -} - - -InsetBase & Buffer::inset() const -{ - return const_cast(pimpl_->inset); + return const_cast(pimpl_->text); } @@ -274,13 +267,13 @@ BufferParams const & Buffer::params() const ParagraphList & Buffer::paragraphs() { - return text().paragraphs(); + return pimpl_->text.paragraphs(); } ParagraphList const & Buffer::paragraphs() const { - return text().paragraphs(); + return pimpl_->text.paragraphs(); } @@ -648,18 +641,12 @@ bool Buffer::readFile(LyXLex & lex, string const & filename, bool the_end = readBody(lex); params().setPaperStuff(); -#warning Look here! -#if 0 - if (token == "\\end_document") - the_end_read = true; - if (!the_end) { Alert::error(_("Document format failure"), bformat(_("%1$s ended unexpectedly, which means" " that it is probably corrupted."), filename)); } -#endif pimpl_->file_fully_loaded = true; return true; } diff --git a/src/buffer.h b/src/buffer.h index 0a82f73b96..ccff3086d4 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -32,7 +32,6 @@ class BufferParams; class ErrorItem; class FuncRequest; class InsetBase; -class InsetText; class LyXFont; class LyXLex; class LyXRC; @@ -360,8 +359,6 @@ public: /// LyXText & text() const; - /// - InsetBase & inset() const; private: /** Inserts a file into a document diff --git a/src/buffer_funcs.C b/src/buffer_funcs.C index bcbd98dce0..dbb5e556d9 100644 --- a/src/buffer_funcs.C +++ b/src/buffer_funcs.C @@ -177,7 +177,12 @@ Buffer * newFile(string const & filename, string const & templatename, string const text = bformat(_("The specified document template\n%1$s\ncould not be read."), file); Alert::error(_("Could not read template"), text); // no template, start with empty buffer + b->paragraphs().push_back(Paragraph()); + b->paragraphs().begin()->layout(b->params().getLyXTextClass().defaultLayout()); } + } else { // start with empty buffer + b->paragraphs().push_back(Paragraph()); + b->paragraphs().begin()->layout(b->params().getLyXTextClass().defaultLayout()); } if (!isNamed) { diff --git a/src/cursor.C b/src/cursor.C index abcb92017d..ab0fc05d94 100644 --- a/src/cursor.C +++ b/src/cursor.C @@ -12,23 +12,19 @@ #include -#include "BufferView.h" #include "buffer.h" +#include "BufferView.h" #include "cursor.h" #include "debug.h" #include "dispatchresult.h" -#include "encoding.h" #include "funcrequest.h" #include "iterators.h" -#include "language.h" #include "lfuns.h" -#include "lyxfont.h" #include "lyxfunc.h" // only for setMessage() #include "lyxrc.h" #include "lyxrow.h" #include "lyxtext.h" #include "paragraph.h" -#include "paragraph_funcs.h" #include "insets/updatableinset.h" #include "insets/insettabular.h" @@ -61,7 +57,7 @@ limited_stack theCutBuffer; LCursor::LCursor(BufferView & bv) - : DocumentIterator(), bv_(&bv), anchor_(), + : DocumentIterator(bv), anchor_(bv), cached_y_(0), x_target_(-1), selection_(false), mark_(false) {} @@ -90,9 +86,6 @@ void LCursor::setCursor(DocumentIterator const & cur, bool sel) DispatchResult LCursor::dispatch(FuncRequest const & cmd0) { //lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl; - if (empty()) - return DispatchResult(false); - BOOST_ASSERT(pos() <= lastpos()); BOOST_ASSERT(idx() <= lastidx()); BOOST_ASSERT(par() <= lastpar()); @@ -101,36 +94,38 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0) DocumentIterator orig = *this; disp_.update(true); disp_.val(NONE); - - // the inset's dispatch() is supposed to reset the update and - // val flags if necessary - inset().dispatch(*this, cmd); + while (size() != 1) { + // the inset's dispatch() is supposed to reset the update and + // val flags if necessary + inset()->dispatch(*this, cmd); - // "Mutate" the request for semi-handled requests that need - // additional handling in outer levels. - switch (disp_.val()) { - case NONE: - // the inset handled the event fully - return DispatchResult(true, true); - case FINISHED_LEFT: - // the inset handled the event partially - cmd = FuncRequest(LFUN_FINISHED_LEFT); - break; - case FINISHED_RIGHT: - cmd = FuncRequest(LFUN_FINISHED_RIGHT); - break; - case FINISHED_UP: - cmd = FuncRequest(LFUN_FINISHED_UP); - break; - case FINISHED_DOWN: - cmd = FuncRequest(LFUN_FINISHED_DOWN); - break; - default: - //lyxerr << "not handled on level " << depth() - // << " val: " << disp_.val() << endl; - break; + // "Mutate" the request for semi-handled requests that need + // additional handling in outer levels. + switch (disp_.val()) { + case NONE: + // the inset handled the event fully + return DispatchResult(true, true); + case FINISHED_LEFT: + // the inset handled the event partially + cmd = FuncRequest(LFUN_FINISHED_LEFT); + break; + case FINISHED_RIGHT: + cmd = FuncRequest(LFUN_FINISHED_RIGHT); + break; + case FINISHED_UP: + cmd = FuncRequest(LFUN_FINISHED_UP); + break; + case FINISHED_DOWN: + cmd = FuncRequest(LFUN_FINISHED_DOWN); + break; + default: + //lyxerr << "not handled on level " << depth() + // << " val: " << disp_.val() << endl; + break; + } + pop(); } - pop(); + bv().text()->dispatch(*this, cmd); if (nopop_) setCursor(orig, false); //lyxerr << " result: " << res.val() << endl; @@ -150,7 +145,7 @@ bool LCursor::getStatus(FuncRequest const & cmd, FuncStatus & status) // a definitive decision on whether it want to handle the // request or not. The result of this decision is put into // the 'status' parameter. - bool const res = inset().getStatus(*this, cmd, status); + bool const res = inset()->getStatus(*this, cmd, status); if (res) { setCursor(orig, false); return true; @@ -164,10 +159,20 @@ bool LCursor::getStatus(FuncRequest const & cmd, FuncStatus & status) BufferView & LCursor::bv() const { - return *bv_; + return DocumentIterator::bv(); } +/* +void LCursor::pop(int depth) +{ + while (int(size()) > depth + 1) + pop(); + lyxerr << "LCursor::pop() result: " << *this << endl; +} +*/ + + void LCursor::pop() { BOOST_ASSERT(size() >= 1); @@ -176,18 +181,18 @@ void LCursor::pop() } -void LCursor::push(InsetBase & p) +void LCursor::push(InsetBase * p) { push_back(CursorSlice(p)); } -void LCursor::pushLeft(InsetBase & p) +void LCursor::pushLeft(InsetBase * p) { BOOST_ASSERT(!empty()); //lyxerr << "Entering inset " << t << " left" << endl; push(p); - p.idxFirst(*this); + p->idxFirst(*this); } @@ -197,10 +202,10 @@ bool LCursor::popLeft() //lyxerr << "Leaving inset to the left" << endl; if (depth() <= 1) { if (depth() == 1) - inset().notifyCursorLeaves(idx()); + inset()->notifyCursorLeaves(idx()); return false; } - inset().notifyCursorLeaves(idx()); + inset()->notifyCursorLeaves(idx()); pop(); return true; } @@ -212,10 +217,10 @@ bool LCursor::popRight() //lyxerr << "Leaving inset to the right" << endl; if (depth() <= 1) { if (depth() == 1) - inset().notifyCursorLeaves(idx()); + inset()->notifyCursorLeaves(idx()); return false; } - inset().notifyCursorLeaves(idx()); + inset()->notifyCursorLeaves(idx()); pop(); ++pos(); return true; @@ -226,7 +231,7 @@ int LCursor::currentMode() { BOOST_ASSERT(!empty()); for (int i = size() - 1; i >= 1; --i) { - int res = operator[](i).inset().currentMode(); + int res = operator[](i).inset()->currentMode(); if (res != MathInset::UNDECIDED_MODE) return res; } @@ -238,8 +243,8 @@ void LCursor::updatePos() { BOOST_ASSERT(!empty()); if (size() > 1) - cached_y_ = bv().top_y() + back().inset().yo(); - //cached_y_ = back().inset().yo(); + cached_y_ = bv().top_y() + back().inset()->yo(); + //cached_y_ = back().inset()->yo(); } @@ -247,8 +252,9 @@ void LCursor::getDim(int & asc, int & des) const { BOOST_ASSERT(!empty()); if (inMathed()) { - BOOST_ASSERT(inset().asMathInset()); - //inset().asMathInset()->getCursorDim(asc, des); + BOOST_ASSERT(inset()); + BOOST_ASSERT(inset()->asMathInset()); + //inset()->asMathInset()->getCursorDim(asc, des); asc = 10; des = 10; } else { @@ -268,10 +274,14 @@ void LCursor::getPos(int & x, int & y) const x = bv().text()->cursorX(front()); y = bv().text()->cursorY(front()); } else { - inset().getCursorPos(back(), x, y); + if (!inset()) { + lyxerr << "#### LCursor::getPos: " << *this << endl; + BOOST_ASSERT(inset()); + } + inset()->getCursorPos(back(), x, y); // getCursorPos gives _screen_ coordinates. We need to add // top_y to get document coordinates. This is hidden in cached_y_. - //y += cached_y_ - inset().yo(); + //y += cached_y_ - inset()->yo(); // The rest is non-obvious. The reason we have to have these // extra computation is that the getCursorPos() calls rely // on the inset's own knowledge of its screen position. @@ -411,7 +421,7 @@ void LCursor::clearTargetX() void LCursor::info(std::ostream & os) const { for (int i = 1, n = depth(); i < n; ++i) { - operator[](i).inset().infoize(os); + operator[](i).inset()->infoize(os); os << " "; } if (pos() != 0) @@ -427,13 +437,13 @@ void region(CursorSlice const & i1, CursorSlice const & i2, LCursor::row_type & r1, LCursor::row_type & r2, LCursor::col_type & c1, LCursor::col_type & c2) { - InsetBase & p = i1.inset(); - c1 = p.col(i1.idx_); - c2 = p.col(i2.idx_); + InsetBase * p = i1.inset(); + c1 = p->col(i1.idx_); + c2 = p->col(i2.idx_); if (c1 > c2) swap(c1, c2); - r1 = p.row(i1.idx_); - r2 = p.row(i2.idx_); + r1 = p->row(i1.idx_); + r2 = p->row(i2.idx_); if (r1 > r2) swap(r1, r2); } @@ -450,7 +460,7 @@ string LCursor::grabSelection() CursorSlice i2 = selEnd(); if (i1.idx_ == i2.idx_) { - if (i1.inset().asMathInset()) { + if (i1.inset()->asMathInset()) { MathArray::const_iterator it = i1.cell().begin(); return asString(MathArray(it + i1.pos_, it + i2.pos_)); } else { @@ -463,7 +473,7 @@ string LCursor::grabSelection() region(i1, i2, r1, r2, c1, c2); string data; - if (i1.inset().asMathInset()) { + if (i1.inset()->asMathInset()) { for (row_type row = r1; row <= r2; ++row) { if (row > r1) data += "\\\\"; @@ -486,7 +496,7 @@ void LCursor::eraseSelection() CursorSlice const & i1 = selBegin(); CursorSlice const & i2 = selEnd(); #warning FIXME - if (i1.inset().asMathInset()) { + if (i1.inset()->asMathInset()) { if (i1.idx_ == i2.idx_) { i1.cell().erase(i1.pos_, i2.pos_); } else { @@ -616,7 +626,7 @@ std::ostream & operator<<(std::ostream & os, LCursor const & cur) bool LCursor::isInside(InsetBase const * p) { for (unsigned i = 0; i < depth(); ++i) - if (&operator[](i).inset() == p) + if (operator[](i).inset() == p) return true; return false; } @@ -636,7 +646,7 @@ bool LCursor::openable(MathAtom const & t) const // we can't move into anything new during selection if (depth() == anchor_.size()) return false; - if (!ptr_cmp(t.nucleus(), &anchor_[depth()].inset())) + if (!ptr_cmp(t.nucleus(), anchor_[depth()].inset())) return false; return true; @@ -652,7 +662,7 @@ bool positionable(DocumentIterator const & cursor, // anchor might be deeper, should have same path then for (size_t i = 0; i < cursor.size(); ++i) - if (&cursor[i].inset() != &anchor[i].inset()) + if (cursor[i].inset() != anchor[i].inset()) return false; // position should be ok. @@ -761,7 +771,7 @@ void LCursor::niceInsert(MathAtom const & t) posLeft(); // be careful here: don't use 'pushLeft(t)' as this we need to // push the clone, not the original - pushLeft(*nextInset()); + pushLeft(nextAtom().nucleus()); paste(safe); } } @@ -787,7 +797,7 @@ bool LCursor::backspace() } if (pos() == 0) { - if (inset().nargs() == 1 && depth() == 1 && lastpos() == 0) + if (inset()->nargs() == 1 && depth() == 1 && lastpos() == 0) return false; pullArg(); return true; @@ -826,23 +836,23 @@ bool LCursor::erase() } // delete empty cells if possible - if (pos() == lastpos() && inset().idxDelete(idx())) + if (pos() == lastpos() && inset()->idxDelete(idx())) return true; // special behaviour when in last position of cell if (pos() == lastpos()) { - bool one_cell = inset().nargs() == 1; + bool one_cell = inset()->nargs() == 1; if (one_cell && depth() == 1 && lastpos() == 0) return false; // remove markup if (one_cell) pullArg(); else - inset().idxGlue(idx()); + inset()->idxGlue(idx()); return true; } - if (pos() != lastpos() && inset().nargs() > 0) { + if (pos() != lastpos() && inset()->nargs() > 0) { selection() = true; ++pos(); } else { @@ -915,7 +925,7 @@ void LCursor::handleNest(MathAtom const & a, int c) asArray(grabAndEraseSelection(), t.nucleus()->cell(c)); insert(t); posLeft(); - pushLeft(*nextInset()); + pushLeft(nextAtom().nucleus()); } @@ -933,7 +943,7 @@ int LCursor::targetX() const MathHullInset * LCursor::formula() const { for (int i = size() - 1; i >= 1; --i) { - MathInset * inset = operator[](i).inset().asMathInset(); + MathInset * inset = operator[](i).inset()->asMathInset(); if (inset && inset->asHullInset()) return static_cast(inset); } @@ -977,7 +987,7 @@ bool LCursor::inMacroArgMode() const MathGridInset * LCursor::enclosingGrid(idx_type & idx) const { for (MathInset::difference_type i = depth() - 1; i >= 0; --i) { - MathInset * m = operator[](i).inset().asMathInset(); + MathInset * m = operator[](i).inset()->asMathInset(); if (!m) return 0; MathGridInset * p = m->asGridInset(); @@ -1021,7 +1031,7 @@ void LCursor::normalize() if (idx() >= nargs()) { lyxerr << "this should not really happen - 1: " << idx() << ' ' << nargs() - << " in: " << &inset() << endl; + << " in: " << inset() << endl; } idx() = min(idx(), lastidx()); @@ -1030,7 +1040,7 @@ void LCursor::normalize() << pos() << ' ' << lastpos() << " in idx: " << idx() << " in atom: '"; WriteStream wi(lyxerr, false, true); - inset().asMathInset()->write(wi); + inset()->asMathInset()->write(wi); lyxerr << endl; } pos() = min(pos(), lastpos()); @@ -1098,7 +1108,7 @@ bool LCursor::goUpDown(bool up) } // try current cell for e.g. text insets - if (inset().idxUpDown2(*this, up)) + if (inset()->idxUpDown2(*this, up)) return true; //xarray().boundingBox(xlow, xhigh, ylow, yhigh); @@ -1113,9 +1123,9 @@ bool LCursor::goUpDown(bool up) // try to find an inset that knows better then we while (1) { - //lyxerr << "updown: We are in " << &inset() << " idx: " << idx() << endl; + //lyxerr << "updown: We are in " << inset() << " idx: " << idx() << endl; // ask inset first - if (inset().idxUpDown(*this, up)) { + if (inset()->idxUpDown(*this, up)) { // try to find best position within this inset if (!selection()) bruteFind2(xo, yo); @@ -1145,17 +1155,17 @@ bool LCursor::goUpDown(bool up) bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh) { - DocumentIterator best_cursor; + DocumentIterator best_cursor(bv()); double best_dist = 1e10; - DocumentIterator it = insetBegin(bv().buffer()->inset()); - DocumentIterator et = insetEnd(); + DocumentIterator it = bufferBegin(bv()); + DocumentIterator et = bufferEnd(); while (1) { // avoid invalid nesting when selecting if (!selection() || positionable(it, anchor_)) { int xo, yo; CursorSlice & cur = it.back(); - cur.inset().getCursorPos(cur, xo, yo); + cur.inset()->getCursorPos(cur, xo, yo); if (xlow <= xo && xo <= xhigh && ylow <= yo && yo <= yhigh) { double d = (x - xo) * (x - xo) + (y - yo) * (y - yo); //lyxerr << "x: " << x << " y: " << y << " d: " << endl; @@ -1190,7 +1200,7 @@ void LCursor::bruteFind2(int x, int y) for (int i = 0; ; ++i) { int xo, yo; CursorSlice & cur = it.back(); - cur.inset().getCursorPos(cur, xo, yo); + cur.inset()->getCursorPos(cur, xo, yo); double d = (x - xo) * (x - xo) + (y - yo) * (y - yo); // '<=' in order to take the last possible position // this is important for clicking behind \sum in e.g. '\sum_i a' @@ -1304,7 +1314,7 @@ string LCursor::selectionAsString(bool label) const return result; } -#warning and mathed? +#warning an mathed? return string(); } @@ -1316,11 +1326,7 @@ string LCursor::currentState() info(os); return os.str(); } - - if (inTexted()) - return text()->currentState(*this); - - return string(); + return text() ? text()->currentState(*this) : string(); } @@ -1351,27 +1357,6 @@ string LCursor::getPossibleLabel() } -Encoding const * LCursor::getEncoding() const -{ - if (empty()) - return 0; - if (!bv().buffer()) - return 0; - int s = 0; - // go up until first non-0 text is hit - // (innermost text is 0 in mathed) - for (s = size() - 1; s >= 0; --s) - if (operator[](s).text()) - break; - CursorSlice const & sl = operator[](s); - LyXText & text = *sl.text(); - ParagraphList::iterator pit = text.getPar(sl.par()); - LyXFont font = pit->getFont( - bv().buffer()->params(), sl.pos(), outerFont(pit, text.paragraphs())); - return font.language()->encoding(); -} - - void LCursor::undispatched() { disp_.dispatched(false); diff --git a/src/cursor.h b/src/cursor.h index b436c58414..6654f1660b 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -18,15 +18,16 @@ #include #include -class BufferView; +class UpdatableInset; +class DispatchResult; class FuncStatus; class FuncRequest; +class InsetTabular; // these should go class MathHullInset; class MathUnknownInset; class MathGridInset; -class Encoding; /// The cursor class describes the position of a cursor within a document. @@ -35,18 +36,18 @@ class Encoding; // (or maybe private inheritance) at some point of time. class LCursor : public DocumentIterator { public: + /// create the cursor of a BufferView explicit LCursor(BufferView & bv); - /// dispatch from innermost inset upwards DispatchResult dispatch(FuncRequest const & cmd); /// are we willing to handle this event? bool getStatus(FuncRequest const & cmd, FuncStatus & flag); /// add a new cursor slice - void push(InsetBase & inset); + void push(InsetBase * inset); /// add a new cursor slice, place cursor on left end - void pushLeft(InsetBase & inset); + void pushLeft(InsetBase * inset); /// pop one level off the cursor void pop(); /// pop one slice off the cursor stack and go left @@ -177,10 +178,7 @@ public: /// output friend std::ostream & operator<<(std::ostream & os, LCursor const & cur); - public: - /// - BufferView * bv_; //private: /// the anchor position DocumentIterator anchor_; @@ -318,8 +316,6 @@ public: int macroNamePos(); /// can we enter the inset? bool openable(MathAtom const &) const; - /// - Encoding const * getEncoding() const; }; #endif // LYXCURSOR_H diff --git a/src/cursor_slice.C b/src/cursor_slice.C index 7528be9d43..746ab78224 100644 --- a/src/cursor_slice.C +++ b/src/cursor_slice.C @@ -34,8 +34,8 @@ CursorSlice::CursorSlice() {} -CursorSlice::CursorSlice(InsetBase & p) - : inset_(&p), idx_(0), par_(0), pos_(0), boundary_(false) +CursorSlice::CursorSlice(InsetBase * p) + : inset_(p), idx_(0), par_(0), pos_(0), boundary_(false) { ///BOOST_ASSERT(inset_); } @@ -100,8 +100,7 @@ CursorSlice::pos_type & CursorSlice::pos() CursorSlice::pos_type CursorSlice::lastpos() const { - BOOST_ASSERT(inset_); - return inset_->asMathInset() ? cell().size() : paragraph().size(); + return (inset_ && inset_->asMathInset()) ? cell().size() : paragraph().size(); } @@ -133,15 +132,13 @@ CursorSlice::col_type CursorSlice::col() const MathInset * CursorSlice::asMathInset() const { - BOOST_ASSERT(inset_); - return inset_->asMathInset(); + return inset_ ? inset_->asMathInset() : 0; } UpdatableInset * CursorSlice::asUpdatableInset() const { - BOOST_ASSERT(inset_); - return inset_->asUpdatableInset(); + return inset_ ? inset_->asUpdatableInset() : 0; } @@ -154,8 +151,7 @@ MathArray & CursorSlice::cell() const LyXText * CursorSlice::text() const { - BOOST_ASSERT(inset_); - return inset_->getText(idx_); + return inset_ ? inset_->getText(idx_) : 0; } @@ -216,7 +212,7 @@ bool operator>(CursorSlice const & p, CursorSlice const & q) std::ostream & operator<<(std::ostream & os, CursorSlice const & item) { - return os + os << "inset: " << item.inset_ // << " text: " << item.text() << " idx: " << item.idx_ @@ -225,4 +221,5 @@ std::ostream & operator<<(std::ostream & os, CursorSlice const & item) // << " x: " << item.inset_->x() // << " y: " << item.inset_->y() ; + return os; } diff --git a/src/cursor_slice.h b/src/cursor_slice.h index d3a24aef6c..33770a5421 100644 --- a/src/cursor_slice.h +++ b/src/cursor_slice.h @@ -54,10 +54,10 @@ public: /// CursorSlice(); /// - explicit CursorSlice(InsetBase &); + explicit CursorSlice(InsetBase *); /// the current inset - InsetBase & inset() const { return *inset_; } + InsetBase * inset() const { return inset_; } /// return the cell this cursor is in idx_type idx() const; /// return the cell this cursor is in diff --git a/src/dociterator.C b/src/dociterator.C index b8baa1a28e..1293fb3d02 100644 --- a/src/dociterator.C +++ b/src/dociterator.C @@ -1,6 +1,7 @@ #include "dociterator.h" +#include "BufferView.h" #include "debug.h" #include "lyxtext.h" #include "lyxrow.h" @@ -12,6 +13,17 @@ #include + +DocumentIterator::DocumentIterator() + : bv_(0) +{} + + +DocumentIterator::DocumentIterator(BufferView & bv) + : std::vector(1), bv_(&bv) +{} + + InsetBase * DocumentIterator::nextInset() { if (pos() == lastpos()) @@ -72,21 +84,21 @@ MathAtom & DocumentIterator::nextAtom() LyXText * DocumentIterator::text() const { - return top().text(); + return size() > 1 ? top().text() : bv().text(); } Paragraph & DocumentIterator::paragraph() { BOOST_ASSERT(inTexted()); - return top().paragraph(); + return size() > 1 ? top().paragraph() : *bv().text()->getPar(par()); } Paragraph const & DocumentIterator::paragraph() const { BOOST_ASSERT(inTexted()); - return top().paragraph(); + return size() > 1 ? top().paragraph() : *bv().text()->getPar(par()); } @@ -128,84 +140,100 @@ DocumentIterator::row_type DocumentIterator::lastcrow() const DocumentIterator::idx_type DocumentIterator::lastidx() const { - return top().lastidx(); + return size() > 1 ? top().lastidx() : 0; } size_t DocumentIterator::nargs() const { // assume 1x1 grid for main text - return top().nargs(); + return size() > 1 ? top().nargs() : 1; } size_t DocumentIterator::ncols() const { // assume 1x1 grid for main text - return top().ncols(); + return size() > 1 ? top().ncols() : 1; } size_t DocumentIterator::nrows() const { // assume 1x1 grid for main text - return top().nrows(); + return size() > 1 ? top().nrows() : 1; } DocumentIterator::row_type DocumentIterator::row() const { - return top().row(); + return size() > 1 ? top().row() : 0; } DocumentIterator::col_type DocumentIterator::col() const { - return top().col(); + return size() > 1 ? top().col() : 0; } MathArray const & DocumentIterator::cell() const { - BOOST_ASSERT(inMathed()); + BOOST_ASSERT(size() > 1); return top().cell(); } MathArray & DocumentIterator::cell() { - BOOST_ASSERT(inMathed()); + BOOST_ASSERT(size() > 1); return top().cell(); } bool DocumentIterator::inMathed() const { - return !empty() && inset().inMathed(); + return size() > 1 && inset()->inMathed(); } bool DocumentIterator::inTexted() const { - return !empty() && !inset().inMathed(); + return !inMathed(); } LyXText * DocumentIterator::innerText() const { BOOST_ASSERT(!empty()); - // go up until first non-0 text is hit - // (innermost text is 0 in mathed) - for (int i = size() - 1; i >= 0; --i) - if (operator[](i).text()) - return operator[](i).text(); - return 0; + if (size() > 1) { + // go up until first non-0 text is hit + // (innermost text is 0 in mathed) + for (int i = size() - 1; i >= 1; --i) + if (operator[](i).text()) + return operator[](i).text(); + } + return bv().text(); +} + + +CursorSlice const & DocumentIterator::innerTextSlice() const +{ + BOOST_ASSERT(!empty()); + if (size() > 1) { + // go up until first non-0 text is hit + // (innermost text is 0 in mathed) + for (int i = size() - 1; i >= 1; --i) + if (operator[](i).text()) + return operator[](i); + } + return operator[](0); } InsetBase * DocumentIterator::innerInsetOfType(int code) const { - for (int i = size() - 1; i >= 0; --i) + for (int i = size() - 1; i >= 1; --i) if (operator[](i).inset_->lyxCode() == code) return operator[](i).inset_; return 0; @@ -231,7 +259,7 @@ void DocumentIterator::forwardPos() if (n && n->isActive()) { //lyxerr << "... descend" << std::endl; - push_back(CursorSlice(*n)); + push_back(CursorSlice(n)); return; } @@ -259,7 +287,7 @@ void DocumentIterator::forwardPos() ++top.idx(); top.par() = 0; top.pos() = 0; - if (top.inset().validCell(top.idx())) { + if (top.inset() && top.inset()->validCell(top.idx())) { //lyxerr << " ... ok" << std::endl; return; } @@ -295,7 +323,7 @@ void DocumentIterator::forwardPar() if (n && n->isActive()) { lyxerr << "... descend" << std::endl; - push_back(CursorSlice(*n)); + push_back(CursorSlice(n)); return; } @@ -322,7 +350,7 @@ void DocumentIterator::forwardPar() ++top.idx(); top.par() = 0; top.pos() = 0; - if (top.inset().validCell(top.idx())) { + if (top.inset() && top.inset()->validCell(top.idx())) { lyxerr << " ... ok" << std::endl; return; } @@ -336,10 +364,22 @@ void DocumentIterator::forwardPar() } -DocumentIterator insetBegin(InsetBase & inset) +DocumentIterator bufferBegin(BufferView & bv) { - DocumentIterator it; - it.push_back(CursorSlice(inset)); + return DocumentIterator(bv); +} + + +DocumentIterator bufferEnd() +{ + return DocumentIterator(); +} + + +DocumentIterator insetBegin(BufferView & bv, InsetBase * p) +{ + DocumentIterator it(bv); + it.back() = CursorSlice(p); return it; } @@ -352,6 +392,7 @@ DocumentIterator insetEnd() std::ostream & operator<<(std::ostream & os, DocumentIterator const & dit) { + os << "bv: " << &dit.bv() << "\n"; for (size_t i = 0, n = dit.size(); i != n; ++i) os << " " << dit.operator[](i) << "\n"; return os; @@ -370,11 +411,13 @@ StableDocumentIterator::StableDocumentIterator(const DocumentIterator & dit) DocumentIterator -StableDocumentIterator::asDocumentIterator(InsetBase * inset) const +StableDocumentIterator::asDocumentIterator(BufferView & bv) const { // this function re-creates the cache of inset pointers //lyxerr << "converting:\n" << *this << std::endl; - DocumentIterator dit; + DocumentIterator dit(bv); + dit.clear(); + InsetBase * inset = 0; for (size_t i = 0, n = data_.size(); i != n; ++i) { dit.push_back(data_[i]); dit.back().inset_ = inset; diff --git a/src/dociterator.h b/src/dociterator.h index baff5c690e..22e49c8b45 100644 --- a/src/dociterator.h +++ b/src/dociterator.h @@ -17,8 +17,9 @@ #include #include -class LyXText; +class BufferView; class MathAtom; +class LyXText; class Paragraph; class Row; @@ -49,6 +50,13 @@ public: typedef CursorSlice::col_type col_type; public: + /// + DocumentIterator(); + /// + explicit DocumentIterator(BufferView & bv); + /// + BufferView & bv() const { return *bv_; } + // // access to slice at tip // @@ -59,7 +67,7 @@ public: /// how many nested insets do we have? size_t depth() const { return size(); } /// the containing inset - InsetBase & inset() const { return back().inset(); } + InsetBase * inset() const { return back().inset(); } /// return the cell of the inset this cursor is in idx_type idx() const { return back().idx(); } /// return the cell of the inset this cursor is in @@ -143,6 +151,8 @@ public: /// LyXText * text() const; /// + CursorSlice const & innerTextSlice() const; + /// InsetBase * innerInsetOfType(int code) const; /// LyXText * innerText() const; @@ -161,11 +171,19 @@ public: /// output friend std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur); + +private: + /// + BufferView * bv_; }; /// -DocumentIterator insetBegin(InsetBase & inset); +DocumentIterator bufferBegin(BufferView & bv); +/// +DocumentIterator bufferEnd(); +/// +DocumentIterator insetBegin(BufferView & bv, InsetBase * inset); /// DocumentIterator insetEnd(); @@ -181,7 +199,7 @@ public: /// non-explicit intended StableDocumentIterator(const DocumentIterator & it); /// - DocumentIterator asDocumentIterator(InsetBase * start) const; + DocumentIterator asDocumentIterator(BufferView & bv) const; /// size_t size() const { return data_.size(); } /// diff --git a/src/factory.C b/src/factory.C index 727939de48..11340acb54 100644 --- a/src/factory.C +++ b/src/factory.C @@ -182,7 +182,8 @@ InsetBase * createInset(BufferView * bv, FuncRequest const & cmd) return 0; case LFUN_INSET_CAPTION: { - UpdatableInset * up = bv->cursor().inset().asUpdatableInset(); + UpdatableInset * up = bv->cursor().inset() + ? bv->cursor().inset()->asUpdatableInset() : 0; if (!up) { auto_ptr inset(new InsetCaption(params)); inset->setOwner(up); diff --git a/src/frontends/screen.C b/src/frontends/screen.C index 93f30487b8..2a2309cf16 100644 --- a/src/frontends/screen.C +++ b/src/frontends/screen.C @@ -259,7 +259,7 @@ void LyXScreen::redraw(BufferView & bv) // maybe we have to clear the screen at the bottom int const y2 = workarea().workHeight(); - if (y < y2 && bv.text()->isMainText()) { + if (y < y2 && !bv.text()->isInInset()) { workarea().getPainter().fillRectangle(0, y, workarea().workWidth(), y2 - y, LColor::bottomarea); diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index 75c348571b..9ae7b1541a 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -298,7 +298,7 @@ string const InsetCollapsable::getNewLabel(string const & l) const void InsetCollapsable::edit(LCursor & cur, bool left) { //lyxerr << "InsetCollapsable: edit left/right" << endl; - cur.push(*this); + cur.push(this); inset.edit(cur, left); open(); } @@ -306,7 +306,7 @@ void InsetCollapsable::edit(LCursor & cur, bool left) InsetBase * InsetCollapsable::editXY(LCursor & cur, int x, int y) { - cur.push(*this); + cur.push(this); //lyxerr << "InsetCollapsable: edit xy" << endl; if (status_ == Collapsed) { setStatus(Open); diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index ec2d7734af..e12e7dd2e8 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -396,7 +396,7 @@ void InsetTabular::edit(LCursor & cur, bool left) cur.selection() = false; resetPos(cur); cur.bv().fitCursor(); - cur.push(*this); + cur.push(this); cur.idx() = cell; } @@ -405,7 +405,7 @@ InsetBase * InsetTabular::editXY(LCursor & cur, int x, int y) { //lyxerr << "InsetTabular::editXY: " << this << endl; cur.selection() = false; - cur.push(*this); + cur.push(this); return setPos(cur, x, y); //int xx = cursorx_ - xo_ + tabular.getBeginningOfTextInCell(actcell); } diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 1a24f6883c..faf3173e58 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -70,18 +70,18 @@ using std::vector; InsetText::InsetText(BufferParams const & bp) : autoBreakRows_(false), drawFrame_(NEVER), - frame_color_(LColor::insetframe), text_(0) + frame_color_(LColor::insetframe), text_(0, true) { paragraphs().push_back(Paragraph()); - paragraphs().back().layout(bp.getLyXTextClass().defaultLayout()); + paragraphs().begin()->layout(bp.getLyXTextClass().defaultLayout()); if (bp.tracking_changes) - paragraphs().back().trackChanges(); + paragraphs().begin()->trackChanges(); init(); } InsetText::InsetText(InsetText const & in) - : UpdatableInset(in), text_(in.text_.bv_owner) + : UpdatableInset(in), text_(in.text_.bv_owner, true) { // this is ugly... operator=(in); @@ -94,7 +94,7 @@ void InsetText::operator=(InsetText const & in) autoBreakRows_ = in.autoBreakRows_; drawFrame_ = in.drawFrame_; frame_color_ = in.frame_color_; - text_ = LyXText(in.text_.bv_owner); + text_ = LyXText(in.text_.bv_owner, true); text_.paragraphs() = in.text_.paragraphs(); init(); } diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 6d86ec4da2..63cda7cf37 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -174,7 +174,7 @@ void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state) return; } - Encoding const * encoding = view()->cursor().getEncoding(); + Encoding const * encoding = view()->getEncoding(); encoded_last_key = keysym->getISOEncoded(encoding ? encoding->Name() : ""); @@ -309,6 +309,8 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const } } + UpdatableInset * tli = cur.inset() ? cur.inset()->asUpdatableInset() : 0; + // I would really like to avoid having this switch and rather try to // encode this in the function itself. bool disable = false; @@ -350,7 +352,8 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_LAYOUT: case LFUN_LAYOUT_PARAGRAPH: - disable = cur.inset().forceDefaultParagraphs(&cur.inset()); + disable = cur.inset() + && cur.inset()->forceDefaultParagraphs(cur.inset()); break; case LFUN_INSET_OPTARG: @@ -380,7 +383,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const } else { disable = true; - char const align = mathcursor::halign(); + char align = mathcursor::halign(); if (align == '\0') { disable = true; break; @@ -399,7 +402,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } - if (!cur.empty() && cur.inset().asUpdatableInset()) { + if (tli) { FuncStatus ret; //ret.disabled(true); InsetTabular * tab = static_cast @@ -452,7 +455,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_INSET_SETTINGS: { disable = true; - UpdatableInset * inset = cur.inset().asUpdatableInset(); + if (!cur.inset()) + break; + UpdatableInset * inset = cur.inset()->asUpdatableInset(); if (!inset) break; @@ -510,21 +515,26 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_DIALOG_SHOW: { string const name = cmd.getArg(0); - if (!buf) + if (!buf) { disable = !(name == "aboutlyx" || name == "file" || name == "forks" || name == "preferences" || name == "texinfo"); - else if (name == "print") + break; + } + + if (name == "print") { disable = !Exporter::IsExportable(*buf, "dvi") || lyxrc.print_command == "none"; - else if (name == "character") - disable = cur.inset().lyxCode() == InsetOld::ERT_CODE; - else if (name == "vclog") + } else if (name == "character") { + InsetBase * inset = cur.inset(); + disable = inset && inset->lyxCode() == InsetOld::ERT_CODE; + } else if (name == "vclog") { disable = !buf->lyxvc().inUse(); - else if (name == "latexlog") + } else if (name == "latexlog") { disable = !IsFileReadable(buf->getLogName().second); + } break; } @@ -678,9 +688,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const default: break; } - - if (code != InsetOld::NO_CODE - && (cur.empty() || !cur.inset().insetAllowed(code))) + if (code != InsetOld::NO_CODE && tli && !tli->insetAllowed(code)) disable = true; if (disable) @@ -1037,7 +1045,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) // --- buffers ---------------------------------------- case LFUN_SWITCHBUFFER: - view()->setBuffer(bufferlist.getBuffer(argument)); + view()->buffer(bufferlist.getBuffer(argument)); break; case LFUN_FILE_NEW: @@ -1077,14 +1085,14 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) if (prefixIs(file_name, getTmpDir())) { // Needed by inverse dvi search. If it is a file // in tmpdir, call the apropriated function - view()->setBuffer(bufferlist.getBufferFromTmp(file_name)); + view()->buffer(bufferlist.getBufferFromTmp(file_name)); } else { // Must replace extension of the file to be .lyx // and get full path string const s = ChangeExtension(file_name, ".lyx"); // Either change buffer or load the file if (bufferlist.exists(s)) { - view()->setBuffer(bufferlist.getBuffer(s)); + view()->buffer(bufferlist.getBuffer(s)); } else { view()->loadLyXFile(s); } @@ -1259,7 +1267,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) view()->savePosition(0); string const parentfilename = owner->buffer()->fileName(); if (bufferlist.exists(filename)) - view()->setBuffer(bufferlist.getBuffer(filename)); + view()->buffer(bufferlist.getBuffer(filename)); else view()->loadLyXFile(filename); // Set the parent name of the child document. @@ -1673,7 +1681,7 @@ void LyXFunc::closeBuffer() // since there's no current buffer owner->getDialogs().hideBufferDependent(); } else { - view()->setBuffer(bufferlist.first()); + view()->buffer(bufferlist.first()); } } } diff --git a/src/lyxtext.h b/src/lyxtext.h index 3cdd4aaa64..5ab7cd9e0b 100644 --- a/src/lyxtext.h +++ b/src/lyxtext.h @@ -55,7 +55,7 @@ public: typedef lyx::paroffset_type par_type; /// constructor - explicit LyXText(BufferView *); + LyXText(BufferView *, bool ininset); /// void init(BufferView *); @@ -328,8 +328,8 @@ public: /// access to our paragraphs ParagraphList & paragraphs() const; - /// return true if this is the main text - bool isMainText() const; + /// return true if this is owned by an inset. + bool isInInset() const; /// return first row of text RowList::iterator firstRow() const; @@ -401,6 +401,8 @@ public: /// mutable Bidi bidi; /// + bool in_inset_; + /// ParagraphList paragraphs_; /// absolute document pixel coordinates of this LyXText diff --git a/src/mathed/math_hullinset.C b/src/mathed/math_hullinset.C index 64cb7db090..3f46a091c1 100644 --- a/src/mathed/math_hullinset.C +++ b/src/mathed/math_hullinset.C @@ -29,7 +29,6 @@ #include "lyxrc.h" #include "outputparams.h" #include "textpainter.h" -#include "undo.h" #include "frontends/Alert.h" @@ -804,7 +803,7 @@ void MathHullInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) case LFUN_MATH_NUMBER: //lyxerr << "toggling all numbers" << endl; if (display()) { - recordUndo(cur); + ////recordUndo(cur, Undo::INSERT); bool old = numberedType(); if (type_ == "multline") numbered(nrows() - 1, !old); @@ -818,7 +817,7 @@ void MathHullInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) case LFUN_MATH_NONUMBER: if (display()) { row_type r = (type_ == "multline") ? nrows() - 1 : cur.row(); - recordUndo(cur); + ////recordUndo(cur, Undo::INSERT); bool old = numbered(r); cur.message(old ? _("No number") : _("Number")); numbered(r, !old); @@ -955,13 +954,14 @@ void MathHullInset::mutateToText() } -void MathHullInset::handleFont(LCursor & cur, string const & arg, - string const & font) +void MathHullInset::handleFont + (LCursor & cur, string const & arg, string const & font) { // this whole function is a hack and won't work for incremental font // changes... - recordUndo(cur); - if (cur.inset().asMathInset()->name() == font) + //recordUndo(cur, Undo::ATOMIC); + + if (cur.inset()->asMathInset()->name() == font) cur.handleFont(font); else { cur.handleNest(createMathInset(font)); @@ -972,7 +972,7 @@ void MathHullInset::handleFont(LCursor & cur, string const & arg, void MathHullInset::handleFont2(LCursor & cur, string const & arg) { - recordUndo(cur); + //recordUndo(cur, Undo::ATOMIC); LyXFont font; bool b; bv_funcs::string2font(arg, font, b); diff --git a/src/mathed/math_mboxinset.C b/src/mathed/math_mboxinset.C index 6228f09fdb..0b7fa15485 100644 --- a/src/mathed/math_mboxinset.C +++ b/src/mathed/math_mboxinset.C @@ -26,7 +26,7 @@ using std::endl; MathMBoxInset::MathMBoxInset(BufferView & bv) - : text_(&bv), bv_(&bv) + : text_(&bv, true), bv_(&bv) { text_.paragraphs().push_back(Paragraph()); text_.paragraphs().back(). diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 6667318101..2c58c03fb3 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -87,7 +87,7 @@ MathArray const & MathNestInset::cell(idx_type i) const void MathNestInset::getCursorPos(CursorSlice const & cur, int & x, int & y) const { - BOOST_ASSERT(ptr_cmp(&cur.inset(), this)); + BOOST_ASSERT(ptr_cmp(cur.inset(), this)); MathArray const & ar = cur.cell(); x = ar.xo() + ar.pos2x(cur.pos()); y = ar.yo(); @@ -114,7 +114,7 @@ void MathNestInset::metrics(MetricsInfo const & mi) const bool MathNestInset::idxNext(LCursor & cur) const { - BOOST_ASSERT(ptr_cmp(&cur.inset(), this)); + BOOST_ASSERT(ptr_cmp(cur.inset(), this)); if (cur.idx() == cur.lastidx()) return false; ++cur.idx(); @@ -131,7 +131,7 @@ bool MathNestInset::idxRight(LCursor & cur) const bool MathNestInset::idxPrev(LCursor & cur) const { - BOOST_ASSERT(ptr_cmp(&cur.inset(), this)); + BOOST_ASSERT(ptr_cmp(cur.inset(), this)); if (cur.idx() == 0) return false; --cur.idx(); @@ -148,7 +148,7 @@ bool MathNestInset::idxLeft(LCursor & cur) const bool MathNestInset::idxFirst(LCursor & cur) const { - BOOST_ASSERT(ptr_cmp(&cur.inset(), this)); + BOOST_ASSERT(ptr_cmp(cur.inset(), this)); if (nargs() == 0) return false; cur.idx() = 0; @@ -159,7 +159,7 @@ bool MathNestInset::idxFirst(LCursor & cur) const bool MathNestInset::idxLast(LCursor & cur) const { - BOOST_ASSERT(ptr_cmp(&cur.inset(), this)); + BOOST_ASSERT(ptr_cmp(cur.inset(), this)); if (nargs() == 0) return false; cur.idx() = cur.lastidx(); @@ -197,7 +197,7 @@ void MathNestInset::drawSelection(PainterInfo & pi, int, int) const LCursor & cur = pi.base.bv->cursor(); if (!cur.selection()) return; - if (!ptr_cmp(&cur.inset(), this)) + if (!ptr_cmp(cur.inset(), this)) return; CursorSlice & s1 = cur.selBegin(); CursorSlice & s2 = cur.selEnd(); @@ -309,7 +309,7 @@ void MathNestInset::handleFont // changes... recordUndo(cur, Undo::ATOMIC); - if (cur.inset().asMathInset()->name() == font) + if (cur.inset()->asMathInset()->name() == font) cur.handleFont(font); else { cur.handleNest(createMathInset(font)); @@ -411,8 +411,8 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) if (cur.inMacroMode()) cur.macroModeClose(); else if (cur.pos() != cur.lastpos() && cur.openable(cur.nextAtom())) { - cur.pushLeft(*cur.nextAtom().nucleus()); - cur.inset().idxFirst(cur); + cur.pushLeft(cur.nextAtom().nucleus()); + cur.inset()->idxFirst(cur); } else if (cur.posRight() || idxRight(cur) || cur.popRight() || cur.selection()) ; @@ -430,8 +430,8 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) cur.macroModeClose(); else if (cur.pos() != 0 && cur.openable(cur.prevAtom())) { cur.posLeft(); - cur.push(*cur.nextAtom().nucleus()); - cur.inset().idxLast(cur); + cur.push(cur.nextAtom().nucleus()); + cur.inset()->idxLast(cur); } else if (cur.posLeft() || idxLeft(cur) || cur.popLeft() || cur.selection()) ; @@ -522,11 +522,11 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) break; case LFUN_CELL_FORWARD: - cur.inset().idxNext(cur); + cur.inset()->idxNext(cur); break; case LFUN_CELL_BACKWARD: - cur.inset().idxPrev(cur); + cur.inset()->idxPrev(cur); break; case LFUN_DELETE_WORD_BACKWARD: @@ -682,7 +682,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) cur.selClearOrDel(); cur.plainInsert(MathAtom(new MathMBoxInset(cur.bv()))); cur.posLeft(); - cur.pushLeft(*cur.nextInset()); + cur.pushLeft(cur.nextInset()); #else if (currentMode() == InsetBase::TEXT_MODE) cur.niceInsert(MathAtom(new MathHullInset("simple"))); @@ -821,7 +821,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) void MathNestInset::edit(LCursor & cur, bool left) { - cur.push(*this); + cur.push(this); cur.idx() = left ? 0 : cur.lastidx(); cur.pos() = left ? 0 : cur.lastpos(); cur.resetAnchor(); @@ -840,7 +840,7 @@ InsetBase * MathNestInset::editXY(LCursor & cur, int x, int y) } } MathArray & ar = cell(idx_min); - cur.push(*this); + cur.push(this); cur.idx() = idx_min; cur.pos() = ar.x2pos(x - ar.xo()); lyxerr << "found cell : " << idx_min << " pos: " << cur.pos() << endl; @@ -1083,20 +1083,20 @@ bool MathNestInset::script(LCursor & cur, bool up) } else if (cur.pos() != 0 && cur.prevAtom()->asScriptInset()) { --cur.pos(); cur.nextAtom().nucleus()->asScriptInset()->ensure(up); - cur.push(*cur.nextInset()); + cur.push(cur.nextInset()); cur.idx() = up; cur.pos() = cur.lastpos(); } else if (cur.pos() != 0) { --cur.pos(); cur.cell()[cur.pos()] = MathAtom(new MathScriptInset(cur.nextAtom(), up)); - cur.push(*cur.nextInset()); + cur.push(cur.nextInset()); cur.idx() = up; cur.pos() = 0; } else { cur.plainInsert(MathAtom(new MathScriptInset(up))); --cur.pos(); cur.nextAtom().nucleus()->asScriptInset()->ensure(up); - cur.push(*cur.nextInset()); + cur.push(cur.nextInset()); cur.idx() = up; cur.pos() = 0; } diff --git a/src/output_latex.C b/src/output_latex.C index f775d4af12..483fe10bce 100644 --- a/src/output_latex.C +++ b/src/output_latex.C @@ -332,7 +332,7 @@ TeXOnePar(Buffer const & buf, // Is this really needed ? (Dekel) // We do not need to use to change the font for the last paragraph // or for a command. - LyXFont const outerfont = outerFont(pit, paragraphs); + LyXFont const outerfont(outerFont(pit, paragraphs)); LyXFont const font = (pit->empty() diff --git a/src/paragraph_funcs.C b/src/paragraph_funcs.C index a88b014f65..07c9703dc1 100644 --- a/src/paragraph_funcs.C +++ b/src/paragraph_funcs.C @@ -623,3 +623,4 @@ void getParsInRange(ParagraphList & pl, for (end = beg ; end != endpar && end->y <= yend; ++end) ; } + diff --git a/src/text.C b/src/text.C index 03033d16d3..8cef593271 100644 --- a/src/text.C +++ b/src/text.C @@ -1740,17 +1740,25 @@ bool LyXText::read(Buffer const & buf, LyXLex & lex) if (token.empty()) continue; - if (token == "\\end_inset") { - the_end_read = true; - break; - } + if (in_inset_) { + + if (token == "\\end_inset") { + the_end_read = true; + break; + } + + if (token == "\\end_document") { + lex.printError("\\end_document read in inset! Error in document!"); + return false; + } + + } else { + + if (token == "\\end_document") { + the_end_read = true; + continue; + } - if (token == "\\end_document") { -#warning Look here! -#if 0 - lex.printError("\\end_document read in inset! Error in document!"); -#endif - return false; } // FIXME: ugly. @@ -1763,7 +1771,8 @@ bool LyXText::read(Buffer const & buf, LyXLex & lex) par.params().depth(depth); if (buf.params().tracking_changes) par.trackChanges(); - par.setFont(0, LyXFont(LyXFont::ALL_INHERIT, buf.params().language)); + LyXFont f(LyXFont::ALL_INHERIT, buf.params().language); + par.setFont(0, f); // insert after if (pit != paragraphs().end()) diff --git a/src/text2.C b/src/text2.C index ac234dc244..9515b42662 100644 --- a/src/text2.C +++ b/src/text2.C @@ -71,10 +71,10 @@ using std::ostringstream; using std::string; -LyXText::LyXText(BufferView * bv) +LyXText::LyXText(BufferView * bv, bool in_inset) : width_(0), maxwidth_(bv ? bv->workWidth() : 100), height_(0), background_color_(LColor::background), - bv_owner(bv), xo_(0), yo_(0) + bv_owner(bv), in_inset_(in_inset), xo_(0), yo_(0) {} @@ -100,12 +100,6 @@ void LyXText::init(BufferView * bv) } -bool LyXText::isMainText() const -{ - return &bv()->buffer()->text() == this; -} - - // Gets the fully instantiated font at a given position in a paragraph // Basically the same routine as Paragraph::getFont() in paragraph.C. // The difference is that this one is used for displaying, and thus we @@ -123,7 +117,7 @@ LyXFont LyXText::getFont(ParagraphList::iterator pit, pos_type pos) const // We specialize the 95% common case: if (!pit->getDepth()) { LyXFont f = pit->getFontSettings(params, pos); - if (!isMainText()) + if (in_inset_) f.realize(font_); if (layout->labeltype == LABEL_MANUAL && pos < body_pos) return f.realize(layout->reslabelfont); @@ -141,7 +135,7 @@ LyXFont LyXText::getFont(ParagraphList::iterator pit, pos_type pos) const LyXFont font = pit->getFontSettings(params, pos); font.realize(layoutfont); - if (!isMainText()) + if (in_inset_) font.realize(font_); // Realize with the fonts of lesser depth. @@ -1604,6 +1598,12 @@ void LyXText::recUndo(par_type par) const } +bool LyXText::isInInset() const +{ + return in_inset_; +} + + bool LyXText::toggleInset(LCursor & cur) { InsetBase * inset = cur.nextInset(); diff --git a/src/text3.C b/src/text3.C index e584b75407..ba25ab6020 100644 --- a/src/text3.C +++ b/src/text3.C @@ -131,8 +131,7 @@ namespace { lyxerr << "selection is: '" << sel << "'" << endl; if (sel.empty()) { - cur.insert(new MathHullInset); - cur.dispatch(FuncRequest(LFUN_RIGHT)); + cur.insert(new MathHullInset); // activates inset cur.dispatch(FuncRequest(LFUN_MATH_MUTATE, "simple")); // don't do that also for LFUN_MATH_MODE unless you want end up with // always changing to mathrm when opening an inlined inset @@ -144,16 +143,14 @@ namespace { // create a macro if we see "\\newcommand" somewhere, and an ordinary // formula otherwise text->cutSelection(cur, true, true); - if (sel.find("\\newcommand") == string::npos - && sel.find("\\def") == string::npos) + if (sel.find("\\newcommand") == string::npos && + sel.find("\\def") == string::npos) { cur.insert(new MathHullInset); - cur.dispatch(FuncRequest(LFUN_RIGHT)); cur.dispatch(FuncRequest(LFUN_MATH_MUTATE, "simple")); cur.dispatch(FuncRequest(LFUN_INSERT_MATH, sel)); } else { cur.insert(new InsetFormulaMacro(sel)); - cur.dispatch(FuncRequest(LFUN_RIGHT)); } } cur.message(N_("Math editor mode")); @@ -777,8 +774,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd) } case LFUN_INSET_SETTINGS: - if (cur.inset().asUpdatableInset()) - cur.inset().asUpdatableInset()->showInsetDialog(bv); + if (cur.inset() && cur.inset()->asUpdatableInset()) + cur.inset()->asUpdatableInset()->showInsetDialog(bv); break; case LFUN_INSET_TOGGLE: @@ -863,6 +860,28 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd) cur.message(_("Copy")); break; + case LFUN_BEGINNINGBUFSEL: + if (in_inset_) { + cur.undispatched(); + } else { + if (!cur.selection()) + cur.resetAnchor(); + cursorTop(cur); + finishChange(cur, true); + } + break; + + case LFUN_ENDBUFSEL: + if (in_inset_) { + cur.undispatched(); + } else { + if (!cur.selection()) + cur.resetAnchor(); + cursorBottom(cur); + finishChange(cur, true); + } + break; + case LFUN_GETXY: cur.message(tostr(cursorX(cur.top())) + ' ' + tostr(cursorY(cur.top()))); @@ -1074,7 +1093,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd) // This is to allow jumping over large insets // FIXME: shouldn't be top-text-specific - if (isMainText() && cur.top() == old) { + if (!in_inset_ && cur.top() == old) { if (cmd.y - bv->top_y() >= bv->workHeight()) cursorDown(cur); else if (cmd.y - bv->top_y() < 0) @@ -1442,8 +1461,9 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd) params2string(cur.paragraph(), data); // Will the paragraph accept changes from the dialog? - InsetBase & inset = cur.inset(); - bool const accept = !inset.forceDefaultParagraphs(&inset); + InsetBase * const inset = cur.inset(); + bool const accept = + !(inset && inset->forceDefaultParagraphs(inset)); data = "update " + tostr(accept) + '\n' + data; bv->owner()->getDialogs().update("paragraph", data); diff --git a/src/undo.C b/src/undo.C index ab798f3dfe..9d028f03c7 100644 --- a/src/undo.C +++ b/src/undo.C @@ -107,7 +107,7 @@ void performUndoOrRedo(BufferView & bv, Undo const & undo) { LCursor & cur = bv.cursor(); lyxerr << "undo, performing: " << undo << std::endl; - cur.setCursor(undo.cursor.asDocumentIterator(&bv.buffer()->inset()), false); + cur.setCursor(undo.cursor.asDocumentIterator(bv), false); if (cur.inMathed()) { // We stored the full cell here as there is not much to be @@ -155,8 +155,7 @@ bool textUndoOrRedo(BufferView & bv, // this implements redo if (!undo_frozen) { otherstack.push(undo); - DocumentIterator dit = - undo.cursor.asDocumentIterator(&bv.buffer()->inset()); + DocumentIterator dit = undo.cursor.asDocumentIterator(bv); if (dit.inMathed()) { // not much to be done } else {