diff --git a/src/Bidi.C b/src/Bidi.C index ce9b4651d5..e469270558 100644 --- a/src/Bidi.C +++ b/src/Bidi.C @@ -61,8 +61,7 @@ void Bidi::computeTables(Paragraph const & par, } InsetOld * inset = par.inInset(); - if (inset && inset->owner() && - inset->owner()->lyxCode() == InsetOld::ERT_CODE) { + if (inset && inset->lyxCode() == InsetOld::ERT_CODE) { start_ = -1; return; } diff --git a/src/BufferView.C b/src/BufferView.C index 53defc5c60..a0b4084495 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -20,6 +20,7 @@ #include "bufferlist.h" #include "bufferparams.h" #include "BufferView_pimpl.h" +#include "CutAndPaste.h" #include "debug.h" #include "funcrequest.h" #include "gettext.h" @@ -30,7 +31,6 @@ #include "lyxtextclass.h" #include "paragraph.h" #include "paragraph_funcs.h" -#include "PosIterator.h" #include "texrow.h" #include "undo.h" #include "WordLangTuple.h" @@ -51,6 +51,8 @@ using lyx::support::bformat; using lyx::support::MakeAbsPath; +using lyx::cap::setSelectionRange; + using std::distance; using std::find; using std::string; @@ -268,8 +270,7 @@ bool BufferView::insertLyXFile(string const & filen) text()->breakParagraph(cursor()); BOOST_ASSERT(cursor().inTexted()); - LyXText * text = cursor().text(); - bool res = buffer()->readFile(fname, text->getPar(cursor().par())); + bool res = buffer()->readFile(fname, cursor().par()); resize(); return res; } @@ -302,8 +303,7 @@ void BufferView::setCursorFromRow(int row) if (tmpid == -1) text()->setCursor(cursor(), 0, 0); else - text()->setCursor(cursor(), - text()->parOffset(buffer()->getParFromID(tmpid).pit()), + text()->setCursor(cursor(), buffer()->getParFromID(tmpid).pit(), tmppos); } @@ -316,9 +316,7 @@ void BufferView::gotoLabel(string const & label) it->getLabelList(*buffer(), labels); if (find(labels.begin(),labels.end(),label) != labels.end()) { cursor().clearSelection(); - text()->setCursor(cursor(), - distance(text()->paragraphs().begin(), it.getPar()), - it.getPos()); + text()->setCursor(cursor(), it.getPar(), it.getPos()); cursor().resetAnchor(); update(); return; @@ -376,8 +374,7 @@ void BufferView::setCursor(ParIterator const & par, lyx::pos_type pos) 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); + par.text(*buffer())->setCursor(cur, par.pit(), pos); } @@ -395,7 +392,7 @@ this is solved in putSelectionAt with: Ab. */ -void BufferView::putSelectionAt(PosIterator const & cur, +void BufferView::putSelectionAt(DocumentIterator const & cur, int length, bool backwards) { ParIterator par(cur); @@ -407,22 +404,18 @@ void BufferView::putSelectionAt(PosIterator const & cur, // hack for the chicken and egg problem if (par.inset()) - top_y(par.outerPar()->y); + top_y(text->getPar(par.outerPar()).y); update(); - text->setCursor(cursor(), text->parOffset(cur.pit()), cur.pos()); + text->setCursor(cursor(), cur.par(), cur.pos()); cursor().updatePos(); if (length) { - text->setSelectionRange(cursor(), length); + setSelectionRange(cursor(), length); cursor().setSelection(); if (backwards) { -#if 0 - swap(cursor().cursor_, cursor().anchor_); -#else - DocumentIterator it = cursor(); + DocumentIterator const it = cursor(); cursor().setCursor(cursor().anchor_, false); cursor().anchor_ = it; -#endif } } diff --git a/src/BufferView.h b/src/BufferView.h index a8cae7000b..3a2a7d03c6 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -23,6 +23,7 @@ class Buffer; class Change; +class DocumentIterator; class Encoding; class ErrorList; class FuncRequest; @@ -35,7 +36,6 @@ class LyXScreen; class LyXView; class Painter; class ParIterator; -class PosIterator; class TeXErrors; class UpdatableInset; @@ -173,7 +173,8 @@ public: /// void setCursor(ParIterator const & par, lyx::pos_type pos); /// - void putSelectionAt(PosIterator const & cur, int length, bool backwards); + void putSelectionAt(DocumentIterator const & cur, + int length, bool backwards); private: /// diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 2761da801a..cd1ae3f597 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -334,7 +334,7 @@ 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()); + 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 @@ -377,21 +377,15 @@ void BufferView::Pimpl::redoCurrentBuffer() void BufferView::Pimpl::resizeCurrentBuffer() { lyxerr[Debug::INFO] << "resizeCurrentBuffer" << endl; - owner_->busy(true); - owner_->message(_("Formatting document...")); LyXText * text = bv_->text(); - lyxerr << "### resizeCurrentBuffer: text " << text << endl; if (!text) return; - // save the cursor mangled in init - LCursor cur = bv_->cursor(); text->init(bv_); update(); - bv_->cursor() = cur; bv_->cursor().updatePos(); fitCursor(); @@ -570,8 +564,7 @@ void BufferView::Pimpl::update() // check needed to survive LyX startup if (buffer_) { // update all 'visible' paragraphs - ParagraphList::iterator beg; - ParagraphList::iterator end; + lyx::par_type beg, end; getParsInRange(buffer_->paragraphs(), top_y(), top_y() + workarea().workHeight(), beg, end); @@ -618,8 +611,8 @@ Change const BufferView::Pimpl::getCurrentChange() if (!cur.selection()) return Change(Change::UNCHANGED); - return text->getPar(cur.selBegin()) - ->lookupChangeFull(cur.selBegin().pos()); + return text->getPar(cur.selBegin().par()). + lookupChangeFull(cur.selBegin().pos()); } @@ -661,9 +654,7 @@ void BufferView::Pimpl::restorePosition(unsigned int i) if (par == buffer_->par_iterator_end()) return; - bv_->text()->setCursor( - bv_->cursor(), - bv_->text()->parOffset(par.pit()), + bv_->text()->setCursor(bv_->cursor(), par.pit(), min(par->size(), saved_positions[i].par_pos)); if (i > 0) @@ -735,7 +726,10 @@ InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code code) bool cursor_par_seen = false; LCursor & cur = bv_->cursor(); - ParagraphList::iterator pit = bv_->getLyXText()->getPar(cur.par()); +#warning FIXME +#if 0 + LyXText * = bv_->getLyXText(); + ParagraphList::iterator pit = text->getPar(cur.par()); for (; beg != end; ++beg) { if (beg.getPar() == pit) @@ -754,6 +748,7 @@ InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code code) return &(*beg); } } +#endif return 0; } @@ -847,97 +842,78 @@ void BufferView::Pimpl::trackChanges() bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) { - // - // this is only called for mouse related events (including - // LFUN_FILE_OPEN generated by drag-and-drop) - // + // this is only called for mouse related events including + // LFUN_FILE_OPEN generated by drag-and-drop. FuncRequest cmd = cmd0; + + // handle drag&deop + if (cmd.action == LFUN_FILE_OPEN) { + owner_->dispatch(cmd); + return true; + } + 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) { -#if 0 - case LFUN_MOUSE_MOTION: { - if (!available()) - return false; - FuncRequest cmd1 = cmd; - DispatchResult res = cur.inset().dispatch(cur, cmd); - if (fitCursor() || res.update()) { - update(); - cur.updatePos(); - } - return true; - } -#else - case LFUN_MOUSE_MOTION: -#endif + // Doesn't go through lyxfunc, so we need to update + // the layout choice etc. ourselves - 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 + // e.g. Qt mouse press when no buffer + if (!available()) + return false; - // Doesn't go through lyxfunc, so we need to update - // the layout choice etc. ourselves + screen().hideCursor(); - // e.g. Qt mouse press when no buffer - if (!available()) - return false; + // either the inset under the cursor or the + // surrounding LyXText will handle this event. - screen().hideCursor(); + // built temporary path to inset + InsetBase * inset = bv_->text()->editXY(cur, cmd.x, cmd.y); + lyxerr << "hit inset at tip: " << inset << endl; + lyxerr << "created temp cursor:\n" << cur << endl; - // either the inset under the cursor or the - // surrounding LyXText will handle this event. + // Try to dispatch to an non-editable inset near this position + // via the temp cursor. If the inset wishes to change the real + // cursor it has to do so explicitly by using + // cur.bv().cursor() = cur; (or similar)' + DispatchResult res; + if (inset) + inset->dispatch(cur, cmd); - // built temporary path to inset - InsetBase * inset = bv_->text()->editXY(cur, cmd.x, cmd.y); - lyxerr << "hit inset at tip: " << inset << endl; - lyxerr << "created temp cursor:\n" << cur << endl; + // Now dispatch to the real cursor. Any change to the cursor + // is immediate. + if (!res.dispatched()) + res = cur.dispatch(cmd); - // Try to dispatch to an non-editable inset near this position - DispatchResult res; - if (inset) - inset->dispatch(cur, cmd); + // If the request was dispatched the temp cursor should have been + // in a way to be used as new 'real' cursor. + if (res.dispatched()) + bv_->cursor() = cur; - // Dispatch to the temp cursor. - // An inset (or LyXText) can assign this to bv->cursor() - // if it wishes to do so. - if (!res.dispatched()) - res = cur.dispatch(cmd); + // Redraw if requested or necessary. + if (res.update()) + update(); + if (fitCursor()) + update(); - if (fitCursor() || res.update()) - update(); + // see workAreaKeyPress + cursor_timeout.restart(); + screen().showCursor(*bv_); - // 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; + // skip these when selecting + if (cmd.action != LFUN_MOUSE_MOTION) { + owner_->updateLayoutChoice(); + owner_->updateToolbar(); } - case LFUN_FILE_OPEN: - owner_->dispatch(cmd); - return true; - - default: - BOOST_ASSERT(false); - } + // slight hack: this is only called currently when we + // clicked somewhere, so we force through the display + // of the new status here. + owner_->clearMessage(); return true; } diff --git a/src/ChangeLog b/src/ChangeLog index 6324e3b575..b0351ee39f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,83 @@ + +2004-03-25 André Pönitz + + * Makefile.am: + * iterators.[Ch]: + * PosIterator.[Ch]: drop PosIterator, replaced by DocumentIterator + + * ParagraphList_fwd.h: change ParagraphList to a std::vector + + * CutAndPaste.[Ch]: simpler interface by moving some stuff from + text*.C over here. Rename namespace CutAndPaste to lyx::cap + + * ParameterStruct.h: merge with ParagraphParameters + + * lyxtext.h: remove LyXText::parOffset() and getPar() + + * text3.C: Remove all 'manual' update calls. We do now one per user + interaction which is completely sufficient. + + * Bidi.C: + * BufferView.[Ch]: + * BufferView_pimpl.C: + * FontIterator.[Ch]: + * MenuBackend.C: + * ParagraphParameters.[Ch]: + * buffer.C: + * buffer.h: + * bufferlist.C: + * cursor.[Ch]: + * cursor_slice.[Ch]: + * dociterator.[Ch]: + * errorlist.[Ch]: + * factory.C: + * lfuns.h: + * lyxfind.C: + * lyxfunc.C: + * output_docbook.[Ch]: + * output_latex.[Ch]: + * output_linuxdoc.[Ch]: + * output_plaintext.[Ch]: + * paragraph.[Ch]: + * paragraph_funcs.[Ch]: + * paragraph_pimpl.[Ch]: + * rowpainter.C: + * tabular.[Ch]: + * text.C: + * text2.C: + * toc.C: + * undo.[Ch]: adjust + + * frontends/controllers/ControlDocument.C: + * frontends/controllers/ControlErrorList.C: + * frontends/controllers/ControlSpellchecker.C: + * insets/inset.C: + * insets/inset.h: + * insets/insetbase.h: + * insets/insetbibitem.C: + * insets/insetbox.C: + * insets/insetbranch.C: + * insets/insetcaption.C: + * insets/insetcharstyle.C: + * insets/insetcharstyle.h: + * insets/insetcollapsable.C: + * insets/insetcollapsable.h: + * insets/insetert.C: + * insets/insetfloat.C: + * insets/insetfoot.C: + * insets/insetmarginal.C: + * insets/insetnote.C: + * insets/insetoptarg.C: + * insets/insettabular.C: + * insets/insettext.C: + * insets/insettext.h: + * insets/insetwrap.C: + * mathed/math_mboxinset.C: + * mathed/math_nestinset.C: + * mathed/math_scriptinset.C: + * mathed/math_scriptinset.h: + * support/types.h: + 2004-03-24 Angus Leeming * BufferView_pimpl.C (cursorToggle): use the cursor toggle to diff --git a/src/CutAndPaste.C b/src/CutAndPaste.C index 522b7d31ef..de02331c41 100644 --- a/src/CutAndPaste.C +++ b/src/CutAndPaste.C @@ -15,20 +15,29 @@ #include "CutAndPaste.h" #include "buffer.h" +#include "buffer_funcs.h" #include "bufferparams.h" +#include "BufferView.h" +#include "cursor.h" #include "errorlist.h" #include "gettext.h" #include "iterators.h" +#include "lyxtext.h" #include "lyxtextclasslist.h" #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" +#include "ParagraphList_fwd.h" +#include "undo.h" #include "insets/insettabular.h" #include "support/lstrings.h" +#include + using lyx::pos_type; +using lyx::par_type; using lyx::textclass_type; using lyx::support::bformat; @@ -40,17 +49,65 @@ using std::vector; using std::string; -typedef limited_stack > CutStack; - namespace { +typedef std::pair PitPosPair; + +typedef limited_stack > CutStack; + CutStack cuts(10); +struct resetOwnerAndChanges : public std::unary_function { + void operator()(Paragraph & p) const { + p.cleanChanges(); + p.setInsetOwner(0); + } +}; + } // namespace anon -std::vector const -CutAndPaste::availableSelections(Buffer const & buffer) +namespace lyx { +namespace cap { + + +int SwitchLayoutsBetweenClasses(textclass_type c1, textclass_type c2, + ParagraphList & pars, ErrorList & errorlist) +{ + BOOST_ASSERT(!pars.empty()); + int ret = 0; + if (c1 == c2) + return ret; + + LyXTextClass const & tclass1 = textclasslist[c1]; + LyXTextClass const & tclass2 = textclasslist[c2]; + ParIterator end = ParIterator(pars.size(), pars); + for (ParIterator it = ParIterator(0, pars); it != end; ++it) { + string const name = it->layout()->name(); + bool hasLayout = tclass2.hasLayout(name); + + if (hasLayout) + it->layout(tclass2[name]); + else + it->layout(tclass2.defaultLayout()); + + if (!hasLayout && name != tclass1.defaultLayoutName()) { + ++ret; + string const s = bformat( + _("Layout had to be changed from\n%1$s to %2$s\n" + "because of class conversion from\n%3$s to %4$s"), + name, it->layout()->name(), tclass1.name(), tclass2.name()); + // To warn the user that something had to be done. + errorlist.push_back(ErrorItem("Changed Layout", s, + it->id(), 0, + it->size())); + } + } + return ret; +} + + +std::vector const availableSelections(Buffer const & buffer) { vector selList; @@ -78,55 +135,40 @@ CutAndPaste::availableSelections(Buffer const & buffer) } -PitPosPair CutAndPaste::cutSelection(BufferParams const & params, - ParagraphList & pars, - ParagraphList::iterator startpit, - ParagraphList::iterator endpit, - int startpos, int endpos, - textclass_type tc, bool doclear) +PitPosPair eraseSelection(BufferParams const & params, ParagraphList & pars, + par_type startpit, par_type endpit, + int startpos, int endpos, bool doclear) { - copySelection(startpit, endpit, startpos, endpos, tc); - return eraseSelection(params, pars, startpit, endpit, startpos, - endpos, doclear); -} - - -PitPosPair CutAndPaste::eraseSelection(BufferParams const & params, - ParagraphList & pars, - ParagraphList::iterator startpit, - ParagraphList::iterator endpit, - int startpos, int endpos, bool doclear) -{ - if (startpit == pars.end() || (startpos > startpit->size())) + if (startpit == pars.size() || (startpos > pars[startpit].size())) return PitPosPair(endpit, endpos); - if (endpit == pars.end() || startpit == endpit) { - endpos -= startpit->erase(startpos, endpos); + if (endpit == pars.size() || startpit == endpit) { + endpos -= pars[startpit].erase(startpos, endpos); return PitPosPair(endpit, endpos); } // clear end/begin fragments of the first/last par in selection bool all_erased = true; - startpit->erase(startpos, startpit->size()); - if (startpit->size() != startpos) + pars[startpit].erase(startpos, pars[startpit].size()); + if (pars[startpit].size() != startpos) all_erased = false; - endpos -= endpit->erase(0, endpos); + endpos -= pars[endpit].erase(0, endpos); if (endpos != 0) all_erased = false; // Loop through the deleted pars if any, erasing as needed - ParagraphList::iterator pit = boost::next(startpit); + par_type pit = startpit + 1; - while (pit != endpit && pit != pars.end()) { - ParagraphList::iterator const next = boost::next(pit); + while (pit != endpit && pit != pars.size()) { + par_type const next = pit + 1; // "erase" the contents of the par - pit->erase(0, pit->size()); - if (!pit->size()) { + pars[pit].erase(0, pars[pit].size()); + if (!pars[pit].size()) { // remove the par if it's now empty - pars.erase(pit); + pars.erase(pars.begin() + pit); } else all_erased = false; pit = next; @@ -141,17 +183,17 @@ PitPosPair CutAndPaste::eraseSelection(BufferParams const & params, } #endif - if (boost::next(startpit) == pars.end()) + if (startpit + 1 == pars.size()) return PitPosPair(endpit, endpos); if (doclear) { - boost::next(startpit)->stripLeadingSpaces(); + pars[startpit + 1].stripLeadingSpaces(); } // paste the paragraphs again, if possible if (all_erased && - (startpit->hasSameLayout(*boost::next(startpit)) || - boost::next(startpit)->empty())) { + (pars[startpit].hasSameLayout(pars[startpit + 1]) || + pars[startpit + 1].empty())) { mergeParagraph(params, pars, startpit); // this because endpar gets deleted here! endpit = startpit; @@ -163,30 +205,16 @@ PitPosPair CutAndPaste::eraseSelection(BufferParams const & params, } -namespace { - -struct resetOwnerAndChanges : public std::unary_function { - void operator()(Paragraph & p) const { - p.cleanChanges(); - p.setInsetOwner(0); - } -}; - -} // anon namespace - -bool CutAndPaste::copySelection(ParagraphList::iterator startpit, - ParagraphList::iterator endpit, - int start, int end, textclass_type tc) +bool copySelection(ParagraphList & pars, + par_type startpit, par_type endpit, + int start, int end, textclass_type tc) { - BOOST_ASSERT(0 <= start && start <= startpit->size()); - BOOST_ASSERT(0 <= end && end <= endpit->size()); + BOOST_ASSERT(0 <= start && start <= pars[startpit].size()); + BOOST_ASSERT(0 <= end && end <= pars[endpit].size()); BOOST_ASSERT(startpit != endpit || start <= end); - // Clone the paragraphs within the selection. - ParagraphList::iterator postend = boost::next(endpit); - - ParagraphList paragraphs(startpit, postend); + ParagraphList paragraphs(pars.begin() + startpit, pars.begin() + endpit + 1); for_each(paragraphs.begin(), paragraphs.end(), resetOwnerAndChanges()); // Cut out the end of the last paragraph. @@ -203,46 +231,43 @@ bool CutAndPaste::copySelection(ParagraphList::iterator startpit, } -pair -CutAndPaste::pasteSelection(Buffer const & buffer, - ParagraphList & pars, - ParagraphList::iterator pit, int pos, - textclass_type tc, - ErrorList & errorlist) +PitPosPair cutSelection(BufferParams const & params, ParagraphList & pars, + par_type startpit, par_type endpit, + int startpos, int endpos, textclass_type tc, bool doclear) { - return pasteSelection(buffer, pars, pit, pos, tc, 0, errorlist); + copySelection(pars, startpit, endpit, startpos, endpos, tc); + return eraseSelection(params, pars, startpit, endpit, startpos, + endpos, doclear); } -pair -CutAndPaste::pasteSelection(Buffer const & buffer, - ParagraphList & pars, - ParagraphList::iterator pit, int pos, - textclass_type tc, size_t cut_index, - ErrorList & errorlist) +pair +pasteSelection(Buffer const & buffer, ParagraphList & pars, + par_type pit, int pos, + textclass_type tc, size_t cut_index, ErrorList & errorlist) { if (!checkPastePossible()) return make_pair(PitPosPair(pit, pos), pit); - BOOST_ASSERT (pos <= pit->size()); + BOOST_ASSERT (pos <= pars[pit].size()); // Make a copy of the CaP paragraphs. - ParagraphList simple_cut_clone = cuts[cut_index].first; + ParagraphList insertion = cuts[cut_index].first; textclass_type const textclass = cuts[cut_index].second; // Now remove all out of the pars which is NOT allowed in the // new environment and set also another font if that is required. // Make sure there is no class difference. - SwitchLayoutsBetweenClasses(textclass, tc, simple_cut_clone, + SwitchLayoutsBetweenClasses(textclass, tc, insertion, errorlist); - ParagraphList::iterator tmpbuf = simple_cut_clone.begin(); - int depth_delta = pit->params().depth() - tmpbuf->params().depth(); + ParagraphList::iterator tmpbuf = insertion.begin(); + int depth_delta = pars[pit].params().depth() - tmpbuf->params().depth(); - Paragraph::depth_type max_depth = pit->getMaxDepthAfter(); + Paragraph::depth_type max_depth = pars[pit].getMaxDepthAfter(); - for (; tmpbuf != simple_cut_clone.end(); ++tmpbuf) { + for (; tmpbuf != insertion.end(); ++tmpbuf) { // If we have a negative jump so that the depth would // go below 0 depth then we have to redo the delta to // this new max depth level so that subsequent @@ -258,28 +283,26 @@ CutAndPaste::pasteSelection(Buffer const & buffer, // Only set this from the 2nd on as the 2nd depends // for maxDepth still on pit. - if (tmpbuf != simple_cut_clone.begin()) + if (tmpbuf != insertion.begin()) max_depth = tmpbuf->getMaxDepthAfter(); // Set the inset owner of this paragraph. - tmpbuf->setInsetOwner(pit->inInset()); + tmpbuf->setInsetOwner(pars[pit].inInset()); for (pos_type i = 0; i < tmpbuf->size(); ++i) { if (tmpbuf->getChar(i) == Paragraph::META_INSET) { - if (!pit->insetAllowed(tmpbuf->getInset(i)->lyxCode())) + if (!pars[pit].insetAllowed(tmpbuf->getInset(i)->lyxCode())) tmpbuf->erase(i--); } } } - // Make the buf exactly the same layout than - // the cursor paragraph. - simple_cut_clone.begin()->makeSameLayout(*pit); + // Make the buf exactly the same layout as the cursor paragraph. + insertion.begin()->makeSameLayout(pars[pit]); - // Prepare the paragraphs and insets for insertion - // A couple of insets store buffer references so need - // updating - ParIterator fpit(simple_cut_clone.begin(), simple_cut_clone); - ParIterator fend(simple_cut_clone.end(), simple_cut_clone); + // Prepare the paragraphs and insets for insertion. + // A couple of insets store buffer references so need updating. + ParIterator fpit(0, insertion); + ParIterator fend(insertion.size(), insertion); for (; fpit != fend; ++fpit) { InsetList::iterator lit = fpit->insetlist.begin(); @@ -299,103 +322,242 @@ CutAndPaste::pasteSelection(Buffer const & buffer, } } - bool paste_the_end = false; - - // Open the paragraph for inserting the buf - // if necessary. - if (pit->size() > pos || boost::next(pit) == pars.end()) { - breakParagraphConservative(buffer.params(), - pars, pit, pos); - paste_the_end = true; + // Split the paragraph for inserting the buf if necessary. + bool did_split = false; + if (pars[pit].size() || pit + 1 == pars.size()) { + breakParagraphConservative(buffer.params(), pars, pit, pos); + did_split = true; } - // Set the end for redoing later. - ParagraphList::iterator endpit = boost::next(boost::next(pit)); - // Paste it! - - ParagraphList::iterator past_pit = boost::next(pit); - pars.splice(past_pit, simple_cut_clone); - ParagraphList::iterator last_paste = boost::prior(past_pit); + pars.insert(pars.begin() + pit + 1, insertion.begin(), insertion.end()); + par_type last_paste = pit + insertion.size(); // If we only inserted one paragraph. - if (boost::next(pit) == last_paste) + if (insertion.size() == 1) last_paste = pit; mergeParagraph(buffer.params(), pars, pit); // Store the new cursor position. pit = last_paste; - pos = last_paste->size(); + pos = pars[last_paste].size(); // Maybe some pasting. - if (boost::next(last_paste) != pars.end() && - paste_the_end) { - if (boost::next(last_paste)->hasSameLayout(*last_paste)) { - mergeParagraph(buffer.params(), pars, - last_paste); - } else if (boost::next(last_paste)->empty()) { - boost::next(last_paste)->makeSameLayout(*last_paste); - mergeParagraph(buffer.params(), pars, - last_paste); - } else if (last_paste->empty()) { - last_paste->makeSameLayout(*boost::next(last_paste)); - mergeParagraph(buffer.params(), pars, - last_paste); + if (did_split && last_paste + 1 != pars.size()) { + if (pars[last_paste + 1].hasSameLayout(pars[last_paste])) { + mergeParagraph(buffer.params(), pars, last_paste); + } else if (pars[last_paste + 1].empty()) { + pars[last_paste + 1].makeSameLayout(pars[last_paste]); + mergeParagraph(buffer.params(), pars, last_paste); + } else if (pars[last_paste].empty()) { + pars[last_paste].makeSameLayout(pars[last_paste]); + mergeParagraph(buffer.params(), pars, last_paste); } else - boost::next(last_paste)->stripLeadingSpaces(); + pars[last_paste + 1].stripLeadingSpaces(); } - return make_pair(PitPosPair(pit, pos), endpit); + return make_pair(PitPosPair(pit, pos), pit + insertion.size() + 1); } -int CutAndPaste::nrOfParagraphs() +pair +pasteSelection(Buffer const & buffer, ParagraphList & pars, + par_type pit, int pos, textclass_type tc, ErrorList & errorlist) +{ + return pasteSelection(buffer, pars, pit, pos, tc, 0, errorlist); +} + + +int nrOfParagraphs() { return cuts.empty() ? 0 : cuts[0].first.size(); } -int CutAndPaste::SwitchLayoutsBetweenClasses(textclass_type c1, - textclass_type c2, - ParagraphList & pars, - ErrorList & errorlist) -{ - BOOST_ASSERT(!pars.empty()); - - int ret = 0; - if (c1 == c2) - return ret; - - LyXTextClass const & tclass1 = textclasslist[c1]; - LyXTextClass const & tclass2 = textclasslist[c2]; - ParIterator end = ParIterator(pars.end(), pars); - for (ParIterator it = ParIterator(pars.begin(), pars); it != end; ++it) { - string const name = it->layout()->name(); - bool hasLayout = tclass2.hasLayout(name); - - if (hasLayout) - it->layout(tclass2[name]); - else - it->layout(tclass2.defaultLayout()); - - if (!hasLayout && name != tclass1.defaultLayoutName()) { - ++ret; - string const s = bformat( - _("Layout had to be changed from\n%1$s to %2$s\n" - "because of class conversion from\n%3$s to %4$s"), - name, it->layout()->name(), tclass1.name(), tclass2.name()); - // To warn the user that something had to be done. - errorlist.push_back(ErrorItem("Changed Layout", s, - it->id(), 0, - it->size())); - } - } - return ret; -} - - -bool CutAndPaste::checkPastePossible() +bool checkPastePossible() { return !cuts.empty() && !cuts[0].first.empty(); } + + +void cutSelection(LCursor & cur, bool doclear, bool realcut) +{ + LyXText * text = cur.text(); + BOOST_ASSERT(text); + // Stuff what we got on the clipboard. Even if there is no selection. + + // There is a problem with having the stuffing here in that the + // larger the selection the slower LyX will get. This can be + // solved by running the line below only when the selection has + // finished. The solution used currently just works, to make it + // faster we need to be more clever and probably also have more + // calls to stuffClipboard. (Lgb) + cur.bv().stuffClipboard(cur.selectionAsString(true)); + + // This doesn't make sense, if there is no selection + if (!cur.selection()) + return; + + // OK, we have a selection. This is always between cur.selBegin() + // and cur.selEnd() + + // make sure that the depth behind the selection are restored, too + recordUndoSelection(cur); + par_type begpit = cur.selBegin().par(); + par_type endpit = cur.selEnd().par(); + + int endpos = cur.selEnd().pos(); + + BufferParams const & bufparams = cur.bv().buffer()->params(); + boost::tie(endpit, endpos) = realcut ? + cutSelection(bufparams, + text->paragraphs(), + begpit, endpit, + cur.selBegin().pos(), endpos, + bufparams.textclass, + doclear) + : eraseSelection(bufparams, + text->paragraphs(), + begpit, endpit, + cur.selBegin().pos(), endpos, + doclear); + // sometimes necessary + if (doclear) + text->paragraphs()[begpit].stripLeadingSpaces(); + + text->redoParagraphs(begpit, begpit + 1); + // cutSelection can invalidate the cursor so we need to set + // it anew. (Lgb) + // we prefer the end for when tracking changes + cur.pos() = endpos; + cur.par() = endpit; + + // need a valid cursor. (Lgb) + cur.clearSelection(); + text->updateCounters(); +} + + +void copySelection(LCursor & cur) +{ + LyXText * text = cur.text(); + BOOST_ASSERT(text); + // stuff the selection onto the X clipboard, from an explicit copy request + cur.bv().stuffClipboard(cur.selectionAsString(true)); + + // this doesn't make sense, if there is no selection + if (!cur.selection()) + return; + + // ok we have a selection. This is always between cur.selBegin() + // and sel_end cursor + + // copy behind a space if there is one + ParagraphList & pars = text->paragraphs(); + pos_type pos = cur.selBegin().pos(); + par_type par = cur.selBegin().par(); + while (pos < pars[par].size() + && pars[par].isLineSeparator(pos) + && (par != cur.selEnd().par() || pos < cur.selEnd().pos())) + ++pos; + + copySelection(pars, par, cur.selEnd().par(), + pos, cur.selEnd().pos(), cur.bv().buffer()->params().textclass); +} + + +void pasteSelection(LCursor & cur, size_t sel_index) +{ + LyXText * text = cur.text(); + BOOST_ASSERT(text); + // this does not make sense, if there is nothing to paste + if (!checkPastePossible()) + return; + + recordUndo(cur); + + par_type endpit; + PitPosPair ppp; + + ErrorList el; + + boost::tie(ppp, endpit) = + pasteSelection(*cur.bv().buffer(), + text->paragraphs(), + cur.par(), cur.pos(), + cur.bv().buffer()->params().textclass, + sel_index, el); + bufferErrors(*cur.bv().buffer(), el); + text->bv()->showErrorList(_("Paste")); + + text->redoParagraphs(cur.par(), endpit); + + cur.clearSelection(); + cur.resetAnchor(); + text->setCursor(cur, ppp.first, ppp.second); + cur.setSelection(); + text->updateCounters(); +} + + +void setSelectionRange(LCursor & cur, pos_type length) +{ + LyXText * text = cur.text(); + BOOST_ASSERT(text); + if (!length) + return; + cur.resetAnchor(); + while (length--) + text->cursorRight(cur); + cur.setSelection(); +} + + +// simple replacing. The font of the first selected character is used +void replaceSelectionWithString(LCursor & cur, string const & str) +{ + LyXText * text = cur.text(); + BOOST_ASSERT(text); + recordUndo(cur); + + // Get font setting before we cut + pos_type pos = cur.selEnd().pos(); + LyXFont const font = text->getPar(cur.selBegin().par()). + getFontSettings(cur.bv().buffer()->params(), cur.selBegin().pos()); + + // Insert the new string + string::const_iterator cit = str.begin(); + string::const_iterator end = str.end(); + for (; cit != end; ++cit, ++pos) + text->getPar(cur.selEnd().par()).insertChar(pos, (*cit), font); + + // Cut the selection + cutSelection(cur, true, false); +} + + +void replaceSelection(LCursor & cur) +{ + if (cur.selection()) + cutSelection(cur, true, false); +} + + +// only used by the spellchecker +void replaceWord(LCursor & cur, string const & replacestring) +{ + LyXText * text = cur.text(); + BOOST_ASSERT(text); + + replaceSelectionWithString(cur, replacestring); + setSelectionRange(cur, replacestring.length()); + + // Go back so that replacement string is also spellchecked + for (string::size_type i = 0; i < replacestring.length() + 1; ++i) + text->cursorLeft(cur); +} + + +} // namespace cap +} // namespace lyx diff --git a/src/CutAndPaste.h b/src/CutAndPaste.h index 0c753fbadc..7e52bcea53 100644 --- a/src/CutAndPaste.h +++ b/src/CutAndPaste.h @@ -14,60 +14,45 @@ #ifndef CUTANDPASTE_H #define CUTANDPASTE_H -#include "ParagraphList_fwd.h" #include "support/types.h" #include #include class Buffer; -class BufferParams; class ErrorList; class LyXTextClass; -class Paragraph; +class LCursor; +class ParagraphList; /// -namespace CutAndPaste { +namespace lyx { +namespace cap { /// std::vector const availableSelections(Buffer const & buffer); /// -PitPosPair cutSelection(BufferParams const & params, - ParagraphList & pars, - ParagraphList::iterator startpit, - ParagraphList::iterator endpit, - int start, int end, lyx::textclass_type tc, - bool doclear = false); -/// -PitPosPair eraseSelection(BufferParams const & params, - ParagraphList & pars, - ParagraphList::iterator startpit, - ParagraphList::iterator endpit, - int start, int end, bool doclear = false); -/// -bool copySelection(ParagraphList::iterator startpit, - ParagraphList::iterator endpit, - int start, int end, lyx::textclass_type tc); -/// -std::pair -pasteSelection(Buffer const & buffer, - ParagraphList & pars, - ParagraphList::iterator pit, int pos, - lyx::textclass_type tc, ErrorList &); +void cutSelection(LCursor & cur, bool doclear, bool realcut); + +/** + * Sets the selection from the current cursor position to length + * characters to the right. No safety checks. + */ +void setSelectionRange(LCursor & cur, lyx::pos_type length); +/// simply replace using the font of the first selected character +void replaceSelectionWithString(LCursor & cur, std::string const & str); +/// replace selection helper +void replaceSelection(LCursor & cur); /// -std::pair -pasteSelection(Buffer const & buffer, - ParagraphList & pars, - ParagraphList::iterator pit, int pos, - lyx::textclass_type tc, - size_t cuts_indexm, ErrorList &); - +void cutSelection(LCursor & cur, bool doclear = true, bool realcut = true); /// -int nrOfParagraphs(); +void copySelection(LCursor & cur); +/// +void pasteSelection(LCursor & cur, size_t sel_index = 0); -/** Needed to switch between different classes this works +/** Needed to switch between different classes. This works for a list of paragraphs beginning with the specified par return value is the number of wrong conversions. */ @@ -78,6 +63,10 @@ int SwitchLayoutsBetweenClasses(lyx::textclass_type c1, /// bool checkPastePossible(); -} // end of CutAndPaste +// only used by the spellchecker +void replaceWord(LCursor & cur, std::string const & replacestring); + +} // namespace cap +} // namespce lyx #endif diff --git a/src/FontIterator.C b/src/FontIterator.C index 9de58e3e3b..f4fe4ade5c 100644 --- a/src/FontIterator.C +++ b/src/FontIterator.C @@ -12,24 +12,24 @@ #include -#include "lyxtext.h" - #include "FontIterator.h" + +#include "lyxtext.h" #include "paragraph.h" -FontIterator::FontIterator(LyXText const & text, ParagraphList::iterator pit, +FontIterator::FontIterator(LyXText const & text, lyx::par_type pit, lyx::pos_type pos) : text_(text), pit_(pit), pos_(pos), font_(text.getFont(pit, pos)), - endspan_(pit->getEndPosOfFontSpan(pos)), - bodypos_(pit->beginOfBody()) + endspan_(text.getPar(pit).getEndPosOfFontSpan(pos)), + bodypos_(text.getPar(pit).beginOfBody()) {} LyXFont FontIterator::operator*() const { - return font_; + return font_; } @@ -44,7 +44,7 @@ FontIterator & FontIterator::operator++() ++pos_; if (pos_ > endspan_ || pos_ == bodypos_) { font_ = text_.getFont(pit_, pos_); - endspan_ = pit_->getEndPosOfFontSpan(pos_); + endspan_ = text_.getPar(pit_).getEndPosOfFontSpan(pos_); } return *this; } diff --git a/src/FontIterator.h b/src/FontIterator.h index f640c8a661..e52c67b175 100644 --- a/src/FontIterator.h +++ b/src/FontIterator.h @@ -20,31 +20,38 @@ #ifndef FONTITERATOR_H #define FONTITERATOR_H - #include "lyxfont.h" -#include "ParagraphList_fwd.h" #include "support/types.h" class LyXText; + class FontIterator : std::iterator { public: - FontIterator(LyXText const & text, ParagraphList::iterator pit, - lyx::pos_type pos); - + /// + FontIterator(LyXText const & text, lyx::par_type pit, lyx::pos_type pos); + /// LyXFont operator*() const; + /// FontIterator & operator++(); + /// LyXFont * operator->(); private: + /// LyXText const & text_; - ParagraphList::iterator pit_; + /// + lyx::par_type pit_; + /// lyx::pos_type pos_; + /// LyXFont font_; + /// lyx::pos_type endspan_; + /// lyx::pos_type bodypos_; }; -#endif //FONTITERATOR_H +#endif // FONTITERATOR_H diff --git a/src/Makefile.am b/src/Makefile.am index 455a559fa8..a3dca7310d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -96,7 +96,6 @@ lyx_SOURCES = \ ParagraphList_fwd.h \ ParagraphParameters.C \ ParagraphParameters.h \ - ParameterStruct.h \ PrinterParams.C \ PrinterParams.h \ RowList_fwd.h \ @@ -242,8 +241,6 @@ lyx_SOURCES = \ paragraph_funcs.h \ paragraph_pimpl.C \ paragraph_pimpl.h \ - PosIterator.h \ - PosIterator.C \ SpellBase.h \ ispell.C \ ispell.h \ diff --git a/src/MenuBackend.C b/src/MenuBackend.C index 180a98fbb9..7eb3166240 100644 --- a/src/MenuBackend.C +++ b/src/MenuBackend.C @@ -684,11 +684,11 @@ void expandPasteRecent(Menu & tomenu, LyXView const * view) if (!view || !view->buffer()) return; - vector const selL = - CutAndPaste::availableSelections(*view->buffer()); + vector const sel = + lyx::cap::availableSelections(*view->buffer()); - vector::const_iterator cit = selL.begin(); - vector::const_iterator end = selL.end(); + vector::const_iterator cit = sel.begin(); + vector::const_iterator end = sel.end(); for (unsigned int index = 0; cit != end; ++cit, ++index) { tomenu.add(MenuItem(MenuItem::Command, *cit, diff --git a/src/ParagraphList_fwd.h b/src/ParagraphList_fwd.h index e3401edaf6..8febea1383 100644 --- a/src/ParagraphList_fwd.h +++ b/src/ParagraphList_fwd.h @@ -12,13 +12,22 @@ #ifndef PARAGRAPH_LIST_FWD_H #define PARAGRAPH_LIST_FWD_H -#include -#include +#include class Paragraph; -typedef std::list ParagraphList; - -typedef std::pair PitPosPair; +class ParagraphList : public std::vector +{ +public: + /// + typedef std::vector base_type; + /// + ParagraphList(); + /// + template + ParagraphList(Iter beg, Iter end) + : base_type(beg, end) + {} +}; #endif diff --git a/src/ParagraphParameters.C b/src/ParagraphParameters.C index 7c6be1abf9..757ab074f6 100644 --- a/src/ParagraphParameters.C +++ b/src/ParagraphParameters.C @@ -23,7 +23,6 @@ #include "lyxlex.h" #include "lyxtext.h" #include "paragraph.h" -#include "ParameterStruct.h" #include "tex-strings.h" #include "frontends/LyXView.h" @@ -39,169 +38,133 @@ using std::ostringstream; using std::string; -// Initialize static member var. -ShareContainer ParagraphParameters::container; - ParagraphParameters::ParagraphParameters() -{ - ParameterStruct tmp; - set_from_struct(tmp); -} + : noindent_(false), + start_of_appendix_(false), appendix_(false), + align_(LYX_ALIGN_LAYOUT), depth_(0) +{} void ParagraphParameters::clear() { - ParameterStruct tmp(*param); - tmp.spacing.set(Spacing::Default); - tmp.align = LYX_ALIGN_LAYOUT; - tmp.depth = 0; - tmp.noindent = false; - tmp.labelstring.erase(); - tmp.labelwidthstring.erase(); - tmp.start_of_appendix = false; - set_from_struct(tmp); + operator=(ParagraphParameters()); } ParagraphParameters::depth_type ParagraphParameters::depth() const { - return param->depth; + return depth_; } bool ParagraphParameters::sameLayout(ParagraphParameters const & pp) const { - return param->align == pp.param->align && - param->spacing == pp.param->spacing && - param->noindent == pp.param->noindent && - param->depth == pp.param->depth; -} - - -void ParagraphParameters::set_from_struct(ParameterStruct const & ps) -{ - // get new param from container with tmp as template - param = container.get(ps); + return align_ == pp.align_ + && spacing_ == pp.spacing_ + && noindent_ == pp.noindent_ + && depth_ == pp.depth_; } Spacing const & ParagraphParameters::spacing() const { - return param->spacing; + return spacing_; } void ParagraphParameters::spacing(Spacing const & s) { - ParameterStruct tmp(*param); - tmp.spacing = s; - set_from_struct(tmp); + spacing_ = s; } bool ParagraphParameters::noindent() const { - return param->noindent; + return noindent_; } void ParagraphParameters::noindent(bool ni) { - ParameterStruct tmp(*param); - tmp.noindent = ni; - set_from_struct(tmp); + noindent_ = ni; } LyXAlignment ParagraphParameters::align() const { - return param->align; + return align_; } void ParagraphParameters::align(LyXAlignment la) { - ParameterStruct tmp(*param); - tmp.align = la; - set_from_struct(tmp); + align_ = la; } void ParagraphParameters::depth(depth_type d) { - ParameterStruct tmp(*param); - tmp.depth = d; - set_from_struct(tmp); + depth_ = d; } bool ParagraphParameters::startOfAppendix() const { - return param->start_of_appendix; + return start_of_appendix_; } void ParagraphParameters::startOfAppendix(bool soa) { - ParameterStruct tmp(*param); - tmp.start_of_appendix = soa; - set_from_struct(tmp); + start_of_appendix_ = soa; } bool ParagraphParameters::appendix() const { - return param->appendix; + return appendix_; } void ParagraphParameters::appendix(bool a) { - ParameterStruct tmp(*param); - tmp.appendix = a; - set_from_struct(tmp); + appendix_ = a; } string const & ParagraphParameters::labelString() const { - return param->labelstring; + return labelstring_; } void ParagraphParameters::labelString(string const & ls) { - ParameterStruct tmp(*param); - tmp.labelstring = ls; - set_from_struct(tmp); + labelstring_ = ls; } string const & ParagraphParameters::labelWidthString() const { - return param->labelwidthstring; + return labelwidthstring_; } void ParagraphParameters::labelWidthString(string const & lws) { - ParameterStruct tmp(*param); - tmp.labelwidthstring = lws; - set_from_struct(tmp); + labelwidthstring_ = lws; } LyXLength const & ParagraphParameters::leftIndent() const { - return param->leftindent; + return leftindent_; } void ParagraphParameters::leftIndent(LyXLength const & li) { - ParameterStruct tmp(*param); - tmp.leftindent = li; - set_from_struct(tmp); + leftindent_ = li; } @@ -323,3 +286,22 @@ void params2string(Paragraph const & par, string & data) data = os.str(); } + + +/* +bool operator==(ParagraphParameeters const & ps1, + ParagraphParameeters const & ps2) +{ + return + ps1.spacing == ps2.spacing + && ps1.noindent == ps2.noindent + && ps1.align == ps2.align + && ps1.depth == ps2.depth + && ps1.start_of_appendix == ps2.start_of_appendix + && ps1.appendix == ps2.appendix + && ps1.labelstring == ps2.labelstring + && ps1.labelwidthstring == ps2.labelwidthstring + && ps1.leftindent == ps2.leftindent; +} +*/ + diff --git a/src/ParagraphParameters.h b/src/ParagraphParameters.h index 99369cfcd5..fc6d9acf3b 100644 --- a/src/ParagraphParameters.h +++ b/src/ParagraphParameters.h @@ -15,7 +15,8 @@ #define PARAGRAPHPARAMETERS_H #include "layout.h" -#include "ShareContainer.h" +#include "lyxlength.h" +#include "Spacing.h" #include "support/types.h" @@ -26,7 +27,6 @@ class BufferView; class LyXLength; class LyXLex; class Paragraph; -class ParameterStruct; class Spacing; @@ -84,16 +84,32 @@ public: /// write out the parameters to a stream void write(std::ostream & os) const; + //friend bool operator==(ParameterStruct const & ps1, + //ParameterStruct const & ps2); + private: /// - void set_from_struct(ParameterStruct const &); + Spacing spacing_; /// - boost::shared_ptr param; + bool noindent_; /// - static ShareContainer container; + bool start_of_appendix_; + /// + bool appendix_; + /// + LyXAlignment align_; + /// + depth_type depth_; + /// + std::string labelstring_; + /// + std::string labelwidthstring_; + /// + LyXLength leftindent_; }; + /** Generate a string \param data from \param par's ParagraphParameters. The function also generates some additional info needed by the Paragraph dialog. diff --git a/src/ParameterStruct.h b/src/ParameterStruct.h deleted file mode 100644 index 5b0543e441..0000000000 --- a/src/ParameterStruct.h +++ /dev/null @@ -1,73 +0,0 @@ -// -*- C++ -*- -/** - * \file ParameterStruct.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Lars Gullik Bjønnes - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef PARAMETERSTRUCT_H -#define PARAMETERSTRUCT_H - -#include "layout.h" -#include "lyxlength.h" -#include "Spacing.h" - -#include "support/types.h" - - -/// -struct ParameterStruct { - /// - typedef lyx::depth_type depth_type; - /// - ParameterStruct(); - /// - Spacing spacing; - /// - bool noindent; - /// - LyXAlignment align; - /// - depth_type depth; - /// - bool start_of_appendix; - /// - bool appendix; - /// - std::string labelstring; - /// - std::string labelwidthstring; - /// - LyXLength leftindent; -}; - - -inline -ParameterStruct::ParameterStruct() - : noindent(false), - align(LYX_ALIGN_BLOCK), depth(0), start_of_appendix(false), - appendix(false) -{} - - -inline -bool operator==(ParameterStruct const & ps1, - ParameterStruct const & ps2) -{ - return - ps1.spacing == ps2.spacing - && ps1.noindent == ps2.noindent - && ps1.align == ps2.align - && ps1.depth == ps2.depth - && ps1.start_of_appendix == ps2.start_of_appendix - && ps1.appendix == ps2.appendix - && ps1.labelstring == ps2.labelstring - && ps1.labelwidthstring == ps2.labelwidthstring - && ps1.leftindent == ps2.leftindent; -} - -#endif diff --git a/src/PosIterator.C b/src/PosIterator.C deleted file mode 100644 index 67772f4b5c..0000000000 --- a/src/PosIterator.C +++ /dev/null @@ -1,173 +0,0 @@ -/* \file PosIterator.C - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Alfredo Braunstein - * - * Full author contact details are available in file CREDITS. - */ - - -#include - -#include "PosIterator.h" - -#include "buffer.h" -#include "BufferView.h" -#include "cursor.h" -#include "iterators.h" -#include "lyxtext.h" -#include "paragraph.h" - -#include "insets/insettext.h" -#include "insets/updatableinset.h" -#include "insets/inset.h" - -#include - - -using boost::prior; - - -PosIterator::PosIterator(ParagraphList * pl, ParagraphList::iterator pit, - lyx::pos_type pos) -{ - stack_.push_back(PosIteratorItem(pl, pit, pos)); -} - - -PosIterator::PosIterator(BufferView & bv) -{ - LCursor & cur = bv.cursor(); - BOOST_ASSERT(cur.inTexted()); - LyXText * text = cur.text(); - lyx::pos_type pos = cur.pos(); - ParagraphList::iterator pit = text->getPar(cur.par()); - - ParIterator par = bv.buffer()->par_iterator_begin(); - ParIterator end = bv.buffer()->par_iterator_end(); - for (; par != end; ++par) { - if (par.pit() == pit) - break; - } - setFrom(par, pos); -} - - -PosIterator::PosIterator(ParIterator const & par, lyx::pos_type pos) -{ - setFrom(par, pos); -} - - -void PosIterator::setFrom(ParIterator const & par, lyx::pos_type pos) -{ - BOOST_ASSERT(par.size() > 0); - - ParIterator::PosHolder const & ph = par.positions(); - - int const last = par.size() - 1; - for (int i = 0; i < last; ++i) { - ParPosition const & pp = ph[i]; - stack_.push_back( - PosIteratorItem(const_cast(pp.plist), - pp.pit, (*pp.it)->pos, *pp.index + 1)); - } - ParPosition const & pp = ph[last]; - stack_.push_back( - PosIteratorItem(const_cast(pp.plist), pp.pit, pos, 0)); -} - - -PosIterator & PosIterator::operator++() -{ - BOOST_ASSERT(!stack_.empty()); - while (true) { - PosIteratorItem & p = stack_.back(); - - if (p.pos < p.pit->size()) { - if (InsetBase * inset = p.pit->getInset(p.pos)) { - if (LyXText * text = inset->getText(p.index)) { - ParagraphList & pl = text->paragraphs(); - p.index++; - stack_.push_back(PosIteratorItem(&pl, pl.begin(), 0)); - return *this; - } - } - p.index = 0; - ++p.pos; - } else { - ++p.pit; - p.pos = 0; - } - - if (p.pit != p.pl->end() || stack_.size() == 1) - return *this; - - stack_.pop_back(); - } - return *this; -} - - -PosIterator & PosIterator::operator--() -{ - BOOST_ASSERT(!stack_.empty()); - - // try to go one position backwards: if on the start of the - // ParagraphList, pops an item - PosIteratorItem & p = stack_.back(); - if (p.pos > 0) { - --p.pos; - InsetBase * inset = p.pit->getInset(p.pos); - if (inset) - p.index = inset->nargs(); - } else { - if (p.pit == p.pl->begin()) { - if (stack_.size() == 1) - return *this; - stack_.pop_back(); - --stack_.back().index; - } else { - --p.pit; - p.pos = p.pit->size(); - } - } - // try to push an item if there is some left unexplored - PosIteratorItem & q = stack_.back(); - if (q.pos < q.pit->size()) { - InsetBase * inset = q.pit->getInset(q.pos); - if (inset && q.index > 0) { - LyXText * text = inset->getText(q.index - 1); - BOOST_ASSERT(text); - ParagraphList & pl = text->paragraphs(); - stack_.push_back(PosIteratorItem(&pl, prior(pl.end()), pl.back().size())); - } - } - return *this; -} - - -bool operator==(PosIterator const & lhs, PosIterator const & rhs) -{ - PosIteratorItem const & li = lhs.stack_.back(); - PosIteratorItem const & ri = rhs.stack_.back(); - - return (li.pl == ri.pl && li.pit == ri.pit && - (li.pit == li.pl->end() || li.pos == ri.pos)); -} - - -bool PosIterator::at_end() const -{ - return pos() == pit()->size(); -} - - -InsetBase * PosIterator::inset() const -{ - if (stack_.size() == 1) - return 0; - PosIteratorItem const & pi = stack_[stack_.size() - 2]; - return pi.pit->getInset(pi.pos); -} diff --git a/src/PosIterator.h b/src/PosIterator.h deleted file mode 100644 index cc6107e368..0000000000 --- a/src/PosIterator.h +++ /dev/null @@ -1,75 +0,0 @@ -// -*- C++ -*- -/* \file PosIterator.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Alfredo Braunstein - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef POSITERATOR_H -#define POSITERATOR_H - -#include "ParagraphList_fwd.h" - -#include "iterators.h" - -#include "support/types.h" - -#include - - -class BufferView; - -struct PosIteratorItem { - PosIteratorItem(ParagraphList * pl, - ParagraphList::iterator pit, - lyx::pos_type pos, - int index = 0) - : pl(pl), pit(pit), pos(pos), index(index) {}; - ParagraphList * pl; - ParagraphList::iterator pit; - lyx::pos_type pos; - int index; -}; - - -class PosIterator : public std::iterator< - std::bidirectional_iterator_tag, - ParagraphList::value_type> { -public: - // Creates a singular. - PosIterator() {}; - - PosIterator(BufferView & bv); - PosIterator(ParagraphList * pl, ParagraphList::iterator pit, - lyx::pos_type pos); - PosIterator(ParIterator const & par, lyx::pos_type pos); - PosIterator & operator++(); - PosIterator & operator--(); - friend bool operator==(PosIterator const &, PosIterator const &); - - ParagraphList::iterator pit() const { return stack_.back().pit; } - lyx::pos_type pos() const { return stack_.back().pos; } - bool at_end() const; - InsetBase * inset() const; - friend ParIterator::ParIterator(PosIterator const &); -private: - void setFrom(ParIterator const & par, lyx::pos_type pos); - // This is conceptually a stack, - // but we need random access sometimes. - std::vector stack_; -}; - - -bool operator==(PosIterator const &, PosIterator const &); - - -inline -bool operator!=(PosIterator const & lhs, PosIterator const & rhs) -{ - return !(lhs == rhs); -} - -#endif diff --git a/src/buffer.C b/src/buffer.C index 273ece0f6e..a84ca170f6 100644 --- a/src/buffer.C +++ b/src/buffer.C @@ -43,7 +43,6 @@ #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" -#include "PosIterator.h" #include "sgml.h" #include "texrow.h" #include "undo.h" @@ -76,10 +75,8 @@ #include -#ifdef HAVE_LOCALE -#endif - using lyx::pos_type; +using lyx::par_type; using lyx::support::AddName; using lyx::support::atoi; @@ -202,7 +199,6 @@ Buffer::Buffer(string const & file, bool ronly) : pimpl_(new Impl(*this, file, ronly)) { lyxerr[Debug::INFO] << "Buffer::Buffer()" << endl; - lyxerr << "Buffer::Buffer()" << endl; } @@ -426,8 +422,6 @@ int Buffer::readHeader(LyXLex & lex) // Returns false if "\end_document" is not read (Asger) bool Buffer::readBody(LyXLex & lex) { - bool the_end_read = false; - if (paragraphs().empty()) { readHeader(lex); if (!params().getLyXTextClass().load()) { @@ -446,30 +440,28 @@ bool Buffer::readBody(LyXLex & lex) tmpbuf.readHeader(lex); } - if (text().read(*this, lex)) - the_end_read = true; - - return the_end_read; + return text().read(*this, lex); } // needed to insert the selection -void Buffer::insertStringAsLines(ParagraphList::iterator & par, pos_type & pos, - LyXFont const & fn, string const & str) +void Buffer::insertStringAsLines(ParagraphList & pars, + par_type & par, pos_type & pos, + LyXFont const & fn, string const & str) { - LyXLayout_ptr const & layout = par->layout(); + LyXLayout_ptr const & layout = pars[par].layout(); LyXFont font = fn; - par->checkInsertChar(font); + pars[par].checkInsertChar(font); // insert the string, don't insert doublespace bool space_inserted = true; - bool autobreakrows = !par->inInset() || - static_cast(par->inInset())->getAutoBreakRows(); + bool autobreakrows = !pars[par].inInset() || + static_cast(pars[par].inInset())->getAutoBreakRows(); for(string::const_iterator cit = str.begin(); cit != str.end(); ++cit) { if (*cit == '\n') { - if (autobreakrows && (!par->empty() || par->allowEmpty())) { + if (autobreakrows && (!pars[par].empty() || pars[par].allowEmpty())) { breakParagraph(params(), paragraphs(), par, pos, layout->isEnvironment()); ++par; @@ -480,18 +472,18 @@ void Buffer::insertStringAsLines(ParagraphList::iterator & par, pos_type & pos, } // do not insert consecutive spaces if !free_spacing } else if ((*cit == ' ' || *cit == '\t') && - space_inserted && !par->isFreeSpacing()) { + space_inserted && !pars[par].isFreeSpacing()) { continue; } else if (*cit == '\t') { - if (!par->isFreeSpacing()) { + if (!pars[par].isFreeSpacing()) { // tabs are like spaces here - par->insertChar(pos, ' ', font); + pars[par].insertChar(pos, ' ', font); ++pos; space_inserted = true; } else { const pos_type n = 8 - pos % 8; for (pos_type i = 0; i < n; ++i) { - par->insertChar(pos, ' ', font); + pars[par].insertChar(pos, ' ', font); ++pos; } space_inserted = true; @@ -501,7 +493,7 @@ void Buffer::insertStringAsLines(ParagraphList::iterator & par, pos_type & pos, continue; } else { // just insert the character - par->insertChar(pos, *cit, font); + pars[par].insertChar(pos, *cit, font); ++pos; space_inserted = (*cit == ' '); } @@ -520,7 +512,7 @@ bool Buffer::readFile(string const & filename) // remove dummy empty par paragraphs().clear(); - bool ret = readFile(filename, paragraphs().end()); + bool ret = readFile(filename, paragraphs().size()); // After we have read a file, we must ensure that the buffer // language is set and used in the gui. @@ -531,7 +523,7 @@ bool Buffer::readFile(string const & filename) } -bool Buffer::readFile(string const & filename, ParagraphList::iterator pit) +bool Buffer::readFile(string const & filename, par_type pit) { LyXLex lex(0, 0); lex.setFile(filename); @@ -551,8 +543,7 @@ void Buffer::fully_loaded(bool value) } -bool Buffer::readFile(LyXLex & lex, string const & filename, - ParagraphList::iterator pit) +bool Buffer::readFile(LyXLex & lex, string const & filename, par_type pit) { BOOST_ASSERT(!filename.empty()); @@ -1300,9 +1291,9 @@ bool Buffer::isMultiLingual() const void Buffer::inset_iterator::setParagraph() { - while (pit != pend) { - it = pit->insetlist.begin(); - if (it != pit->insetlist.end()) + while (pit != pars_->size()) { + it = (*pars_)[pit].insetlist.begin(); + if (it != (*pars_)[pit].insetlist.end()) return; ++pit; } @@ -1349,41 +1340,27 @@ bool Buffer::hasParWithID(int id) const } -PosIterator Buffer::pos_iterator_begin() -{ - return PosIterator(¶graphs(), paragraphs().begin(), 0); -} - - -PosIterator Buffer::pos_iterator_end() -{ - return PosIterator(¶graphs(), paragraphs().end(), 0); -} - - ParIterator Buffer::par_iterator_begin() { - return ParIterator(paragraphs().begin(), paragraphs()); + return ParIterator(0, paragraphs()); } ParIterator Buffer::par_iterator_end() { - return ParIterator(paragraphs().end(), paragraphs()); + return ParIterator(paragraphs().size(), paragraphs()); } ParConstIterator Buffer::par_iterator_begin() const { - ParagraphList const & pars = paragraphs(); - return ParConstIterator(const_cast(pars).begin(), pars); + return ParConstIterator(0, paragraphs()); } ParConstIterator Buffer::par_iterator_end() const { - ParagraphList const & pars = paragraphs(); - return ParConstIterator(const_cast(pars).end(), pars); + return ParConstIterator(paragraphs().size(), paragraphs()); } @@ -1486,13 +1463,8 @@ void Buffer::setParentName(string const & name) } -Buffer::inset_iterator::inset_iterator() - : pit(), pend() -{} - - -Buffer::inset_iterator::inset_iterator(base_type p, base_type e) - : pit(p), pend(e) +Buffer::inset_iterator::inset_iterator(ParagraphList & pars, base_type p) + : pit(p), pars_(&pars) { setParagraph(); } @@ -1500,35 +1472,35 @@ Buffer::inset_iterator::inset_iterator(base_type p, base_type e) Buffer::inset_iterator Buffer::inset_iterator_begin() { - return inset_iterator(paragraphs().begin(), paragraphs().end()); + return inset_iterator(paragraphs(), 0); } Buffer::inset_iterator Buffer::inset_iterator_end() { - return inset_iterator(paragraphs().end(), paragraphs().end()); + return inset_iterator(paragraphs(), paragraphs().size()); } Buffer::inset_iterator Buffer::inset_const_iterator_begin() const { ParagraphList & pars = const_cast(paragraphs()); - return inset_iterator(pars.begin(), pars.end()); + return inset_iterator(pars, 0); } Buffer::inset_iterator Buffer::inset_const_iterator_end() const { ParagraphList & pars = const_cast(paragraphs()); - return inset_iterator(pars.end(), pars.end()); + return inset_iterator(pars, pars.size()); } Buffer::inset_iterator & Buffer::inset_iterator::operator++() { - if (pit != pend) { + if (pit != pars_->size()) { ++it; - if (it == pit->insetlist.end()) { + if (it == (*pars_)[pit].insetlist.end()) { ++pit; setParagraph(); } @@ -1557,7 +1529,7 @@ Buffer::inset_iterator::pointer Buffer::inset_iterator::operator->() } -ParagraphList::iterator Buffer::inset_iterator::getPar() const +lyx::par_type Buffer::inset_iterator::getPar() const { return pit; } @@ -1572,8 +1544,7 @@ lyx::pos_type Buffer::inset_iterator::getPos() const bool operator==(Buffer::inset_iterator const & iter1, Buffer::inset_iterator const & iter2) { - return iter1.pit == iter2.pit - && (iter1.pit == iter1.pend || iter1.it == iter2.it); + return iter1.pit == iter2.pit && iter1.it == iter2.it; } diff --git a/src/buffer.h b/src/buffer.h index 0a82f73b96..b14fe23584 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -13,7 +13,6 @@ #define BUFFER_H #include "InsetList.h" -#include "ParagraphList_fwd.h" #include "support/limited_stack.h" #include "support/types.h" @@ -42,9 +41,9 @@ class LaTeXFeatures; class Language; class Messages; class OutputParams; -class ParIterator; -class PosIterator; +class ParagraphList; class ParConstIterator; +class ParIterator; class TeXErrors; class TexRow; class Undo; @@ -87,7 +86,7 @@ public: /// load a new file bool readFile(std::string const & filename); - bool readFile(std::string const & filename, ParagraphList::iterator pit); + bool readFile(std::string const & filename, lyx::par_type pit); /// read the header, returns number of unknown tokens int readHeader(LyXLex & lex); @@ -99,8 +98,9 @@ public: bool readBody(LyXLex &); /// - void insertStringAsLines(ParagraphList::iterator &, lyx::pos_type &, - LyXFont const &, std::string const &); + void insertStringAsLines(ParagraphList & plist, + lyx::par_type &, lyx::pos_type &, + LyXFont const &, std::string const &); /// ParIterator getParFromID(int id) const; /// do we have a paragraph with this id? @@ -288,14 +288,10 @@ public: typedef ptrdiff_t difference_type; typedef InsetBase * pointer; typedef InsetBase & reference; - typedef ParagraphList::iterator base_type; + typedef lyx::par_type base_type; /// - inset_iterator(); - /// - inset_iterator(base_type p, base_type e); - /// - inset_iterator(base_type p, lyx::pos_type pos, base_type e); + inset_iterator(ParagraphList & pars, base_type p); /// prefix ++ inset_iterator & operator++(); @@ -307,7 +303,7 @@ public: pointer operator->(); /// - ParagraphList::iterator getPar() const; + lyx::par_type getPar() const; /// lyx::pos_type getPos() const; /// @@ -318,11 +314,11 @@ public: /// void setParagraph(); /// - ParagraphList::iterator pit; - /// - ParagraphList::iterator pend; + lyx::par_type pit; /// InsetList::iterator it; + public: + ParagraphList * pars_; }; /// return an iterator to all *top-level* insets in the buffer @@ -337,10 +333,6 @@ public: /// return the const end of all *top-level* insets in the buffer inset_iterator inset_const_iterator_end() const; - /// - PosIterator pos_iterator_begin(); - /// - PosIterator pos_iterator_end(); /// ParIterator par_iterator_begin(); /// @@ -369,7 +361,7 @@ private: \return \c false if method fails. */ bool readFile(LyXLex &, std::string const & filename, - ParagraphList::iterator pit); + lyx::par_type pit); bool do_writeFile(std::ostream & ofs) const; diff --git a/src/bufferlist.C b/src/bufferlist.C index 8c19a3928f..29fabe9d84 100644 --- a/src/bufferlist.C +++ b/src/bufferlist.C @@ -22,6 +22,7 @@ #include "lyx_main.h" #include "output_latex.h" #include "paragraph.h" +#include "ParagraphList_fwd.h" #include "frontends/Alert.h" diff --git a/src/cursor.C b/src/cursor.C index 761bb0c5e7..1d29a5dbb2 100644 --- a/src/cursor.C +++ b/src/cursor.C @@ -15,6 +15,7 @@ #include "BufferView.h" #include "buffer.h" #include "cursor.h" +#include "CutAndPaste.h" #include "debug.h" #include "dispatchresult.h" #include "encoding.h" @@ -45,6 +46,8 @@ #include +using lyx::par_type; + using std::string; using std::vector; using std::endl; @@ -91,7 +94,6 @@ void LCursor::reset(InsetBase & inset) clear(); push_back(CursorSlice(inset)); anchor_.clear(); - anchor_.push_back(CursorSlice(inset)); cached_y_ = 0; clearTargetX(); selection_ = false; @@ -109,10 +111,10 @@ 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(); - //lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl; FuncRequest cmd = cmd0; LCursor safe = *this; @@ -133,15 +135,21 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0) } // it completely to get a 'bomb early' behaviour in case this // object will be used again. - if (!disp_.dispatched()) + if (!disp_.dispatched()) { + lyxerr << "RESTORING OLD CURSOR!" << endl; operator=(safe); + } return disp_; } bool LCursor::getStatus(FuncRequest const & cmd, FuncStatus & status) { + // This is, of course, a mess. Better create a new doc iterator and use + // this in Inset::getStatus. This might require an additional + // BufferView * arg, though (which should be avoided) LCursor safe = *this; + bool res = false; for ( ; size(); pop()) { //lyxerr << "\nLCursor::getStatus: cmd: " << cmd << endl << *this << endl; BOOST_ASSERT(pos() <= lastpos()); @@ -152,11 +160,13 @@ 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. - if (inset().getStatus(*this, cmd, status)) + if (inset().getStatus(*this, cmd, status)) { + res = true; break; + } } operator=(safe); - return true; + return res; } @@ -170,7 +180,6 @@ void LCursor::pop() { BOOST_ASSERT(size() >= 1); pop_back(); - anchor_.pop_back(); } @@ -306,12 +315,14 @@ bool LCursor::posRight() CursorSlice & LCursor::anchor() { + BOOST_ASSERT(!anchor_.empty()); return anchor_.back(); } CursorSlice const & LCursor::anchor() const { + BOOST_ASSERT(!anchor_.empty()); return anchor_.back(); } @@ -324,15 +335,6 @@ CursorSlice const & LCursor::selBegin() const } -CursorSlice & LCursor::selBegin() -{ - if (!selection()) - return back(); - // can't use std::min as this returns a const ref - return anchor() < back() ? anchor() : back(); -} - - CursorSlice const & LCursor::selEnd() const { if (!selection()) @@ -341,12 +343,19 @@ CursorSlice const & LCursor::selEnd() const } -CursorSlice & LCursor::selEnd() +DocumentIterator LCursor::selectionBegin() const { if (!selection()) - return back(); - // can't use std::min as this returns a const ref - return anchor() > back() ? anchor() : back(); + return *this; + return anchor() < back() ? anchor_ : *this; +} + + +DocumentIterator LCursor::selectionEnd() const +{ + if (!selection()) + return *this; + return anchor() > back() ? anchor_ : *this; } @@ -551,9 +560,19 @@ void LCursor::selClearOrDel() std::ostream & operator<<(std::ostream & os, LCursor const & cur) { - for (size_t i = 0, n = cur.size(); i != n; ++i) - os << " " << cur.operator[](i) << " | " << cur.anchor_[i] << "\n"; - os << " selection: " << cur.selection_ << endl; + for (size_t i = 0, n = cur.size(); i != n; ++i) { + os << " " << cur.operator[](i) << " | "; + if (i < cur.anchor_.size()) + os << cur.anchor_[i]; + else + os << "-------------------------------"; + os << "\n"; + } + for (size_t i = cur.size(), n = cur.anchor_.size(); i < n; ++i) { + os << "------------------------------- | " << cur.anchor_[i] << "\n"; + } + os << " selection: " << cur.selection_ + << " x_target: " << cur.x_target_ << endl; return os; } @@ -602,7 +621,7 @@ bool LCursor::openable(MathAtom const & t) const return true; // we can't move into anything new during selection - if (depth() == anchor_.size()) + if (depth() >= anchor_.size()) return false; if (!ptr_cmp(t.nucleus(), &anchor_[depth()].inset())) return false; @@ -1092,8 +1111,7 @@ bool LCursor::goUpDown(bool up) bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh) { BOOST_ASSERT(!empty()); - ParagraphList::iterator beg; - ParagraphList::iterator end; + par_type beg, end; CursorSlice bottom = operator[](0); LyXText * text = bottom.text(); BOOST_ASSERT(text); @@ -1101,11 +1119,11 @@ bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh) DocumentIterator it(bv().buffer()->inset()); DocumentIterator et; - lyxerr << "x: " << x << " y: " << y << endl; - lyxerr << "xlow: " << xlow << " ylow: " << ylow << endl; - lyxerr << "xhigh: " << xhigh << " yhigh: " << yhigh << endl; + //lyxerr << "x: " << x << " y: " << y << endl; + //lyxerr << "xlow: " << xlow << " ylow: " << ylow << endl; + //lyxerr << "xhigh: " << xhigh << " yhigh: " << yhigh << endl; - it.par() = text->parOffset(beg); + it.par() = beg; //et.par() = text->parOffset(end); double best_dist = 10e10; @@ -1119,11 +1137,11 @@ bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh) 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 << "xo: " << xo << " yo: " << yo << " d: " << d << endl; + //lyxerr << "xo: " << xo << " yo: " << yo << " d: " << d << endl; // '<=' in order to take the last possible position // this is important for clicking behind \sum in e.g. '\sum_i a' if (d <= best_dist) { - lyxerr << "*" << endl; + //lyxerr << "*" << endl; best_dist = d; best_cursor = it; } @@ -1131,7 +1149,7 @@ bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh) } } - lyxerr << "best_dist: " << best_dist << " cur:\n" << best_cursor << endl; + //lyxerr << "best_dist: " << best_dist << " cur:\n" << best_cursor << endl; if (best_dist < 1e10) setCursor(best_cursor, false); return best_dist < 1e10; @@ -1238,27 +1256,29 @@ string LCursor::selectionAsString(bool label) const if (inTexted()) { Buffer const & buffer = *bv().buffer(); + ParagraphList & pars = text()->paragraphs(); // should be const ... - ParagraphList::iterator startpit = text()->getPar(selBegin()); - ParagraphList::iterator endpit = text()->getPar(selEnd()); + par_type startpit = selBegin().par(); + par_type endpit = selEnd().par(); size_t const startpos = selBegin().pos(); size_t const endpos = selEnd().pos(); if (startpit == endpit) - return startpit->asString(buffer, startpos, endpos, label); + return pars[startpit].asString(buffer, startpos, endpos, label); // First paragraph in selection - string result = - startpit->asString(buffer, startpos, startpit->size(), label) + "\n\n"; + string result = pars[startpit]. + asString(buffer, startpos, pars[startpit].size(), label) + "\n\n"; // The paragraphs in between (if any) - ParagraphList::iterator pit = startpit; - for (++pit; pit != endpit; ++pit) - result += pit->asString(buffer, 0, pit->size(), label) + "\n\n"; + for (par_type pit = startpit + 1; pit != endpit; ++pit) { + Paragraph & par = pars[pit]; + result += par.asString(buffer, 0, par.size(), label) + "\n\n"; + } // Last paragraph in selection - result += endpit->asString(buffer, 0, endpos, label); + result += pars[endpit].asString(buffer, 0, endpos, label); return result; } @@ -1283,27 +1303,6 @@ string LCursor::currentState() } -// only used by the spellchecker -void LCursor::replaceWord(string const & replacestring) -{ - LyXText * t = text(); - BOOST_ASSERT(t); - - t->replaceSelectionWithString(*this, replacestring); - t->setSelectionRange(*this, replacestring.length()); - - // Go back so that replacement string is also spellchecked - for (string::size_type i = 0; i < replacestring.length() + 1; ++i) - t->cursorLeft(*this); -} - - -void LCursor::update() -{ - bv().update(); -} - - string LCursor::getPossibleLabel() { return inMathed() ? "eq:" : text()->getPossibleLabel(*this); @@ -1324,9 +1323,8 @@ Encoding const * LCursor::getEncoding() const 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())); + LyXFont font = text.getPar(sl.par()).getFont( + bv().buffer()->params(), sl.pos(), outerFont(sl.par(), text.paragraphs())); return font.language()->encoding(); } diff --git a/src/cursor.h b/src/cursor.h index 44ef8b80a4..ec1002aebc 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -73,13 +73,13 @@ public: /// void clearSelection(); /// access start of selection - CursorSlice & selBegin(); - /// access start of selection CursorSlice const & selBegin() const; /// access end of selection - CursorSlice & selEnd(); - /// access end of selection CursorSlice const & selEnd() const; + /// access start of selection + DocumentIterator selectionBegin() const; + /// access start of selection + DocumentIterator selectionEnd() const; /// std::string grabSelection(); /// diff --git a/src/cursor_slice.C b/src/cursor_slice.C index 3cf9cdffa9..a537aee3aa 100644 --- a/src/cursor_slice.C +++ b/src/cursor_slice.C @@ -62,42 +62,6 @@ size_t CursorSlice::ncols() const } -CursorSlice::idx_type CursorSlice::idx() const -{ - return idx_; -} - - -CursorSlice::idx_type & CursorSlice::idx() -{ - return idx_; -} - - -CursorSlice::par_type CursorSlice::par() const -{ - return par_; -} - - -CursorSlice::par_type & CursorSlice::par() -{ - return par_; -} - - -CursorSlice::pos_type CursorSlice::pos() const -{ - return pos_; -} - - -CursorSlice::pos_type & CursorSlice::pos() -{ - return pos_; -} - - CursorSlice::pos_type CursorSlice::lastpos() const { BOOST_ASSERT(inset_); @@ -105,18 +69,6 @@ CursorSlice::pos_type CursorSlice::lastpos() const } -bool CursorSlice::boundary() const -{ - return boundary_; -} - - -bool & CursorSlice::boundary() -{ - return boundary_; -} - - CursorSlice::row_type CursorSlice::row() const { BOOST_ASSERT(asMathInset()); @@ -163,7 +115,7 @@ Paragraph & CursorSlice::paragraph() { // access to the main lyx text must be handled in the cursor BOOST_ASSERT(text()); - return *text()->getPar(par_); + return text()->getPar(par_); } @@ -171,7 +123,7 @@ Paragraph const & CursorSlice::paragraph() const { // access to the main lyx text must be handled in the cursor BOOST_ASSERT(text()); - return *text()->getPar(par_); + return text()->getPar(par_); } diff --git a/src/cursor_slice.h b/src/cursor_slice.h index 298e0d836c..f50820549a 100644 --- a/src/cursor_slice.h +++ b/src/cursor_slice.h @@ -17,8 +17,6 @@ #ifndef CURSORSLICE_H #define CURSORSLICE_H -#include "ParagraphList_fwd.h" - #include "support/types.h" #include @@ -45,7 +43,7 @@ public: /// type for cell number in inset typedef size_t idx_type; /// type for paragraph numbers positions within a cell - typedef lyx::paroffset_type par_type; + typedef lyx::par_type par_type; /// type for cursor positions within a cell typedef lyx::pos_type pos_type; /// type for row indices @@ -61,23 +59,23 @@ public: /// the current inset InsetBase & inset() const { return *inset_; } /// return the cell this cursor is in - idx_type idx() const; + idx_type idx() const { return idx_; } /// return the cell this cursor is in - idx_type & idx(); + idx_type & idx() { return idx_; } /// return the last cell in this inset idx_type lastidx() const { return nargs() - 1; } /// return the paragraph this cursor is in - par_type par() const; + par_type par() const { return par_; } /// set the paragraph this cursor is in - par_type & par(); + par_type & par() { return par_; } /// increments the paragraph this cursor is in void incrementPar(); /// increments the paragraph this cursor is in void decrementPar(); /// return the position within the paragraph - pos_type pos() const; + pos_type pos() const { return pos_; } /// return the position within the paragraph - pos_type & pos(); + pos_type & pos() { return pos_; } /// return the last position within the paragraph pos_type lastpos() const; /// return the number of embedded cells @@ -95,9 +93,9 @@ public: /// texted specific stuff /// /// see comment for the member - bool boundary() const; + bool boundary() const { return boundary_; } /// see comment for the member - bool & boundary(); + bool & boundary() { return boundary_; } /// LyXText * text() const; /// diff --git a/src/dociterator.C b/src/dociterator.C index e1667ec914..d4d51819ef 100644 --- a/src/dociterator.C +++ b/src/dociterator.C @@ -11,6 +11,8 @@ #include +using std::endl; + DocumentIterator::DocumentIterator() {} @@ -24,6 +26,7 @@ DocumentIterator::DocumentIterator(InsetBase & inset) InsetBase * DocumentIterator::nextInset() { + BOOST_ASSERT(!empty()); if (pos() == lastpos()) return 0; if (inMathed()) @@ -34,6 +37,7 @@ InsetBase * DocumentIterator::nextInset() InsetBase * DocumentIterator::prevInset() { + BOOST_ASSERT(!empty()); if (pos() == 0) return 0; if (inMathed()) @@ -44,6 +48,7 @@ InsetBase * DocumentIterator::prevInset() InsetBase const * DocumentIterator::prevInset() const { + BOOST_ASSERT(!empty()); if (pos() == 0) return 0; if (inMathed()) @@ -54,6 +59,7 @@ InsetBase const * DocumentIterator::prevInset() const MathAtom const & DocumentIterator::prevAtom() const { + BOOST_ASSERT(!empty()); BOOST_ASSERT(pos() > 0); return cell()[pos() - 1]; } @@ -61,6 +67,7 @@ MathAtom const & DocumentIterator::prevAtom() const MathAtom & DocumentIterator::prevAtom() { + BOOST_ASSERT(!empty()); BOOST_ASSERT(pos() > 0); return cell()[pos() - 1]; } @@ -68,6 +75,7 @@ MathAtom & DocumentIterator::prevAtom() MathAtom const & DocumentIterator::nextAtom() const { + BOOST_ASSERT(!empty()); BOOST_ASSERT(pos() < lastpos()); return cell()[pos()]; } @@ -75,6 +83,7 @@ MathAtom const & DocumentIterator::nextAtom() const MathAtom & DocumentIterator::nextAtom() { + BOOST_ASSERT(!empty()); BOOST_ASSERT(pos() < lastpos()); return cell()[pos()]; } @@ -82,6 +91,7 @@ MathAtom & DocumentIterator::nextAtom() LyXText * DocumentIterator::text() const { + BOOST_ASSERT(!empty()); return top().text(); } @@ -225,11 +235,15 @@ InsetBase * DocumentIterator::innerInsetOfType(int code) const void DocumentIterator::forwardPos() { CursorSlice & top = back(); - //lyxerr << "XXX\n" << *this << std::endl; + //lyxerr << "XXX\n" << *this << endl; + + // this is used twice and shows up in the profiler! + pos_type const lastp = lastpos(); // move into an inset to the right if possible InsetBase * n = 0; - if (top.pos() != lastpos()) { + + if (top.pos() != lastp) { // this is impossible for pos() == size() if (inMathed()) { n = (top.cell().begin() + top.pos())->nucleus(); @@ -240,56 +254,65 @@ void DocumentIterator::forwardPos() } if (n && n->isActive()) { - //lyxerr << "... descend" << std::endl; + //lyxerr << "... descend" << endl; push_back(CursorSlice(*n)); return; } - // otherwise move on one cell back if possible - if (top.pos() < lastpos()) { - //lyxerr << "... next pos" << std::endl; + // otherwise move on one position if possible + if (top.pos() < lastp) { + //lyxerr << "... next pos" << endl; ++top.pos(); return; } - //lyxerr << "... no next pos" << std::endl; + //lyxerr << "... no next pos" << endl; - // otherwise move on one cell back if possible + // otherwise move on one paragraph if possible if (top.par() < lastpar()) { - //lyxerr << "... next par" << std::endl; + //lyxerr << "... next par" << endl; ++top.par(); top.pos() = 0; return; } - //lyxerr << "... no next par" << std::endl; + //lyxerr << "... no next par" << endl; // otherwise try to move on one cell if possible - // [stupid hack for necessary for MathScriptInset] - while (top.idx() < lastidx()) { - //lyxerr << "... next idx" << std::endl; + if (top.idx() < lastidx()) { + //lyxerr << "... next idx" << endl; ++top.idx(); top.par() = 0; top.pos() = 0; - if (top.inset().validCell(top.idx())) { - //lyxerr << " ... ok" << std::endl; - return; - } + return; } - //lyxerr << "... no next idx" << std::endl; + //lyxerr << "... no next idx" << endl; - // otherwise leave inset an jump over inset as a whole + // otherwise leave inset and jump over inset as a whole pop_back(); // 'top' is invalid now... if (size()) ++back().pos(); - //else - // lyxerr << "... no slice left" << std::endl; +} + + +void DocumentIterator::forwardChar() +{ + forwardPos(); + while (size() != 0 && pos() == lastpos()) + forwardPos(); +} + + +void DocumentIterator::backwardChar() +{ + lyxerr << "not implemented" << endl; + BOOST_ASSERT(false); } void DocumentIterator::forwardPar() { CursorSlice & top = back(); - lyxerr << "XXX " << *this << std::endl; + lyxerr << "XXX " << *this << endl; // move into an inset to the right if possible InsetBase * n = 0; @@ -304,38 +327,34 @@ void DocumentIterator::forwardPar() } if (n && n->isActive()) { - lyxerr << "... descend" << std::endl; + lyxerr << "... descend" << endl; push_back(CursorSlice(*n)); return; } // otherwise move on one cell back if possible if (top.pos() < lastpos()) { - lyxerr << "... next pos" << std::endl; + lyxerr << "... next pos" << endl; ++top.pos(); return; } // otherwise move on one cell back if possible if (top.par() < lastpar()) { - lyxerr << "... next par" << std::endl; + lyxerr << "... next par" << endl; ++top.par(); top.pos() = 0; return; } // otherwise try to move on one cell if possible - // [stupid hack for necessary for MathScriptInset] while (top.idx() < top.lastidx()) { lyxerr << "... next idx" - << " was: " << top.idx() << " max: " << top.lastidx() << std::endl; + << " was: " << top.idx() << " max: " << top.lastidx() << endl; ++top.idx(); top.par() = 0; top.pos() = 0; - if (top.inset().validCell(top.idx())) { - lyxerr << " ... ok" << std::endl; - return; - } + return; } // otherwise leave inset an jump over inset as a whole @@ -369,7 +388,7 @@ DocumentIterator StableDocumentIterator::asDocumentIterator(InsetBase * inset) const { // this function re-creates the cache of inset pointers - //lyxerr << "converting:\n" << *this << std::endl; + //lyxerr << "converting:\n" << *this << endl; DocumentIterator dit; for (size_t i = 0, n = data_.size(); i != n; ++i) { dit.push_back(data_[i]); @@ -377,7 +396,7 @@ StableDocumentIterator::asDocumentIterator(InsetBase * inset) const if (i + 1 != n) inset = dit.nextInset(); } - //lyxerr << "convert:\n" << *this << " to:\n" << dit << std::endl; + //lyxerr << "convert:\n" << *this << " to:\n" << dit << endl; return dit; } diff --git a/src/dociterator.h b/src/dociterator.h index e44c8fd1e8..c2663fb2ff 100644 --- a/src/dociterator.h +++ b/src/dociterator.h @@ -61,6 +61,10 @@ public: CursorSlice & top() { return back(); } /// access to tip CursorSlice const & top() const { return back(); } + /// access to outermost slice + CursorSlice & bottom() { return front(); } + /// access to outermost slicetip + CursorSlice const & bottom() const { return front(); } /// how many nested insets do we have? size_t depth() const { return size(); } /// the containing inset @@ -155,14 +159,27 @@ public: // // elementary moving // - /// move on one position + /// move on one logical position void forwardPos(); + /// move on one physical character or inset + void forwardChar(); /// move on one paragraph void forwardPar(); /// move on one cell void forwardIdx(); /// move on one inset void forwardInset(); + /// move backward one logical position + void backwardPos(); + /// move backward one physical character or inset + void backwardChar(); + /// move backward one paragraph + void backwardPar(); + /// move backward one cell + void backwardIdx(); + /// move backward one inset + void backwardInset(); + /// output friend std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur); diff --git a/src/errorlist.C b/src/errorlist.C index d829f04c4f..89bc1c1ee2 100644 --- a/src/errorlist.C +++ b/src/errorlist.C @@ -24,5 +24,5 @@ ErrorItem::ErrorItem(string const & error_, string const & description_, ErrorItem::ErrorItem() - : par_id(-1), pos_start(0), pos_end(0) + : par_id(-1), pos_start(0), pos_end(0) {} diff --git a/src/errorlist.h b/src/errorlist.h index 52e79a5ee2..1e5f7a9b32 100644 --- a/src/errorlist.h +++ b/src/errorlist.h @@ -31,6 +31,7 @@ struct ErrorItem { ErrorItem(); }; + class ErrorList : private std::vector { public: @@ -46,6 +47,4 @@ public: using std::vector::const_iterator; }; - - #endif diff --git a/src/factory.C b/src/factory.C index 727939de48..10e11708e8 100644 --- a/src/factory.C +++ b/src/factory.C @@ -185,7 +185,6 @@ InsetBase * createInset(BufferView * bv, FuncRequest const & cmd) UpdatableInset * up = bv->cursor().inset().asUpdatableInset(); if (!up) { auto_ptr inset(new InsetCaption(params)); - inset->setOwner(up); inset->setAutoBreakRows(true); inset->setDrawFrame(InsetText::LOCKED); inset->setFrameColor(LColor::captionframe); diff --git a/src/frontends/controllers/ControlDocument.C b/src/frontends/controllers/ControlDocument.C index cbab160ad2..c5c51c5d99 100644 --- a/src/frontends/controllers/ControlDocument.C +++ b/src/frontends/controllers/ControlDocument.C @@ -154,7 +154,7 @@ void ControlDocument::classApply() lv_.message(_("Converting document to new document class...")); ErrorList el; - CutAndPaste::SwitchLayoutsBetweenClasses(old_class, new_class, + lyx::cap::SwitchLayoutsBetweenClasses(old_class, new_class, lv_.buffer()->paragraphs(), el); bufferErrors(*buffer(), el); diff --git a/src/frontends/controllers/ControlErrorList.C b/src/frontends/controllers/ControlErrorList.C index b31ba80eb5..44fcb2e2b6 100644 --- a/src/frontends/controllers/ControlErrorList.C +++ b/src/frontends/controllers/ControlErrorList.C @@ -17,8 +17,6 @@ #include "iterators.h" #include "lyxtext.h" #include "paragraph.h" -#include "PosIterator.h" - using std::endl; using std::string; @@ -73,6 +71,9 @@ void ControlErrorList::goTo(int item) lyx::pos_type const range = end - start; // Now make the selection. +#warning FIXME (goto error) +#if 0 PosIterator const pos(pit, start); kernel().bufferview()->putSelectionAt(pos, range, false); +#endif } diff --git a/src/frontends/controllers/ControlSpellchecker.C b/src/frontends/controllers/ControlSpellchecker.C index 46beabd4ab..c660e717d1 100644 --- a/src/frontends/controllers/ControlSpellchecker.C +++ b/src/frontends/controllers/ControlSpellchecker.C @@ -17,11 +17,11 @@ #include "bufferparams.h" #include "BufferView.h" #include "cursor.h" +#include "CutAndPaste.h" #include "debug.h" #include "gettext.h" #include "language.h" #include "lyxrc.h" -#include "PosIterator.h" #include "paragraph.h" #include "ispell.h" @@ -149,41 +149,40 @@ void ControlSpellchecker::endSession() namespace { - -bool isLetter(PosIterator & cur) +bool isLetter(DocumentIterator const & cur) { - return !cur.at_end() - && cur.pit()->isLetter(cur.pos()) - && !isDeletedText(*cur.pit(), cur.pos()) - && (!cur.inset() || cur.inset()->allowSpellCheck()); + return !cur.empty() + && cur.paragraph().isLetter(cur.pos()) + && !isDeletedText(cur.paragraph(), cur.pos()); + //&& (!cur.nextInset() || cur.nextInset()->allowSpellCheck()); } -WordLangTuple nextWord(PosIterator & cur, PosIterator const & end, - PosIterator::difference_type & progress, - BufferParams & bp) +WordLangTuple nextWord(DocumentIterator & cur, ptrdiff_t & progress, + BufferParams & bp) { // skip until we have real text (will jump paragraphs) - for (; cur != end && !isLetter(cur); ++cur, ++progress); + for (; cur.size() && !isLetter(cur); cur.forwardChar()); + ++progress; - if (cur == end) + // hit end + if (cur.empty()) return WordLangTuple(string(), string()); - string lang_code = cur.pit()->getFontSettings(bp, cur.pos()).language()->code(); + string lang_code = cur.paragraph(). + getFontSettings(bp, cur.pos()).language()->code(); string str; // and find the end of the word (insets like optional hyphens // and ligature break are part of a word) - for (; cur != end && isLetter(cur); ++cur, ++progress) { - if (!cur.pit()->isInset(cur.pos())) - str += cur.pit()->getChar(cur.pos()); + for (; cur.size() && isLetter(cur); cur.forwardChar(), ++progress) { + if (!cur.paragraph().isInset(cur.pos())) + str += cur.paragraph().getChar(cur.pos()); } return WordLangTuple(str, lang_code); } - -} //namespace anon - +} // namespace anon @@ -193,18 +192,25 @@ void ControlSpellchecker::check() SpellBase::Result res = SpellBase::OK; - PosIterator cur(*bufferview()); - PosIterator const beg = buffer()->pos_iterator_begin(); - PosIterator const end = buffer()->pos_iterator_end(); + DocumentIterator cur = bufferview()->cursor(); - PosIterator::difference_type start = distance(beg, cur); - PosIterator::difference_type const total = start + distance(cur, end); + // a rough estimate should be sufficient: + //DocumentIterator::difference_type start = distance(beg, cur); + //DocumentIterator::difference_type const total = start + distance(cur, end); - if (cur != buffer()->pos_iterator_begin()) - for (; cur != end && isLetter(cur); ++cur, ++start); + ptrdiff_t start = 0, total = 0; + DocumentIterator it = DocumentIterator(buffer()->inset()); + for (start = 0; it != cur; it.forwardPos()) + ++start; + + for (total = start; it.size(); it.forwardPos()) + ++total; + + for (; cur.size() && isLetter(cur); cur.forwardPos()) + ++start; while (res == SpellBase::OK || res == SpellBase::IGNORE) { - word_ = nextWord(cur, end, start, buffer()->params()); + word_ = nextWord(cur, start, buffer()->params()); // end of document if (word_.word().empty()) @@ -242,9 +248,13 @@ void ControlSpellchecker::check() } int const size = word_.word().size(); +#if 0 advance(cur, -size); bufferview()->putSelectionAt(cur, size, false); advance(cur, size); +#else + bufferview()->putSelectionAt(cur, size, true); +#endif // set suggestions if (res != SpellBase::OK && res != SpellBase::IGNORE) { @@ -292,7 +302,7 @@ void ControlSpellchecker::showSummary() void ControlSpellchecker::replace(string const & replacement) { - bufferview()->cursor().replaceWord(replacement); + lyx::cap::replaceWord(bufferview()->cursor(), replacement); bufferview()->buffer()->markDirty(); bufferview()->update(); // fix up the count diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index a540315c13..20a0511ebf 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,3 +1,26 @@ + +2004-03-25 André Pönitz + + * inset.[Ch]: remover owner + + * insetcollapsable.[Ch]: derive from InsetText instead having such a + member + + * insettext.[Ch]: + * insetbibitem.C: + * insetbox.C: + * insetbranch.C: + * insetcaption.C: + * insetcharstyle.[Ch]: + * insetert.C: + * insetfloat.C: + * insetfoot.C: + * insetmarginal.C: + * insetnote.C: + * insetoptarg.C: + * insettabular.C: + * insetwrap.C: adjust + 2004-03-16 Jürgen Spitzmüller * insetquote.C: use opening quote after '[' char. diff --git a/src/insets/inset.C b/src/insets/inset.C index 00c226cdc0..37b73dd634 100644 --- a/src/insets/inset.C +++ b/src/insets/inset.C @@ -28,7 +28,7 @@ using std::string; InsetOld::InsetOld() : InsetBase(), - xo_(0), yo_(0), scx(0), owner_(0), + xo_(0), yo_(0), scx(0), //background_color_(LColor::inherit) background_color_(LColor::background) {} @@ -36,7 +36,7 @@ InsetOld::InsetOld() InsetOld::InsetOld(InsetOld const & in) : InsetBase(), - xo_(0), yo_(0), scx(0), owner_(0), name_(in.name_), + xo_(0), yo_(0), scx(0), name_(in.name_), background_color_(in.background_color_) {} @@ -53,10 +53,8 @@ LColor_color InsetOld::backgroundColor() const } -bool InsetOld::forceDefaultParagraphs(InsetBase const * inset) const +bool InsetOld::forceDefaultParagraphs(InsetBase const *) const { - if (owner()) - return owner()->forceDefaultParagraphs(inset); return false; } @@ -79,11 +77,9 @@ int InsetOld::width() const } -int InsetOld::scroll(bool recursive) const +int InsetOld::scroll(bool) const { - if (!recursive || !owner_) - return scx; - return 0; + return scx; } diff --git a/src/insets/inset.h b/src/insets/inset.h index 4d26e71603..fe3d22ac39 100644 --- a/src/insets/inset.h +++ b/src/insets/inset.h @@ -47,10 +47,6 @@ public: /// std::string const & getInsetName() const { return name_; } /// - void setOwner(UpdatableInset * inset) { owner_ = inset; } - /// - UpdatableInset * owner() const { return owner_; } - /// virtual void setBackgroundColor(LColor_color); /// LColor_color backgroundColor() const; @@ -76,8 +72,6 @@ protected: mutable Dimension dim_; private: - /// - UpdatableInset * owner_; /// std::string name_; /** We store the LColor::color value as an int to get LColor.h out diff --git a/src/insets/insetbase.h b/src/insets/insetbase.h index 6e93ae8728..e6601105f6 100644 --- a/src/insets/insetbase.h +++ b/src/insets/insetbase.h @@ -147,8 +147,6 @@ public: virtual int cellXOffset(idx_type) const { return 0; } /// any additional y-offset when drawing a cell? virtual int cellYOffset(idx_type) const { return 0; } - /// can we enter this cell? - virtual bool validCell(idx_type) const { return true; } /// number of embedded cells virtual size_t nargs() const { return 0; } /// number of rows in gridlike structures @@ -361,11 +359,6 @@ public: /// return text or mathmode if that is possible to determine virtual mode_type currentMode() const { return UNDECIDED_MODE; } - /// FIXME: This ought to die. - virtual void setOwner(UpdatableInset *) {} - /// - virtual UpdatableInset * owner() const { return 0; } - /// is this inset allowed within a font change? virtual bool noFontChange() const { return false; } diff --git a/src/insets/insetbibitem.C b/src/insets/insetbibitem.C index 26790b6614..a093ad824a 100644 --- a/src/insets/insetbibitem.C +++ b/src/insets/insetbibitem.C @@ -19,6 +19,7 @@ #include "lyxfont.h" #include "lyxlex.h" #include "paragraph.h" +#include "ParagraphList_fwd.h" #include "frontends/font_metrics.h" diff --git a/src/insets/insetbox.C b/src/insets/insetbox.C index 93130f69bf..fc2559d3ac 100644 --- a/src/insets/insetbox.C +++ b/src/insets/insetbox.C @@ -296,7 +296,7 @@ int InsetBox::latex(Buffer const & buf, ostream & os, i += 1; } - i += inset.latex(buf, os, runparams); + i += InsetText::latex(buf, os, runparams); if (params_.inner_box) { if (params_.use_parbox) @@ -331,14 +331,14 @@ int InsetBox::latex(Buffer const & buf, ostream & os, int InsetBox::linuxdoc(Buffer const & buf, std::ostream & os, OutputParams const & runparams) const { - return inset.linuxdoc(buf, os, runparams); + return InsetText::linuxdoc(buf, os, runparams); } int InsetBox::docbook(Buffer const & buf, std::ostream & os, OutputParams const & runparams) const { - return inset.docbook(buf, os, runparams); + return InsetText::docbook(buf, os, runparams); } @@ -356,7 +356,7 @@ int InsetBox::plaintext(Buffer const & buf, std::ostream & os, case Doublebox: os << "[["; break; } - int i = inset.plaintext(buf, os, runparams); + int i = InsetText::plaintext(buf, os, runparams); switch (btype) { case Frameless: break; @@ -386,14 +386,13 @@ void InsetBox::validate(LaTeXFeatures & features) const features.require("fancybox"); break; } - inset.validate(features); + InsetText::validate(features); } InsetBoxMailer::InsetBoxMailer(InsetBox & inset) : inset_(inset) -{ -} +{} string const InsetBoxMailer::name_ = "box"; diff --git a/src/insets/insetbranch.C b/src/insets/insetbranch.C index 9c3309ed35..ef8b06db3e 100644 --- a/src/insets/insetbranch.C +++ b/src/insets/insetbranch.C @@ -162,7 +162,7 @@ int InsetBranch::latex(Buffer const & buf, ostream & os, OutputParams const & runparams) const { return isBranchSelected(buf.params().branchlist()) ? - inset.latex(buf, os, runparams) : 0; + InsetText::latex(buf, os, runparams) : 0; } @@ -170,7 +170,7 @@ int InsetBranch::linuxdoc(Buffer const & buf, std::ostream & os, OutputParams const & runparams) const { return isBranchSelected(buf.params().branchlist()) ? - inset.linuxdoc(buf, os, runparams) : 0; + InsetText::linuxdoc(buf, os, runparams) : 0; } @@ -178,7 +178,7 @@ int InsetBranch::docbook(Buffer const & buf, std::ostream & os, OutputParams const & runparams) const { return isBranchSelected(buf.params().branchlist()) ? - inset.docbook(buf, os, runparams) : 0; + InsetText::docbook(buf, os, runparams) : 0; } @@ -186,18 +186,18 @@ int InsetBranch::plaintext(Buffer const & buf, std::ostream & os, OutputParams const & runparams) const { return isBranchSelected(buf.params().branchlist()) ? - inset.plaintext(buf, os, runparams): 0; + InsetText::plaintext(buf, os, runparams): 0; } void InsetBranch::validate(LaTeXFeatures & features) const { - inset.validate(features); + InsetText::validate(features); } -string const InsetBranchMailer:: name_("branch"); +string const InsetBranchMailer::name_("branch"); InsetBranchMailer::InsetBranchMailer(InsetBranch & inset) : inset_(inset) diff --git a/src/insets/insetcaption.C b/src/insets/insetcaption.C index 2b4d0bf7a0..c368c2a2ff 100644 --- a/src/insets/insetcaption.C +++ b/src/insets/insetcaption.C @@ -87,19 +87,28 @@ void InsetCaption::draw(PainterInfo & pi, int x, int y) const // See if we can find the name of the float this caption // belongs to. +#if 0 InsetOld * i1 = owner(); InsetOld * i2 = i1 ? i1->owner() : 0; string type; if (i2->lyxCode() == FLOAT_CODE) +#warning Now, what happens for i2 == 0? type = static_cast(i2)->params().type; else if (i2->lyxCode() == WRAP_CODE) type = static_cast(i2)->params().type; else BOOST_ASSERT(false); +#else + string type = "float"; +#endif FloatList const & floats = pi.base.bv->buffer()->params().getLyXTextClass().floats(); +#if 0 string const fl = i2 ? floats.getType(type).name() : N_("Float"); +#else + string const fl = N_("Float"); +#endif // Discover the number... string const num = "#"; diff --git a/src/insets/insetcharstyle.C b/src/insets/insetcharstyle.C index 81647143ba..8f64168a34 100644 --- a/src/insets/insetcharstyle.C +++ b/src/insets/insetcharstyle.C @@ -109,33 +109,30 @@ void InsetCharStyle::draw(PainterInfo & pi, int x, int y) const // FIXME: setStatus(Inlined); this is not a const operation LyXFont tmpfont = pi.base.font; - inset.setDrawFrame(InsetText::NEVER); + //setDrawFrame(InsetText::NEVER); getDrawFont(pi.base.font); - inset.draw(pi, x, y); + InsetText::draw(pi, x, y); pi.base.font = tmpfont; - pi.pain.line(x + 2, y + inset.descent() - 4, x + 2, - y + inset.descent(), params_.labelfont.color()); - pi.pain.line(x + 2, y + inset.descent(), x + dim_.wid - 2, - y + inset.descent(), params_.labelfont.color()); - pi.pain.line(x + dim_.wid - 2, y + inset.descent(), x + dim_.wid - 2, - y + inset.descent() - 4, params_.labelfont.color()); + pi.pain.line(x + 2, y + InsetText::descent() - 4, x + 2, + y + InsetText::descent(), params_.labelfont.color()); + pi.pain.line(x + 2, y + InsetText::descent(), x + dim_.wid - 2, + y + InsetText::descent(), params_.labelfont.color()); + pi.pain.line(x + dim_.wid - 2, y + InsetText::descent(), x + dim_.wid - 2, + y + InsetText::descent() - 4, params_.labelfont.color()); if (has_label_) { - if (!owner()) - x += scroll(); - - LyXFont font(params_.labelfont); - font.realize(LyXFont(LyXFont::ALL_SANE)); - font.decSize(); - font.decSize(); - int w = 0; - int a = 0; - int d = 0; - font_metrics::rectText(params_.type, font, w, a, d); - pi.pain.rectText(x + (dim_.wid - w) / 2, - y + inset.descent() + a, - params_.type, font, LColor::none, LColor::none); + LyXFont font(params_.labelfont); + font.realize(LyXFont(LyXFont::ALL_SANE)); + font.decSize(); + font.decSize(); + int w = 0; + int a = 0; + int d = 0; + font_metrics::rectText(params_.type, font, w, a, d); + pi.pain.rectText(x + (dim_.wid - w) / 2, + y + InsetText::descent() + a, + params_.type, font, LColor::none, LColor::none); } } @@ -154,7 +151,7 @@ void InsetCharStyle::priv_dispatch(LCursor & cur, FuncRequest & cmd) if (cmd.button() == mouse_button::button3) has_label_ = !has_label_; else - inset.dispatch(cur, cmd); + InsetText::dispatch(cur, cmd); break; default: @@ -166,7 +163,7 @@ void InsetCharStyle::priv_dispatch(LCursor & cur, FuncRequest & cmd) namespace { -int outputVerbatim(std::ostream & os, InsetText inset) +int outputVerbatim(std::ostream & os, InsetText const & inset) { int lines = 0; ParagraphList::iterator par = inset.paragraphs().begin(); @@ -200,7 +197,7 @@ int InsetCharStyle::latex(Buffer const &, ostream & os, if (!params_.latexparam.empty()) os << params_.latexparam; os << "{"; - int i = outputVerbatim(os, inset); + int i = outputVerbatim(os, *this); os << "}%\n"; i += 2; return i; @@ -214,7 +211,7 @@ int InsetCharStyle::linuxdoc(Buffer const &, std::ostream & os, if (!params_.latexparam.empty()) os << " " << params_.latexparam; os << ">"; - int const i = outputVerbatim(os, inset); + int const i = outputVerbatim(os, *this); os << ""; return i; } @@ -227,7 +224,7 @@ int InsetCharStyle::docbook(Buffer const &, std::ostream & os, if (!params_.latexparam.empty()) os << " " << params_.latexparam; os << ">"; - int const i = outputVerbatim(os, inset); + int const i = outputVerbatim(os, *this); os << ""; return i; } @@ -236,7 +233,7 @@ int InsetCharStyle::docbook(Buffer const &, std::ostream & os, int InsetCharStyle::plaintext(Buffer const &, std::ostream & os, OutputParams const & /*runparams*/) const { - return outputVerbatim(os, inset); + return outputVerbatim(os, *this); } diff --git a/src/insets/insetcharstyle.h b/src/insets/insetcharstyle.h index ca31e33357..f06e485c3c 100644 --- a/src/insets/insetcharstyle.h +++ b/src/insets/insetcharstyle.h @@ -13,12 +13,11 @@ #ifndef INSETCHARSTYLE_H #define INSETCHARSTYLE_H - #include "insetcollapsable.h" #include "lyxtextclass.h" - struct InsetCharStyleParams { +struct InsetCharStyleParams { /// void write(std::ostream & os) const; /// @@ -44,8 +43,6 @@ class InsetCharStyle : public InsetCollapsable { public: /// - - InsetCharStyle(BufferParams const &, CharStyles::iterator); /// Copy constructor InsetCharStyle(InsetCharStyle const &); @@ -88,6 +85,7 @@ protected: virtual void priv_dispatch(LCursor & cur, FuncRequest & cmd); private: + /// friend class InsetCharStyleParams; /// used by the constructors diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index 0c8a5bef1b..c9714b04a5 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -41,26 +41,16 @@ using std::ostream; InsetCollapsable::InsetCollapsable(BufferParams const & bp, CollapseStatus status) - : inset(bp), label("Label"), status_(status), openinlined_(false) + : InsetText(bp), label("Label"), status_(status), openinlined_(false) { - inset.setOwner(this); - inset.setAutoBreakRows(true); - inset.setDrawFrame(InsetText::ALWAYS); - inset.setFrameColor(LColor::collapsableframe); + setAutoBreakRows(true); + setDrawFrame(InsetText::ALWAYS); + setFrameColor(LColor::collapsableframe); setInsetName("Collapsable"); setButtonLabel(); } -InsetCollapsable::InsetCollapsable(InsetCollapsable const & in) - : UpdatableInset(in), inset(in.inset), - labelfont_(in.labelfont_), label(in.label), status_(in.status_) -{ - inset.setOwner(this); - setButtonLabel(); -} - - void InsetCollapsable::write(Buffer const & buf, ostream & os) const { os << "status "; @@ -76,7 +66,7 @@ void InsetCollapsable::write(Buffer const & buf, ostream & os) const break; } os << "\n"; - inset.text_.write(buf, os); + text_.write(buf, os); } @@ -106,13 +96,13 @@ void InsetCollapsable::read(Buffer const & buf, LyXLex & lex) lex.pushToken(token); } } else { - lyxerr << "InsetCollapsable::Read: Missing 'status'-tag!" + lyxerr << "InsetCollapsable::read: Missing 'status'-tag!" << endl; // take countermeasures lex.pushToken(token); } } - inset.read(buf, lex); + InsetText::read(buf, lex); if (!token_found) status_ = isOpen() ? Open : Collapsed; @@ -130,20 +120,19 @@ void InsetCollapsable::dimension_collapsed(Dimension & dim) const void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const { if (status_ == Inlined) { - inset.metrics(mi, dim); + InsetText::metrics(mi, dim); } else { dimension_collapsed(dim); if (status_ == Open) { Dimension insetdim; - inset.metrics(mi, insetdim); + InsetText::metrics(mi, insetdim); openinlined_ = (insetdim.wid + dim.wid <= mi.base.textwidth); if (openinlined_) { dim.wid += insetdim.wid; dim.des = max(dim.des, insetdim.des); dim.asc = max(dim.asc, insetdim.asc); } else { - dim.des += insetdim.height() - + TEXT_TO_BOTTOM_OFFSET; + dim.des += insetdim.height() + TEXT_TO_BOTTOM_OFFSET; dim.wid = max(dim.wid, insetdim.wid); } } @@ -163,7 +152,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const setPosCache(pi, x, y); if (status_ == Inlined) { - inset.draw(pi, x, y); + InsetText::draw(pi, x, y); } else { Dimension dimc; dimension_collapsed(dimc); @@ -175,24 +164,16 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const draw_collapsed(pi, x, y); if (status_ == Open) { - if (!owner()) - x += scroll(); - + x += scroll(); if (openinlined_) - inset.draw(pi, x + dimc.width(), y - aa + inset.ascent()); + InsetText::draw(pi, x + dimc.width(), y - aa + InsetText::ascent()); else - inset.draw(pi, x, y - aa + dimc.height() + inset.ascent()); + InsetText::draw(pi, x, y - aa + dimc.height() + InsetText::ascent()); } } } -void InsetCollapsable::drawSelection(PainterInfo & pi, int x, int y) const -{ - inset.drawSelection(pi, x, y); -} - - InsetOld::EDITABLE InsetCollapsable::editable() const { return status_ != Collapsed ? HIGHLY_EDITABLE : IS_EDITABLE; @@ -205,69 +186,6 @@ bool InsetCollapsable::descendable() const } -void InsetCollapsable::lfunMouseRelease(LCursor & cur, FuncRequest & cmd) -{ - if (cmd.button() == mouse_button::button3) { - showInsetDialog(&cur.bv()); - return; - } - - switch (status_) { - - case Collapsed: - lyxerr << "InsetCollapsable::lfunMouseRelease 1" << endl; - setStatus(Open); - edit(cur, true); - break; - - case Open: { - FuncRequest cmd1 = cmd; - if (hitButton(cmd1)) { - lyxerr << "InsetCollapsable::lfunMouseRelease 2" << endl; - setStatus(Collapsed); - cmd = FuncRequest(LFUN_FINISHED_RIGHT); - break; - } - lyxerr << "InsetCollapsable::lfunMouseRelease 3" << endl; - inset.dispatch(cur, cmd); - break; - } - - case Inlined: - inset.dispatch(cur, cmd); - break; - } -} - - -int InsetCollapsable::latex(Buffer const & buf, ostream & os, - OutputParams const & runparams) const -{ - return inset.latex(buf, os, runparams); -} - - -int InsetCollapsable::plaintext(Buffer const & buf, ostream & os, - OutputParams const & runparams) const -{ - return inset.plaintext(buf, os, runparams); -} - - -int InsetCollapsable::linuxdoc(Buffer const & buf, ostream & os, - OutputParams const & runparams) const -{ - return inset.linuxdoc(buf, os, runparams); -} - - -int InsetCollapsable::docbook(Buffer const & buf, ostream & os, - OutputParams const & runparams) const -{ - return inset.docbook(buf, os, runparams); -} - - bool InsetCollapsable::hitButton(FuncRequest & cmd) const { return button_dim.contains(cmd.x, cmd.y); @@ -278,17 +196,17 @@ string const InsetCollapsable::getNewLabel(string const & l) const { string label; pos_type const max_length = 15; - pos_type const p_siz = inset.paragraphs().begin()->size(); + pos_type const p_siz = paragraphs().begin()->size(); pos_type const n = min(max_length, p_siz); pos_type i = 0; pos_type j = 0; for( ; i < n && j < p_siz; ++j) { - if (inset.paragraphs().begin()->isInset(j)) + if (paragraphs().begin()->isInset(j)) continue; - label += inset.paragraphs().begin()->getChar(j); + label += paragraphs().begin()->getChar(j); ++i; } - if (inset.paragraphs().size() > 1 || (i > 0 && j < p_siz)) { + if (paragraphs().size() > 1 || (i > 0 && j < p_siz)) { label += "..."; } return label.empty() ? l : label; @@ -299,7 +217,7 @@ void InsetCollapsable::edit(LCursor & cur, bool left) { //lyxerr << "InsetCollapsable: edit left/right" << endl; cur.push(*this); - inset.edit(cur, left); + InsetText::edit(cur, left); open(); } @@ -310,13 +228,13 @@ InsetBase * InsetCollapsable::editXY(LCursor & cur, int x, int y) //lyxerr << "InsetCollapsable: edit xy" << endl; if (status_ == Collapsed) { setStatus(Open); - inset.edit(cur, true); -#warning look here -//we are not calling edit(x,y) because there are no coordinates in the -//inset yet. I personally think it's ok. (ab) + // We are not calling editXY() because the row cache of the + // inset might be invalid. 'Entering from the left' should be + // ok, though. + InsetText::edit(cur, true); return this; } - return inset.editXY(cur, x, y); + return InsetText::editXY(cur, x, y); } @@ -327,90 +245,83 @@ void InsetCollapsable::priv_dispatch(LCursor & cur, FuncRequest & cmd) switch (cmd.action) { case LFUN_MOUSE_PRESS: if (status_ == Inlined) - inset.dispatch(cur, cmd); + InsetText::priv_dispatch(cur, cmd); else if (status_ == Open && !hitButton(cmd)) - inset.dispatch(cur, cmd); + InsetText::priv_dispatch(cur, cmd); break; case LFUN_MOUSE_MOTION: if (status_ == Inlined) - inset.dispatch(cur, cmd); + InsetText::priv_dispatch(cur, cmd); else if (status_ == Open && !hitButton(cmd)) - inset.dispatch(cur, cmd); + InsetText::priv_dispatch(cur, cmd); break; case LFUN_MOUSE_RELEASE: - lfunMouseRelease(cur, cmd); + if (cmd.button() == mouse_button::button3) { + showInsetDialog(&cur.bv()); + break; + } + + switch (status_) { + + case Collapsed: + lyxerr << "InsetCollapsable::lfunMouseRelease 1" << endl; + setStatus(Open); + edit(cur, true); + break; + + case Open: { + FuncRequest cmd1 = cmd; + if (hitButton(cmd1)) { + lyxerr << "InsetCollapsable::lfunMouseRelease 2" << endl; + setStatus(Collapsed); + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_RIGHT); + } else { + lyxerr << "InsetCollapsable::lfunMouseRelease 3" << endl; + InsetText::priv_dispatch(cur, cmd); + } + break; + } + + case Inlined: + lyxerr << "InsetCollapsable::lfunMouseRelease 4" << endl; + InsetText::priv_dispatch(cur, cmd); + break; + } break; case LFUN_INSET_TOGGLE: - if (inset.text_.toggleInset(cur)) + if (InsetText::text_.toggleInset(cur)) break; if (status_ == Open) { setStatus(Inlined); break; } setStatus(Collapsed); + cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_RIGHT); break; default: - inset.dispatch(cur, cmd); + InsetText::priv_dispatch(cur, cmd); break; } } -bool InsetCollapsable::getStatus(LCursor & cur, FuncRequest const & cmd, - FuncStatus & flag) const -{ - return inset.getStatus(cur, cmd, flag); -} - - -void InsetCollapsable::validate(LaTeXFeatures & features) const -{ - inset.validate(features); -} - - -void InsetCollapsable::getCursorPos(CursorSlice const & cur, - int & x, int & y) const -{ - inset.getCursorPos(cur, x, y); -} - - -void InsetCollapsable::getLabelList(Buffer const & buffer, - std::vector & list) const -{ - inset.getLabelList(buffer, list); -} - - int InsetCollapsable::scroll(bool recursive) const { int sx = UpdatableInset::scroll(false); if (recursive) - sx += inset.scroll(false); + sx += InsetText::scroll(false); return sx; } -size_t InsetCollapsable::nargs() const -{ - return inset.nargs(); -} - - -LyXText * InsetCollapsable::getText(int i) const -{ - return inset.getText(i); -} - - void InsetCollapsable::open() { if (status_ == Collapsed) // ...but not inlined @@ -437,24 +348,6 @@ void InsetCollapsable::setStatus(CollapseStatus st) } -void InsetCollapsable::markErased() -{ - inset.markErased(); -} - - -void InsetCollapsable::addPreview(PreviewLoader & loader) const -{ - inset.addPreview(loader); -} - - -bool InsetCollapsable::insetAllowed(InsetOld::Code code) const -{ - return inset.insetAllowed(code); -} - - void InsetCollapsable::setLabelFont(LyXFont & font) { labelfont_ = font; @@ -477,10 +370,3 @@ Box const & InsetCollapsable::buttonDim() const { return button_dim; } - - -void InsetCollapsable::setBackgroundColor(LColor_color color) -{ - InsetOld::setBackgroundColor(color); - inset.setBackgroundColor(color); -} diff --git a/src/insets/insetcollapsable.h b/src/insets/insetcollapsable.h index aa0ee77abc..4b34329e35 100644 --- a/src/insets/insetcollapsable.h +++ b/src/insets/insetcollapsable.h @@ -28,7 +28,7 @@ class CursorSlice; /** A collapsable text inset */ -class InsetCollapsable : public UpdatableInset { +class InsetCollapsable : public InsetText { public: /// static int const TEXT_TO_TOP_OFFSET = 2; @@ -36,15 +36,13 @@ public: static int const TEXT_TO_BOTTOM_OFFSET = 2; /// enum CollapseStatus { - Open, Collapsed, - Inlined + Inlined, + Open }; /// InsetCollapsable(BufferParams const &, CollapseStatus status = Open); /// - InsetCollapsable(InsetCollapsable const & in); - /// void read(Buffer const &, LyXLex &); /// void write(Buffer const &, std::ostream &) const; @@ -53,8 +51,6 @@ public: /// void draw(PainterInfo & pi, int x, int y) const; /// - void drawSelection(PainterInfo & pi, int x, int y) const; - /// bool hitButton(FuncRequest &) const; /// std::string const getNewLabel(std::string const & l) const; @@ -63,33 +59,13 @@ public: /// can we go further down on mouse click? bool descendable() const; /// - bool insetAllowed(InsetOld::Code code) const; - /// bool isTextInset() const { return true; } /// - int latex(Buffer const &, std::ostream &, - OutputParams const &) const; - /// - int plaintext(Buffer const &, std::ostream &, - OutputParams const &) const; - /// - int linuxdoc(Buffer const &, std::ostream &, - OutputParams const &) const; - /// - int docbook(Buffer const &, std::ostream &, - OutputParams const & runparams) const; - /// - void validate(LaTeXFeatures & features) const; - /// get the screen x,y of the cursor - void getCursorPos(CursorSlice const & cur, int & x, int & y) const; - /// void setLabel(std::string const & l); /// virtual void setButtonLabel() {} /// void setLabelFont(LyXFont & f); - /// Appends \c list with all labels found within this inset. - void getLabelList(Buffer const &, std::vector & list) const; /// int scroll(bool recursive = true) const; /// @@ -97,10 +73,6 @@ public: /// void scroll(BufferView & bv, int offset) const; /// - size_t nargs() const; - /// - LyXText * getText(int) const; - /// bool isOpen() const { return status_ == Open || status_ == Inlined; } /// bool inlined() const { return status_ == Inlined; } @@ -111,21 +83,13 @@ public: /// void close(); /// - void markErased(); - /// - void addPreview(lyx::graphics::PreviewLoader &) const; - /// - void setBackgroundColor(LColor_color); - /// - void setStatus(CollapseStatus st); - /// bool allowSpellCheck() const { return true; } protected: /// - void priv_dispatch(LCursor & cur, FuncRequest & cmd); + void setStatus(CollapseStatus st); /// - bool getStatus(LCursor & cur, FuncRequest const & cmd, FuncStatus &) const; + void priv_dispatch(LCursor & cur, FuncRequest & cmd); /// void dimension_collapsed(Dimension &) const; /// @@ -139,13 +103,6 @@ protected: /// InsetBase * editXY(LCursor & cur, int x, int y); -private: - /// - void lfunMouseRelease(LCursor & cur, FuncRequest & cmd); - -public: - /// - mutable InsetText inset; protected: /// LyXFont labelfont_; diff --git a/src/insets/insetert.C b/src/insets/insetert.C index b1495e7726..086e32f8fd 100644 --- a/src/insets/insetert.C +++ b/src/insets/insetert.C @@ -85,9 +85,9 @@ InsetERT::InsetERT(BufferParams const & bp, string::const_iterator cit = contents.begin(); string::const_iterator end = contents.end(); pos_type pos = 0; - for (; cit != end; ++cit) { - inset.paragraphs().begin()->insertChar(pos++, *cit, font); - } + for (; cit != end; ++cit) + paragraphs().begin()->insertChar(pos++, *cit, font); + // the init has to be after the initialization of the paragraph // because of the label settings (draw_label for ert insets). init(); @@ -116,8 +116,8 @@ string const InsetERT::editMessage() const int InsetERT::latex(Buffer const &, ostream & os, OutputParams const &) const { - ParagraphList::iterator par = inset.paragraphs().begin(); - ParagraphList::iterator end = inset.paragraphs().end(); + ParagraphList::iterator par = paragraphs().begin(); + ParagraphList::iterator end = paragraphs().end(); int lines = 0; while (par != end) { @@ -153,10 +153,10 @@ int InsetERT::plaintext(Buffer const &, ostream &, int InsetERT::linuxdoc(Buffer const &, ostream & os, - OutputParams const &)const + OutputParams const &) const { - ParagraphList::iterator par = inset.paragraphs().begin(); - ParagraphList::iterator end = inset.paragraphs().end(); + ParagraphList::iterator par = paragraphs().begin(); + ParagraphList::iterator end = paragraphs().end(); int lines = 0; while (par != end) { @@ -183,8 +183,8 @@ int InsetERT::linuxdoc(Buffer const &, ostream & os, int InsetERT::docbook(Buffer const &, ostream & os, OutputParams const &) const { - ParagraphList::iterator par = inset.paragraphs().begin(); - ParagraphList::iterator end = inset.paragraphs().end(); + ParagraphList::iterator par = paragraphs().begin(); + ParagraphList::iterator end = paragraphs().end(); int lines = 0; while (par != end) { diff --git a/src/insets/insetfloat.C b/src/insets/insetfloat.C index 1d20cd0a94..ed173ac63b 100644 --- a/src/insets/insetfloat.C +++ b/src/insets/insetfloat.C @@ -133,9 +133,7 @@ string floatname(string const & type, BufferParams const & bp) InsetFloat::InsetFloat(BufferParams const & bp, string const & type) : InsetCollapsable(bp) { - string lab(_("float: ")); - lab += floatname(type, bp); - setLabel(lab); + setLabel(_("float: ") + floatname(type, bp)); LyXFont font(LyXFont::ALL_SANE); font.decSize(); font.decSize(); @@ -145,7 +143,7 @@ InsetFloat::InsetFloat(BufferParams const & bp, string const & type) setInsetName(type); LyXTextClass const & tclass = bp.getLyXTextClass(); if (tclass.hasLayout(caplayout)) - inset.paragraphs().begin()->layout(tclass[caplayout]); + paragraphs().begin()->layout(tclass[caplayout]); } @@ -294,7 +292,7 @@ int InsetFloat::latex(Buffer const & buf, ostream & os, } os << '\n'; - int const i = inset.latex(buf, os, runparams); + int const i = InsetText::latex(buf, os, runparams); // The \n is used to force \end{} to appear in a new line. // In this case, we do not case if the current output line is empty. @@ -335,7 +333,7 @@ int InsetFloat::linuxdoc(Buffer const & buf, ostream & os, } os << ">"; - int const i = inset.linuxdoc(buf, os, runparams); + int const i = InsetText::linuxdoc(buf, os, runparams); os << "\n"; return i; @@ -346,7 +344,7 @@ int InsetFloat::docbook(Buffer const & buf, ostream & os, OutputParams const & runparams) const { os << '<' << params_.type << '>'; - int const i = inset.docbook(buf, os, runparams); + int const i = InsetText::docbook(buf, os, runparams); os << "'; return i; @@ -363,7 +361,7 @@ bool InsetFloat::insetAllowed(InsetOld::Code code) const bool InsetFloat::showInsetDialog(BufferView * bv) const { - if (!inset.showInsetDialog(bv)) + if (!InsetText::showInsetDialog(bv)) InsetFloatMailer(const_cast(*this)).showDialog(bv); return true; } @@ -381,8 +379,8 @@ void InsetFloat::wide(bool w, BufferParams const & bp) void InsetFloat::addToToc(lyx::toc::TocList & toclist, Buffer const & buf) const { - ParIterator pit(inset.paragraphs().begin(), inset.paragraphs()); - ParIterator end(inset.paragraphs().end(), inset.paragraphs()); + ParIterator pit(0, paragraphs()); + ParIterator end(paragraphs().size(), paragraphs()); // Find a caption layout in one of the (child inset's) pars for (; pit != end; ++pit) { diff --git a/src/insets/insetfoot.C b/src/insets/insetfoot.C index 530efdd1b5..cc844c8c62 100644 --- a/src/insets/insetfoot.C +++ b/src/insets/insetfoot.C @@ -65,7 +65,7 @@ int InsetFoot::latex(Buffer const & buf, ostream & os, os << "%\n\\footnote{"; - int const i = inset.latex(buf, os, runparams); + int const i = InsetText::latex(buf, os, runparams); os << "%\n}"; return i + 2; @@ -76,7 +76,7 @@ int InsetFoot::docbook(Buffer const & buf, ostream & os, OutputParams const & runparams) const { os << ""; - int const i = inset.docbook(buf, os, runparams); + int const i = InsetText::docbook(buf, os, runparams); os << ""; return i; diff --git a/src/insets/insetmarginal.C b/src/insets/insetmarginal.C index 6fafd8950c..e46838c06e 100644 --- a/src/insets/insetmarginal.C +++ b/src/insets/insetmarginal.C @@ -56,9 +56,7 @@ int InsetMarginal::latex(Buffer const & buf, ostream & os, OutputParams const & runparams) const { os << "%\n\\marginpar{"; - - int const i = inset.latex(buf, os, runparams); + int const i = InsetText::latex(buf, os, runparams); os << "%\n}"; - return i + 2; } diff --git a/src/insets/insetnote.C b/src/insets/insetnote.C index a9b0cb9662..0dc7091403 100644 --- a/src/insets/insetnote.C +++ b/src/insets/insetnote.C @@ -226,7 +226,7 @@ int InsetNote::latex(Buffer const & buf, ostream & os, ostringstream ss; ss << "%\n\\begin{" << type << "}\n"; - inset.latex(buf, ss, runparams); + InsetText::latex(buf, ss, runparams); ss << "%\n\\end{" << type << "}\n"; string const str = ss.str(); @@ -246,7 +246,7 @@ int InsetNote::linuxdoc(Buffer const & buf, std::ostream & os, if (params_.type == InsetNoteParams::Comment) ss << "\n"; - inset.linuxdoc(buf, ss, runparams); + InsetText::linuxdoc(buf, ss, runparams); if (params_.type == InsetNoteParams::Comment) ss << "\n\n"; @@ -268,7 +268,7 @@ int InsetNote::docbook(Buffer const & buf, std::ostream & os, if (params_.type == InsetNoteParams::Comment) ss << "\n"; - inset.docbook(buf, ss, runparams); + InsetText::docbook(buf, ss, runparams); if (params_.type == InsetNoteParams::Comment) ss << "\n\n"; @@ -288,7 +288,7 @@ int InsetNote::plaintext(Buffer const & buf, std::ostream & os, ostringstream ss; ss << "["; - inset.plaintext(buf, ss, runparams); + InsetText::plaintext(buf, ss, runparams); ss << "]"; string const str = ss.str(); @@ -306,12 +306,12 @@ void InsetNote::validate(LaTeXFeatures & features) const features.require("color"); features.require("lyxgreyedout"); } - inset.validate(features); + InsetText::validate(features); } -string const InsetNoteMailer:: name_("note"); +string const InsetNoteMailer::name_("note"); InsetNoteMailer::InsetNoteMailer(InsetNote & inset) : inset_(inset) diff --git a/src/insets/insetoptarg.C b/src/insets/insetoptarg.C index 9b5e42b441..ed829859cb 100644 --- a/src/insets/insetoptarg.C +++ b/src/insets/insetoptarg.C @@ -73,7 +73,7 @@ int InsetOptArg::latexOptional(Buffer const & buf, ostream & os, OutputParams const & runparams) const { os << '['; - int const i = inset.latex(buf, os, runparams); + int const i = InsetText::latex(buf, os, runparams); os << ']'; return i + 2; } diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 2ee3c69ddd..fee887c086 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -156,17 +156,13 @@ bool InsetTabular::hasPasteBuffer() const InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns) : tabular(buf.params(), max(rows, 1), max(columns, 1)), buffer_(&buf), cursorx_(0) -{ - tabular.setOwner(this); -} +{} InsetTabular::InsetTabular(InsetTabular const & tab) : UpdatableInset(tab), tabular(tab.tabular), buffer_(tab.buffer_), cursorx_(0) -{ - tabular.setOwner(this); -} +{} InsetTabular::~InsetTabular() @@ -265,9 +261,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const BufferView * bv = pi.base.bv; setPosCache(pi, x, y); - if (!owner()) - x += scroll(); - + x += scroll(); x += ADD_TO_TABULAR_WIDTH; int idx = 0; @@ -463,7 +457,6 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest & cmd) scroll(cur.bv(), static_cast(strToDbl(cmd.argument))); else scroll(cur.bv(), strToInt(cmd.argument)); - cur.update(); break; case LFUN_RIGHTSEL: @@ -802,13 +795,16 @@ int InsetTabular::docbook(Buffer const & buf, ostream & os, OutputParams const & runparams) const { int ret = 0; - InsetOld * master; + InsetOld * master = 0; +#warning Why not pass a proper DocIterator here? +#if 0 // if the table is inside a float it doesn't need the informaltable // wrapper. Search for it. for (master = owner(); master; master = master->owner()) if (master->lyxCode() == InsetOld::FLOAT_CODE) break; +#endif if (!master) { os << ""; @@ -1100,13 +1096,11 @@ void InsetTabular::tabularFeatures(LCursor & cur, case LyXTabular::APPEND_ROW: // append the row into the tabular tabular.appendRow(bv.buffer()->params(), actcell); - tabular.setOwner(this); break; case LyXTabular::APPEND_COLUMN: // append the column into the tabular tabular.appendColumn(bv.buffer()->params(), actcell); - tabular.setOwner(this); actcell = tabular.getCellNumber(row, column); break; @@ -1553,7 +1547,6 @@ bool InsetTabular::copySelection(LCursor & cur) getSelection(cur, rs, re, cs, ce); paste_tabular.reset(new LyXTabular(tabular)); - paste_tabular->setOwner(this); for (int i = 0; i < rs; ++i) paste_tabular->deleteRow(0); @@ -1611,7 +1604,6 @@ bool InsetTabular::pasteSelection(LCursor & cur) } InsetText & inset = tabular.getCellInset(r2, c2); inset = paste_tabular->getCellInset(r1, c1); - inset.setOwner(this); inset.markNew(); } } @@ -1642,8 +1634,8 @@ bool InsetTabular::isRightToLeft(LCursor & cur) void InsetTabular::getSelection(LCursor & cur, int & rs, int & re, int & cs, int & ce) const { - CursorSlice & beg = cur.selBegin(); - CursorSlice & end = cur.selEnd(); + CursorSlice const & beg = cur.selBegin(); + CursorSlice const & end = cur.selEnd(); cs = tabular.column_of_cell(beg.idx()); ce = tabular.column_of_cell(end.idx()); if (cs > ce) { @@ -1738,7 +1730,6 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, if (usePaste) { paste_tabular.reset( new LyXTabular(bv.buffer()->params(), rows, maxCols)); - paste_tabular->setOwner(this); loctab = paste_tabular.get(); cols = 0; } else { @@ -1765,8 +1756,7 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, // we can only set this if we are not too far right if (cols < columns) { InsetText & inset = loctab->getCellInset(cell); - LyXFont const font = inset.text_. - getFont(inset.paragraphs().begin(), 0); + LyXFont const font = inset.text_.getFont(0, 0); inset.setText(buf.substr(op, p - op), font); ++cols; ++cell; @@ -1776,8 +1766,7 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, // we can only set this if we are not too far right if (cols < columns) { InsetText & inset = tabular.getCellInset(cell); - LyXFont const font = inset.text_. - getFont(inset.paragraphs().begin(), 0); + LyXFont const font = inset.text_.getFont(0, 0); inset.setText(buf.substr(op, p - op), font); } cols = ocol; @@ -1792,7 +1781,7 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, // check for the last cell if there is no trailing '\n' if (cell < cells && op < len) { InsetText & inset = loctab->getCellInset(cell); - LyXFont const font = inset.text_.getFont(inset.paragraphs().begin(), 0); + LyXFont const font = inset.text_.getFont(0, 0); inset.setText(buf.substr(op, len - op), font); } return true; diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 4c3b7005ce..7e88694b8a 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -107,7 +107,6 @@ void InsetText::init() for (; pit != end; ++pit) pit->setInsetOwner(this); old_par = -1; - in_insetAllowed = false; } @@ -201,8 +200,7 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const BufferView * bv = pi.base.bv; bv->hideCursor(); - if (!owner()) - x += scroll(); + x += scroll(); y += bv->top_y() - text_.ascent(); text_.draw(pi, x, y); @@ -220,11 +218,10 @@ void InsetText::drawSelection(PainterInfo & pi, int x, int y) const void InsetText::drawFrame(Painter & pain, int x, int y) const { - int const ttoD2 = TEXT_TO_INSET_OFFSET / 2; - int const frame_x = x + ttoD2; - int const frame_y = y - dim_.asc + ttoD2; - int const frame_w = dim_.wid - TEXT_TO_INSET_OFFSET; - int const frame_h = dim_.asc + dim_.des - TEXT_TO_INSET_OFFSET; + int const frame_x = x + TEXT_TO_INSET_OFFSET / 2; + int const frame_y = y - dim_.asc + TEXT_TO_INSET_OFFSET / 2; + int const frame_w = text_.width(); + int const frame_h = text_.height(); pain.rectangle(frame_x, frame_y, frame_w, frame_h, frameColor()); } @@ -246,7 +243,7 @@ void InsetText::updateLocal(LCursor & cur) } cur.clearSelection(); - mergeParagraph(cur.bv().buffer()->params(), paragraphs(), first); + mergeParagraph(cur.bv().buffer()->params(), paragraphs(), 0); } } @@ -258,7 +255,7 @@ void InsetText::updateLocal(LCursor & cur) lv->updateMenubar(); lv->updateToolbar(); if (old_par != cur.par()) { - lv->setLayout(text_.getPar(cur.par())->layout()->name()); + lv->setLayout(text_.getPar(cur.par()).layout()->name()); old_par = cur.par(); } } @@ -309,9 +306,7 @@ InsetBase * InsetText::editXY(LCursor & cur, int x, int y) void InsetText::priv_dispatch(LCursor & cur, FuncRequest & cmd) { - //lyxerr << "InsetText::priv_dispatch (begin), act: " - // << cmd.action << " " << endl; - + //lyxerr << "InsetText::priv_dispatch: " << cmd.action << " " << endl; setViewCache(&cur.bv()); bool was_empty = paragraphs().begin()->empty() && paragraphs().size() == 1; @@ -327,8 +322,6 @@ void InsetText::priv_dispatch(LCursor & cur, FuncRequest & cmd) font.setLanguage(cur.bv().getParentLanguage(this)); text_.setFont(cur, font, false); } - - //lyxerr << "InsetText::priv_dispatch (end)" << endl; } @@ -392,21 +385,6 @@ void InsetText::getCursorPos(CursorSlice const & cur, int & x, int & y) const } -bool InsetText::insetAllowed(InsetOld::Code code) const -{ - // in_insetAllowed is a really gross hack, - // to allow us to call the owner's insetAllowed - // without stack overflow, which can happen - // when the owner uses InsetCollapsable::insetAllowed() - if (in_insetAllowed) - return true; - in_insetAllowed = true; - bool const ret = owner() && owner()->insetAllowed(code); - in_insetAllowed = false; - return ret; -} - - bool InsetText::showInsetDialog(BufferView *) const { return false; @@ -499,12 +477,6 @@ void InsetText::removeNewlines() } -int InsetText::scroll(bool /*recursive*/) const -{ - return UpdatableInset::scroll(false); -} - - void InsetText::clearInset(Painter & pain, int x, int y) const { int w = dim_.wid; @@ -537,7 +509,8 @@ void InsetText::appendParagraphs(Buffer * buffer, ParagraphList & plist) ParagraphList::iterator pit = plist.begin(); ParagraphList::iterator ins = paragraphs().insert(paragraphs().end(), *pit); ++pit; - mergeParagraph(buffer->params(), paragraphs(), boost::prior(ins)); + mergeParagraph(buffer->params(), paragraphs(), + ins - paragraphs().begin() - 1); ParagraphList::iterator pend = plist.end(); for (; pit != pend; ++pit) diff --git a/src/insets/insettext.h b/src/insets/insettext.h index c4b5ef06ce..d1bfc83281 100644 --- a/src/insets/insettext.h +++ b/src/insets/insettext.h @@ -13,7 +13,6 @@ #define INSETTEXT_H #include "updatableinset.h" -#include "ParagraphList_fwd.h" #include "RowList_fwd.h" #include "lyxfont.h" #include "lyxtext.h" @@ -29,7 +28,7 @@ class Dimension; class LColor_color; class CursorSlice; class Painter; -class Paragraph; +class ParagraphList; class Row; @@ -91,8 +90,6 @@ public: /// FIXME, document void getCursorPos(CursorSlice const & cur, int & x, int & y) const; /// - bool insetAllowed(InsetOld::Code) const; - /// void setFont(BufferView *, LyXFont const &, bool toggleall = false, bool selectall = false); @@ -115,22 +112,12 @@ public: /// Appends \c list with all labels found within this inset. void getLabelList(Buffer const &, std::vector & list) const; /// - int scroll(bool recursive = true) const; - /// - void scroll(BufferView & bv, float sx) const { - UpdatableInset::scroll(bv, sx); - } - /// - void scroll(BufferView & bv, int offset) const { - UpdatableInset::scroll(bv, offset); - } - /// LyXText * getText(int) const; /// bool getStatus(LCursor & cur, FuncRequest const & cmd, FuncStatus &) const; /// mark as erased for change tracking - void markErased() { clear(true); }; + void markErased() { clear(true); } /** * Mark as new. Used when pasting in tabular, and adding rows * or columns. Note that pasting will ensure that tracking already @@ -156,9 +143,10 @@ public: /// ParagraphList & paragraphs() const; -private: +protected: /// void priv_dispatch(LCursor & cur, FuncRequest & cmd); +private: /// void updateLocal(LCursor &); /// @@ -184,12 +172,7 @@ private: */ int frame_color_; /// - mutable lyx::paroffset_type old_par; - - /** to remember old painted frame dimensions to clear it on - * the right spot! - */ - mutable bool in_insetAllowed; + mutable lyx::par_type old_par; public: /// mutable LyXText text_; diff --git a/src/insets/insetwrap.C b/src/insets/insetwrap.C index ec433af6eb..2163b026da 100644 --- a/src/insets/insetwrap.C +++ b/src/insets/insetwrap.C @@ -70,7 +70,7 @@ InsetWrap::InsetWrap(BufferParams const & bp, string const & type) setInsetName(type); LyXTextClass const & tclass = bp.getLyXTextClass(); if (tclass.hasLayout(caplayout)) - inset.paragraphs().begin()->layout(tclass[caplayout]); + paragraphs().begin()->layout(tclass[caplayout]); } @@ -180,13 +180,10 @@ int InsetWrap::latex(Buffer const & buf, ostream & os, OutputParams const & runparams) const { os << "\\begin{floating" << params_.type << '}'; - if (!params_.placement.empty()) { + if (!params_.placement.empty()) os << '[' << params_.placement << ']'; - } - os << '{' << params_.width.asLatexString() << "}%\n"; - - int const i = inset.latex(buf, os, runparams); - + os << '{' << params_.width.asLatexString() << "}%\n"; + int const i = InsetText::latex(buf, os, runparams); os << "\\end{floating" << params_.type << "}%\n"; return i + 2; } @@ -196,9 +193,8 @@ int InsetWrap::docbook(Buffer const & buf, ostream & os, OutputParams const & runparams) const { os << '<' << params_.type << '>'; - int const i = inset.docbook(buf, os, runparams); + int const i = InsetText::docbook(buf, os, runparams); os << "'; - return i; } @@ -218,7 +214,7 @@ bool InsetWrap::insetAllowed(InsetOld::Code code) const bool InsetWrap::showInsetDialog(BufferView * bv) const { - if (!inset.showInsetDialog(bv)) + if (!InsetText::showInsetDialog(bv)) InsetWrapMailer(const_cast(*this)).showDialog(bv); return true; } @@ -227,8 +223,8 @@ bool InsetWrap::showInsetDialog(BufferView * bv) const void InsetWrap::addToToc(lyx::toc::TocList & toclist, Buffer const & buf) const { // Now find the caption in the float... - ParagraphList::iterator tmp = inset.paragraphs().begin(); - ParagraphList::iterator end = inset.paragraphs().end(); + ParagraphList::iterator tmp = paragraphs().begin(); + ParagraphList::iterator end = paragraphs().end(); for (; tmp != end; ++tmp) { if (tmp->layout()->name() == caplayout) { diff --git a/src/iterators.C b/src/iterators.C index befe0a971c..bbf771ce5f 100644 --- a/src/iterators.C +++ b/src/iterators.C @@ -13,7 +13,6 @@ #include "iterators.h" #include "paragraph.h" -#include "PosIterator.h" #include "cursor.h" #include "buffer.h" #include "BufferView.h" @@ -25,6 +24,8 @@ #include +using lyx::par_type; + using boost::next; /// @@ -32,12 +33,11 @@ using boost::next; /// -ParPosition::ParPosition(ParagraphList::iterator p, ParagraphList const & pl) +ParPosition::ParPosition(par_type p, ParagraphList const & pl) : pit(p), plist(&pl) { - if (p != const_cast(pl).end()) { - it.reset(p->insetlist.begin()); - } + if (p != pl.size()) + it.reset(const_cast(pl[p].insetlist).begin()); } @@ -57,7 +57,7 @@ bool operator!=(ParPosition const & pos1, ParPosition const & pos2) /// ParIterator /// -ParIterator::ParIterator(ParagraphList::iterator pit, ParagraphList const & pl) +ParIterator::ParIterator(par_type pit, ParagraphList const & pl) { positions_.push_back(ParPosition(pit, pl)); } @@ -75,7 +75,7 @@ ParIterator::ParIterator(ParIterator const & pi) void ParIterator::operator=(ParIterator const & pi) { ParIterator tmp(pi); - swap(positions_ , tmp.positions_); + swap(positions_, tmp.positions_); } @@ -90,7 +90,7 @@ ParIterator & ParIterator::operator++() if (LyXText * text = (*p.it)->inset->getText(*p.index)) { ParagraphList & plist = text->paragraphs(); if (!plist.empty()) { - positions_.push_back(ParPosition(plist.begin(), plist)); + positions_.push_back(ParPosition(0, plist)); return *this; } } @@ -99,29 +99,28 @@ ParIterator & ParIterator::operator++() // The following line is needed because the value of // p.it may be invalid if inset was added/removed to // the paragraph pointed by the iterator - p.it.reset(p.pit->insetlist.begin()); + p.it.reset(const_cast((*p.plist)[p.pit].insetlist).begin()); } // Try to find the next inset that contains paragraphs - InsetList::iterator end = p.pit->insetlist.end(); + InsetList::iterator end = + const_cast((*p.plist)[p.pit].insetlist).end(); for (; *p.it != end; ++(*p.it)) { if (LyXText * text = (*p.it)->inset->getText(0)) { ParagraphList & plist = text->paragraphs(); if (!plist.empty()) { p.index.reset(0); - positions_.push_back(ParPosition(plist.begin(), plist)); + positions_.push_back(ParPosition(0, plist)); return *this; } } } // Try to go to the next paragarph - if (next(p.pit) != const_cast(p.plist)->end() - || positions_.size() == 1) { + if (p.pit + 1 != p.plist->size() || positions_.size() == 1) { ++p.pit; p.index.reset(); p.it.reset(); - return *this; } @@ -165,23 +164,23 @@ int ParIterator::index() const Paragraph & ParIterator::operator*() const { - return *positions_.back().pit; + return plist()[positions_.back().pit]; } -ParagraphList::iterator ParIterator::pit() const +par_type ParIterator::pit() const { return positions_.back().pit; } -ParagraphList::iterator ParIterator::operator->() const +Paragraph * ParIterator::operator->() const { - return positions_.back().pit; + return &plist()[positions_.back().pit]; } -ParagraphList::iterator ParIterator::outerPar() const +par_type ParIterator::outerPar() const { return positions_[0].pit; } @@ -199,22 +198,23 @@ ParagraphList & ParIterator::plist() const } -ParIterator::ParIterator(PosIterator const & pos) +ParIterator::ParIterator(DocumentIterator const & cur) { - int const size = pos.stack_.size(); + int const size = cur.size(); for (int i = 0; i < size; ++i) { - PosIteratorItem const & it = pos.stack_[i]; - ParPosition pp(it.pit, *it.pl); + CursorSlice sl = cur[i]; + ParPosition pp(sl.par(), sl.text()->paragraphs()); if (i < size - 1) { - InsetBase * inset = it.pit->getInset(it.pos); + Paragraph & par = sl.text()->paragraphs()[sl.par()]; + InsetBase * inset = par.getInset(sl.pos()); BOOST_ASSERT(inset); - InsetList::iterator beg = it.pit->insetlist.begin(); - InsetList::iterator end = it.pit->insetlist.end(); + InsetList::iterator beg = par.insetlist.begin(); + InsetList::iterator end = par.insetlist.end(); for ( ; beg != end && beg->inset != inset; ++beg) ; pp.it.reset(beg); - pp.index.reset(it.index - 1); + pp.index.reset(sl.idx() - 1); } positions_.push_back(pp); } @@ -238,8 +238,7 @@ bool operator!=(ParIterator const & iter1, ParIterator const & iter2) /// -ParConstIterator::ParConstIterator(ParagraphList::iterator pit, - ParagraphList const & pl) +ParConstIterator::ParConstIterator(par_type pit, ParagraphList const & pl) { positions_.push_back(ParPosition(pit, pl)); } @@ -265,7 +264,7 @@ ParConstIterator & ParConstIterator::operator++() if (LyXText * text = (*p.it)->inset->getText(*p.index)) { ParagraphList & plist = text->paragraphs(); if (!plist.empty()) { - positions_.push_back(ParPosition(plist.begin(), plist)); + positions_.push_back(ParPosition(0, plist)); return *this; } } @@ -274,29 +273,28 @@ ParConstIterator & ParConstIterator::operator++() // The following line is needed because the value of // p.it may be invalid if inset was added/removed to // the paragraph pointed by the iterator - p.it.reset(p.pit->insetlist.begin()); + p.it.reset(const_cast((*p.plist)[p.pit].insetlist).begin()); } // Try to find the next inset that contains paragraphs - InsetList::iterator end = p.pit->insetlist.end(); + InsetList::iterator end = + const_cast((*p.plist)[p.pit].insetlist).end(); for (; *p.it != end; ++(*p.it)) { if (LyXText * text = (*p.it)->inset->getText(0)) { ParagraphList & plist = text->paragraphs(); if (!plist.empty()) { p.index.reset(0); - positions_.push_back(ParPosition(plist.begin(), plist)); + positions_.push_back(ParPosition(0, plist)); return *this; } } } // Try to go to the next paragarph - if (next(p.pit) != const_cast(p.plist)->end() - || positions_.size() == 1) { + if (p.pit + 1 != p.plist->size() || positions_.size() == 1) { ++p.pit; p.index.reset(); p.it.reset(); - return *this; } @@ -310,19 +308,19 @@ ParConstIterator & ParConstIterator::operator++() Paragraph const & ParConstIterator::operator*() const { - return *positions_.back().pit; + return plist()[positions_.back().pit]; } -ParagraphList::const_iterator ParConstIterator::pit() const +par_type ParConstIterator::pit() const { return positions_.back().pit; } -ParagraphList::const_iterator ParConstIterator::operator->() const +Paragraph const * ParConstIterator::operator->() const { - return positions_.back().pit; + return &plist()[positions_.back().pit]; } diff --git a/src/iterators.h b/src/iterators.h index a68f7ff12d..b6f99ce897 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -12,8 +12,8 @@ #ifndef ITERATORS_H #define ITERATORS_H -#include "ParagraphList_fwd.h" #include "InsetList.h" +#include "ParagraphList_fwd.h" // only for ParagraphList::value_type #include "support/types.h" @@ -21,19 +21,19 @@ #include -class LyXText; -class InsetBase; -class Cursor; class Buffer; -class PosIterator; +class Cursor; +class InsetBase; +class LyXText; +class DocumentIterator; class ParPosition { public: /// - ParPosition(ParagraphList::iterator p, ParagraphList const & pl); + ParPosition(lyx::par_type p, ParagraphList const & pl); /// - ParagraphList::iterator pit; + lyx::par_type pit; /// ParagraphList const * plist; /// @@ -48,13 +48,13 @@ class ParIterator : public std::iterator< ParagraphList::value_type> { public: /// - ParIterator(ParagraphList::iterator pit, ParagraphList const & pl); + ParIterator(lyx::par_type pit, ParagraphList const & pl); /// ~ParIterator(); /// ParIterator(ParIterator const &); /// - ParIterator(PosIterator const &); + ParIterator(DocumentIterator const &); /// void operator=(ParIterator const &); /// @@ -62,11 +62,11 @@ public: /// Paragraph & operator*() const; /// - ParagraphList::iterator operator->() const; + Paragraph * operator->() const; /// This gives us the top-most parent paragraph - ParagraphList::iterator outerPar() const; + lyx::par_type outerPar() const; /// - ParagraphList::iterator pit() const; + lyx::par_type pit() const; /// ParagraphList & plist() const; /// returns 'innermost' LyXText @@ -99,7 +99,7 @@ class ParConstIterator : public std::iterator< ParagraphList::value_type> { public: /// - ParConstIterator(ParagraphList::iterator pit, ParagraphList const & pl); + ParConstIterator(lyx::par_type pit, ParagraphList const & pl); /// ~ParConstIterator(); /// @@ -107,22 +107,23 @@ public: /// ParConstIterator & operator++(); /// - ParagraphList::const_iterator pit() const; + lyx::par_type pit() const; /// Paragraph const & operator*() const; /// - ParagraphList::const_iterator operator->() const; + Paragraph const * operator->() const; /// ParagraphList const & plist() const; /// depth of nesting size_t size() const; + /// typedef std::vector PosHolder; - PosHolder const & positions() const - { - return positions_; - } + /// + PosHolder const & positions() const { return positions_; } + private: + /// PosHolder positions_; }; diff --git a/src/lfuns.h b/src/lfuns.h index 54319e8d8e..118a032a9a 100644 --- a/src/lfuns.h +++ b/src/lfuns.h @@ -9,8 +9,8 @@ * To add a new function: * - add a new enum constant immediately before LFUN_LASTACTION * - add an appropriate line in LyXAction.C - * - add a branch to the suitable ::dispatch() methods - * - add correct test in LyXFunc::getStatus() + * - add a branch to a suitable ::priv_dispatch() method + * - add correct test to the corresponding ::getStatus() method */ #ifndef LFUNS_H @@ -22,7 +22,9 @@ * through which the frontends communicate with the core. * * They are managed in LyXAction.C and handled in various - * ::dispatch() functions, starting with LyXFunc.C:dispatch() + * ::dispatch() functions, starting with LyXFunc.C:dispatch(), + * BufferView_pimpl::dispatch(), LCursor::dispatch() and + * Inset*::priv_dispatch(); */ enum kb_action { LFUN_UNKNOWN_ACTION = -1, diff --git a/src/lyxfind.C b/src/lyxfind.C index 66b4849de1..7f2d5bfee8 100644 --- a/src/lyxfind.C +++ b/src/lyxfind.C @@ -17,6 +17,7 @@ #include "buffer.h" #include "cursor.h" +#include "CutAndPaste.h" #include "BufferView.h" #include "debug.h" #include "iterators.h" @@ -24,7 +25,6 @@ #include "gettext.h" #include "lyxtext.h" #include "paragraph.h" -#include "PosIterator.h" #include "undo.h" #include "frontends/Alert.h" @@ -39,6 +39,9 @@ using lyx::support::lowercase; using lyx::support::uppercase; using lyx::support::split; +using lyx::par_type; +using lyx::pos_type; + using std::advance; using std::ostringstream; using std::string; @@ -56,21 +59,181 @@ bool parse_bool(string & howto) } -bool find(BufferView * bv, - string const & searchstr, bool cs, bool mw, bool fw); +class MatchString : public std::binary_function +{ +public: + MatchString(string const & str, bool cs, bool mw) + : str(str), cs(cs), mw(mw) + {} + + // returns true if the specified string is at the specified position + bool operator()(Paragraph const & par, lyx::pos_type pos) const + { + string::size_type const size = str.length(); + lyx::pos_type i = 0; + lyx::pos_type const parsize = par.size(); + for (i = 0; pos + i < parsize; ++i) { + if (string::size_type(i) >= size) + break; + if (cs && str[i] != par.getChar(pos + i)) + break; + if (!cs && uppercase(str[i]) != uppercase(par.getChar(pos + i))) + break; + } + + if (size != string::size_type(i)) + return false; + + // if necessary, check whether string matches word + if (mw) { + if (pos > 0 && IsLetterCharOrDigit(par.getChar(pos - 1))) + return false; + if (pos + lyx::pos_type(size) < parsize + && IsLetterCharOrDigit(par.getChar(pos + size))); + return false; + } + + return true; + } + +private: + // search string + string str; + // case sensitive + bool cs; + // match whole words only + bool mw; +}; -int replace(BufferView * bv, - string const & searchstr, string const & replacestr, - bool cs, bool mw, bool fw); +bool findForward(DocumentIterator & cur, MatchString const & match) +{ + for (; cur.size(); cur.forwardChar()) + if (match(cur.paragraph(), cur.pos())) + return true; + return false; +} + + +bool findBackwards(DocumentIterator & cur, MatchString const & match) +{ + for (; cur.size(); cur.backwardChar()) + if (match(cur.paragraph(), cur.pos())) + return true; + return false; +} + + +bool findChange(DocumentIterator & cur) +{ + for (; cur.size(); cur.forwardChar()) + if ((cur.paragraph().empty() || !cur.empty()) + && cur.paragraph().lookupChange(cur.pos()) != Change::UNCHANGED) + return true; + return false; +} + + +bool searchAllowed(BufferView * bv, string const & str) +{ + if (str.empty()) { + Alert::error(_("Search error"), _("Search string is empty")); + return false; + } + return bv->available(); +} + + +bool find(BufferView * bv, string const & searchstr, bool cs, bool mw, bool fw) +{ + if (!searchAllowed(bv, searchstr)) + return false; + + DocumentIterator cur = bv->cursor(); + + MatchString const match(searchstr, cs, mw); + + bool found = fw ? findForward(cur, match) : findBackwards(cur, match); + + if (found) + bv->putSelectionAt(cur, searchstr.length(), !fw); + + return found; +} int replaceAll(BufferView * bv, string const & searchstr, string const & replacestr, - bool cs, bool mw); + bool cs, bool mw) +{ + Buffer & buf = *bv->buffer(); + + if (!searchAllowed(bv, searchstr) || buf.isReadonly()) + return 0; + + recordUndoFullDocument(bv->cursor()); + + MatchString const match(searchstr, cs, mw); + int num = 0; + + int const rsize = replacestr.size(); + int const ssize = searchstr.size(); + + DocumentIterator cur = DocumentIterator(buf.inset()); + while (findForward(cur, match)) { + lyx::pos_type pos = cur.pos(); + LyXFont const font + = cur.paragraph().getFontSettings(buf.params(), pos); + int striked = ssize - cur.paragraph().erase(pos, pos + ssize); + cur.paragraph().insert(pos, replacestr, font); + for (int i = 0; i < rsize + striked; ++i) + cur.forwardChar(); + ++num; + } + + bv->text()->init(bv); + bv->putSelectionAt(DocumentIterator(buf.inset()), 0, false); + if (num) + buf.markDirty(); + return num; +} -bool findChange(PosIterator & cur, PosIterator const & end); +bool stringSelected(BufferView * bv, string const & searchstr, + bool cs, bool mw, bool fw) +{ + // if nothing selected or selection does not equal search + // string search and select next occurance and return + string const & str1 = searchstr; + string const str2 = bv->cursor().selectionAsString(false); + if ((cs && str1 != str2) || lowercase(str1) != lowercase(str2)) { + find(bv, searchstr, cs, mw, fw); + return false; + } + + return true; +} + + +int replace(BufferView * bv, string const & searchstr, + string const & replacestr, bool cs, bool mw, bool fw) +{ + if (!searchAllowed(bv, searchstr) || bv->buffer()->isReadonly()) + return 0; + + if (!stringSelected(bv, searchstr, cs, mw, fw)) + return 0; + + LCursor & cur = bv->cursor(); + lyx::cap::replaceSelectionWithString(cur, replacestr); + lyx::cap::setSelectionRange(cur, replacestr.length()); + cur.top() = fw ? cur.selEnd() : cur.selBegin(); + bv->buffer()->markDirty(); + find(bv, searchstr, cs, mw, fw); + bv->update(); + + return 1; +} } // namespace anon @@ -86,7 +249,6 @@ string const find2string(string const & search, << int(casesensitive) << ' ' << int(matchword) << ' ' << int(forward); - return ss.str(); } @@ -102,7 +264,6 @@ string const replace2string(string const & search, string const & replace, << int(matchword) << ' ' << int(all) << ' ' << int(forward); - return ss.str(); } @@ -153,11 +314,9 @@ void replace(BufferView * bv, FuncRequest const & ev) LyXView * lv = bv->owner(); - int const replace_count = all ? - ::replaceAll(bv, search, replace, - casesensitive, matchword) : - ::replace(bv, search, replace, - casesensitive, matchword, forward); + int const replace_count = all + ? ::replaceAll(bv, search, replace, casesensitive, matchword) + : ::replace(bv, search, replace, casesensitive, matchword, forward); if (replace_count == 0) { lv->message(_("String not found!")); @@ -178,21 +337,20 @@ bool findNextChange(BufferView * bv) if (!bv->available()) return false; - PosIterator cur = PosIterator(*bv); - PosIterator const endit = bv->buffer()->pos_iterator_end(); + DocumentIterator cur = DocumentIterator(bv->buffer()->inset()); - if (!findChange(cur, endit)) + if (!findChange(cur)) return false; - ParagraphList::iterator pit = cur.pit(); + Paragraph const & par = cur.paragraph(); pos_type pos = cur.pos(); - Change orig_change = pit->lookupChangeFull(pos); - pos_type parsize = pit->size(); + Change orig_change = par.lookupChangeFull(pos); + pos_type parsize = par.size(); pos_type end = pos; for (; end != parsize; ++end) { - Change change = pit->lookupChangeFull(end); + Change change = par.lookupChangeFull(end); if (change != orig_change) { // slight UI optimisation: for replacements, we get // text like : _old_new. Consider that as one change. @@ -210,194 +368,3 @@ bool findNextChange(BufferView * bv) } // lyx namespace -namespace { - -class MatchString : public std::binary_function -{ -public: - MatchString(string const & str, bool cs, bool mw) - : str(str), cs(cs), mw(mw) - {} - - // returns true if the specified string is at the specified position - bool operator()(Paragraph const & par, lyx::pos_type pos) const - { - string::size_type const size = str.length(); - lyx::pos_type i = 0; - lyx::pos_type const parsize = par.size(); - for (i = 0; pos + i < parsize; ++i) { - if (string::size_type(i) >= size) - break; - if (cs && str[i] != par.getChar(pos + i)) - break; - if (!cs && uppercase(str[i]) != uppercase(par.getChar(pos + i))) - break; - } - - if (size != string::size_type(i)) - return false; - - // if necessary, check whether string matches word - if (mw) { - if (pos > 0 && IsLetterCharOrDigit(par.getChar(pos - 1))) - return false; - if (pos + lyx::pos_type(size) < parsize - && IsLetterCharOrDigit(par.getChar(pos + size))); - return false; - } - - return true; - } - -private: - // search string - string str; - // case sensitive - bool cs; - // match whole words only - bool mw; -}; - - -bool findForward(PosIterator & cur, PosIterator const & end, - MatchString const & match) -{ - for (; cur != end; ++cur) { - if (match(*cur.pit(), cur.pos())) - return true; - } - return false; -} - - -bool findBackwards(PosIterator & cur, PosIterator const & beg, - MatchString const & match) -{ - while (beg != cur) { - --cur; - if (match(*cur.pit(), cur.pos())) - return true; - } - return false; -} - - -bool findChange(PosIterator & cur, PosIterator const & end) -{ - for (; cur != end; ++cur) { - if ((cur.pit()->empty() || !cur.at_end()) - && cur.pit()->lookupChange(cur.pos()) != Change::UNCHANGED) - return true; - } - return false; -} - - -bool searchAllowed(BufferView * bv, string const & str) -{ - if (str.empty()) { - Alert::error(_("Search error"), _("Search string is empty")); - return false; - } - return bv->available(); -} - - -bool find(BufferView * bv, string const & searchstr, bool cs, bool mw, bool fw) -{ - if (!searchAllowed(bv, searchstr)) - return false; - - PosIterator cur = PosIterator(*bv); - - MatchString const match(searchstr, cs, mw); - - PosIterator const end = bv->buffer()->pos_iterator_end(); - PosIterator const beg = bv->buffer()->pos_iterator_begin(); - - bool found = fw ? findForward(cur, end, match) - : findBackwards(cur, beg, match); - - if (found) - bv->putSelectionAt(cur, searchstr.length(), !fw); - - return found; -} - - -int replaceAll(BufferView * bv, - string const & searchstr, string const & replacestr, - bool cs, bool mw) -{ - Buffer & buf = *bv->buffer(); - - if (!searchAllowed(bv, searchstr) || buf.isReadonly()) - return 0; - - recordUndoFullDocument(bv->cursor()); - - PosIterator cur = buf.pos_iterator_begin(); - PosIterator const end = buf.pos_iterator_end(); - MatchString const match(searchstr, cs, mw); - int num = 0; - - int const rsize = replacestr.size(); - int const ssize = searchstr.size(); - - while (findForward(cur, end, match)) { - lyx::pos_type pos = cur.pos(); - LyXFont const font - = cur.pit()->getFontSettings(buf.params(), pos); - int striked = ssize - cur.pit()->erase(pos, pos + ssize); - cur.pit()->insert(pos, replacestr, font); - advance(cur, rsize + striked); - ++num; - } - - PosIterator beg = buf.pos_iterator_begin(); - bv->text()->init(bv); - bv->putSelectionAt(beg, 0, false); - if (num) - buf.markDirty(); - return num; -} - - -bool stringSelected(BufferView * bv, string const & searchstr, - bool cs, bool mw, bool fw) -{ - // if nothing selected or selection does not equal search - // string search and select next occurance and return - string const & str1 = searchstr; - string const str2 = bv->cursor().selectionAsString(false); - if ((cs && str1 != str2) || lowercase(str1) != lowercase(str2)) { - find(bv, searchstr, cs, mw, fw); - return false; - } - - return true; -} - - -int replace(BufferView * bv, string const & searchstr, - string const & replacestr, bool cs, bool mw, bool fw) -{ - if (!searchAllowed(bv, searchstr) || bv->buffer()->isReadonly()) - return 0; - - if (!stringSelected(bv, searchstr, cs, mw, fw)) - return 0; - - LyXText * text = bv->getLyXText(); - - text->replaceSelectionWithString(bv->cursor(), replacestr); - text->setSelectionRange(bv->cursor(), replacestr.length()); - bv->cursor().top() = fw ? bv->cursor().selEnd() : bv->cursor().selBegin(); - bv->buffer()->markDirty(); - find(bv, searchstr, cs, mw, fw); - bv->update(); - - return 1; -} - -} //namespace anon diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 470f830b93..e766c8c66b 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -389,14 +389,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const if (!inset) break; - // jump back to owner if an InsetText, so - // we get back to the InsetTabular or whatever - if (inset->lyxCode() == InsetOld::TEXT_CODE) - inset = inset->owner(); - lyxerr << "inset 2: " << inset << endl; - if (!inset) - break; - InsetOld::Code code = inset->lyxCode(); switch (code) { case InsetOld::TABULAR_CODE: @@ -431,6 +423,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const if (!buf) enable = name == "aboutlyx" || name == "file" + || name == "forks" || name == "preferences" || name == "texinfo"; else if (name == "print") @@ -586,7 +579,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) bool const fw = action == LFUN_WORDFINDFORWARD; string const data = lyx::find::find2string(searched_string, true, false, fw); - view()->dispatch(FuncRequest(LFUN_WORD_FIND, data)); + lyx::find::find(view(), FuncRequest(LFUN_WORD_FIND, data)); break; } @@ -694,13 +687,21 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; case LFUN_QUIT: -#if 0 +#if 1 // test speed of DocumentIterator lyxerr << "start" << endl; for (DocumentIterator it(owner->buffer()->inset()), end; it != end; it.forwardPos()) ; lyxerr << "end" << endl; +#endif +#if 1 + // show some sizes + lyxerr << "sizeof Paragraph: " << sizeof(Paragraph) << endl; + lyxerr << "sizeof Spacing: " << sizeof(Spacing) << endl; + lyxerr << "sizeof LyXLength: " << sizeof(LyXLength) << endl; + lyxerr << "sizeof LyXFont: " << sizeof(LyXFont) << endl; + lyxerr << "sizeof LyXAlignment: " << sizeof(LyXAlignment) << endl; #endif QuitLyX(); break; @@ -1108,6 +1109,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; } + case LFUN_BREAKLINE: { +#warning swallow 'Return' if the minibuffer is focused. But how? + } + default: { DispatchResult res = view()->cursor().dispatch(cmd); if (!res.dispatched()); @@ -1115,22 +1120,22 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; } } - } - if (view()->available()) { - view()->fitCursor(); - view()->update(); - view()->cursor().updatePos(); - // if we executed a mutating lfun, mark the buffer as dirty - if (getStatus(cmd).enabled() - && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) - && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly)) - view()->buffer()->markDirty(); - } + if (view()->available()) { + view()->fitCursor(); + view()->update(); + view()->cursor().updatePos(); + // if we executed a mutating lfun, mark the buffer as dirty + if (getStatus(cmd).enabled() + && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) + && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly)) + view()->buffer()->markDirty(); + } - if (view()->cursor().inTexted()) { - view()->owner()->updateLayoutChoice(); - sendDispatchMessage(getMessage(), cmd, verbose); + if (view()->cursor().inTexted()) { + view()->owner()->updateLayoutChoice(); + sendDispatchMessage(getMessage(), cmd, verbose); + } } } diff --git a/src/lyxtext.h b/src/lyxtext.h index 01d0c7a61b..b2bcdf6358 100644 --- a/src/lyxtext.h +++ b/src/lyxtext.h @@ -20,8 +20,8 @@ #include "lyxfont.h" #include "layout.h" #include "lyxlayout_ptr_fwd.h" -#include "ParagraphList_fwd.h" #include "RowList_fwd.h" +#include "ParagraphList_fwd.h" #include @@ -39,12 +39,10 @@ class LCursor; class LyXTextClass; class MetricsInfo; class PainterInfo; -class Paragraph; class Row; class RowMetrics; class Spacing; -class UpdatableInset; -class VSpace; + /// This class encapsulates the main text data and operations in LyX class LyXText { @@ -52,7 +50,7 @@ public: /// typedef lyx::pos_type pos_type; /// - typedef lyx::paroffset_type par_type; + typedef lyx::par_type par_type; /// constructor explicit LyXText(BufferView *); @@ -62,36 +60,32 @@ public: /// update y coordinate cache of all paragraphs void updateParPositions(); /// - LyXFont getFont(ParagraphList::iterator pit, pos_type pos) const; + LyXFont getFont(par_type pit, pos_type pos) const; /// - LyXFont getLayoutFont(ParagraphList::iterator pit) const; + LyXFont getLayoutFont(par_type pit) const; /// - LyXFont getLabelFont(ParagraphList::iterator pit) const; + LyXFont getLabelFont(par_type pit) const; /// - void setCharFont(ParagraphList::iterator pit, - pos_type pos, LyXFont const & font); - void setCharFont(ParagraphList::iterator pit, - pos_type pos, LyXFont const & font, bool toggleall); + void setCharFont(par_type pit, pos_type pos, LyXFont const & font); + /// + void setCharFont(par_type pit, pos_type pos, LyXFont const & font, + bool toggleall); /// what you expect when pressing at cursor position void breakParagraph(LCursor & cur, char keep_layout = 0); - /** set layout over selection and make a total rebreak of - those paragraphs - */ - ParagraphList::iterator - setLayout(ParagraphList::iterator start, - ParagraphList::iterator end, - std::string const & layout); + /// set layout over selection + par_type setLayout(par_type start, par_type end, + std::string const & layout); /// void setLayout(LCursor & cur, std::string const & layout); - /// Increase or decrease the nesting depth of the selected paragraph(s) /// what type of depth change to make enum DEPTH_CHANGE { INC_DEPTH, DEC_DEPTH }; + /// Increase or decrease the nesting depth of the selected paragraph(s) void changeDepth(LCursor & cur, DEPTH_CHANGE type); /// Returns whether something would be changed by changeDepth @@ -101,10 +95,9 @@ public: void setFont(LCursor & cur, LyXFont const &, bool toggleall = false); /// rebreaks all paragaphs between the given pars. - void redoParagraphs(ParagraphList::iterator begin, - ParagraphList::iterator end); + void redoParagraphs(par_type begin, par_type end); /// rebreaks the given par - void redoParagraph(ParagraphList::iterator pit); + void redoParagraph(par_type pit); /// rebreaks the cursor par void redoParagraph(LCursor & cur); @@ -142,12 +135,8 @@ public: /// access to out BufferView. This should go... BufferView * bv() const; - /// returns an iterator pointing to a cursor paragraph - ParagraphList::iterator getPar(CursorSlice const & cursor) const; - /// - ParagraphList::iterator getPar(par_type par) const; - /// - int parOffset(ParagraphList::iterator pit) const; + /// access to individual paragraphs + Paragraph & getPar(par_type par) const; // Returns the current font and depth as a message. std::string LyXText::currentState(LCursor & cur); @@ -155,13 +144,12 @@ public: * y-coordinate (relative to the whole text). y is set to the * real beginning of this row */ - RowList::iterator getRowNearY(int y, - ParagraphList::iterator & pit) const; + RowList::iterator getRowNearY(int y, par_type & pit) const; /** returns the column near the specified x-coordinate of the row x is set to the real beginning of this column */ - pos_type getColumnNearX(ParagraphList::iterator pit, + pos_type getColumnNearX(par_type pit, Row const & row, int & x, bool & boundary) const; /** Find the word under \c from in the relative location @@ -243,15 +231,8 @@ public: }; /// Change the case of the word at cursor position. void changeCase(LCursor & cur, TextCase action); - /// returns success bool toggleInset(LCursor & cur); - /// - void cutSelection(LCursor & cur, bool doclear = true, bool realcut = true); - /// - void copySelection(LCursor & cur); - /// - void pasteSelection(LCursor & cur, size_t sel_index = 0); /** the DTP switches for paragraphs. LyX will store the top settings always in the first physical paragraph, the bottom settings in the @@ -266,16 +247,6 @@ public: /* these things are for search and replace */ - /** - * Sets the selection from the current cursor position to length - * characters to the right. No safety checks. - */ - void setSelectionRange(LCursor & cur, pos_type length); - /// simply replace using the font of the first selected character - void replaceSelectionWithString(LCursor & cur, std::string const & str); - /// replace selection helper - void replaceSelection(LCursor & cur); - /// needed to insert the selection void insertStringAsLines(LCursor & cur, std::string const & str); /// needed to insert the selection @@ -303,9 +274,9 @@ public: InsetBase * checkInsetHit(int x, int y); /// - int singleWidth(ParagraphList::iterator pit, pos_type pos) const; + int singleWidth(par_type pit, pos_type pos) const; /// - int singleWidth(ParagraphList::iterator pit, + int singleWidth(par_type pit, pos_type pos, char c, LyXFont const & Font) const; /// return the color of the canvas @@ -317,15 +288,14 @@ public: * in LaTeX the beginning of the text fits in some cases * (for example sections) exactly the label-width. */ - int leftMargin(ParagraphList::iterator pit, pos_type pos) const; - int leftMargin(ParagraphList::iterator pit) const; + int leftMargin(par_type pit, pos_type pos) const; + int leftMargin(par_type pit) const; /// int rightMargin(Paragraph const & par) const; /** this calculates the specified parameters. needed when setting * the cursor and when creating a visible row */ - RowMetrics - computeRowMetrics(ParagraphList::iterator pit, Row const & row) const; + RowMetrics computeRowMetrics(par_type pit, Row const & row) const; /// access to our paragraphs ParagraphList & paragraphs() const; @@ -339,16 +309,14 @@ public: /// return row "behind" last row of text RowList::iterator endRow() const; /// return next row crossing paragraph boundaries - void nextRow(ParagraphList::iterator & pit, - RowList::iterator & rit) const; + void nextRow(par_type & pit, RowList::iterator & rit) const; /// return previous row crossing paragraph boundaries - void previousRow(ParagraphList::iterator & pit, - RowList::iterator & rit) const; + void previousRow(par_type & pit, RowList::iterator & rit) const; /// is this row the last in the text? - bool isLastRow(ParagraphList::iterator pit, Row const & row) const; + bool isLastRow(par_type pit, Row const & row) const; /// is this row the first in the text? - bool isFirstRow(ParagraphList::iterator pit, Row const & row) const; + bool isFirstRow(par_type pit, Row const & row) const; /// double spacing(Paragraph const & par) const; @@ -376,13 +344,13 @@ public: /// friend class LyXScreen; +public: /// unsigned int width_; /// int maxwidth_; /// int height_; -public: /// the current font settings LyXFont current_font; /// the current font @@ -398,7 +366,7 @@ public: /// mutable Bidi bidi; /// - ParagraphList paragraphs_; + ParagraphList pars_; /// absolute document pixel coordinates of this LyXText mutable int xo_; @@ -407,38 +375,28 @@ public: /// our 'outermost' Font LyXFont font_; - /// - double fill_separator(Row const & row) const; - /// - double fill_hfill(Row const & row) const; - /// - double - fill_label_hfill(ParagraphList::iterator pit, Row const & row) const; - private: /// return past-the-last paragraph influenced by a layout /// change on pit - ParagraphList::iterator undoSpan(ParagraphList::iterator pit); + par_type undoSpan(par_type pit); /// rebreaks the given par - void redoParagraphInternal(ParagraphList::iterator pit); + void redoParagraphInternal(par_type pit); /// used in setlayout void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par); /// Calculate and set the height of the row - void setHeightOfRow(ParagraphList::iterator, Row & row); + void setHeightOfRow(par_type, Row & row); // fix the cursor `cur' after a characters has been deleted at `where' // position. Called by deleteEmptyParagraphMechanism void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where); - /// delete double space (false) or empty paragraphs (true) around old_cursor - bool deleteEmptyParagraphMechanism( - CursorSlice & cur, - CursorSlice const & old_cursor); + /// delete double space or empty paragraphs around old cursor + bool deleteEmptyParagraphMechanism(LCursor & cur, LCursor const & old); /// - void setCounter(Buffer const &, ParagraphList::iterator pit); + void setCounter(Buffer const &, par_type pit); /// void deleteWordForward(LCursor & cur); /// @@ -448,13 +406,13 @@ private: /// sets row.end to the pos value *after* which a row should break. /// for example, the pos after which isNewLine(pos) == true - void rowBreakPoint(ParagraphList::iterator pit, Row & row) const; + void rowBreakPoint(par_type pit, Row & row) const; /// sets row.width to the minimum space a row needs on the screen in pixel - void setRowWidth(ParagraphList::iterator pit, Row & row) const; + void setRowWidth(par_type pit, Row & row) const; /// the minimum space a manual label needs on the screen in pixels - int labelFill(ParagraphList::iterator pit, Row const & row) const; + int labelFill(par_type pit, Row const & row) const; /// FIXME - int labelEnd(ParagraphList::iterator pit) const; + int labelEnd(par_type pit) const; /// void charInserted(); diff --git a/src/mathed/math_mboxinset.C b/src/mathed/math_mboxinset.C index d1088bdbd4..eaaad2c1d0 100644 --- a/src/mathed/math_mboxinset.C +++ b/src/mathed/math_mboxinset.C @@ -28,10 +28,11 @@ using std::endl; MathMBoxInset::MathMBoxInset(BufferView & bv) : text_(&bv), bv_(&bv) { + text_.paragraphs().clear(); text_.paragraphs().push_back(Paragraph()); text_.paragraphs().back(). layout(bv.buffer()->params().getLyXTextClass().defaultLayout()); - text_.redoParagraph(text_.paragraphs().begin()); + text_.redoParagraph(0); } diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 7a331083ec..93258bf57b 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -200,8 +200,8 @@ void MathNestInset::drawSelection(PainterInfo & pi, int, int) const return; if (!ptr_cmp(&cur.inset(), this)) return; - CursorSlice & s1 = cur.selBegin(); - CursorSlice & s2 = cur.selEnd(); + CursorSlice s1 = cur.selBegin(); + CursorSlice s2 = cur.selEnd(); if (s1.idx() == s2.idx()) { MathArray const & c = cell(s1.idx()); int x1 = c.xo() + c.pos2x(s1.pos()); @@ -1146,29 +1146,31 @@ bool MathNestInset::script(LCursor & cur, bool up) cur.macroModeClose(); string safe = cur.grabAndEraseSelection(); - if (asScriptInset() && cur.idx() == 2) { + if (asScriptInset() && cur.idx() == 0) { // we are in a nucleus of a script inset, move to _our_ script - asScriptInset()->ensure(up); - cur.idx() = up; + MathScriptInset * inset = asScriptInset(); + lyxerr << " going to cell " << inset->idxOfScript(up) << endl; + inset->ensure(up); + cur.idx() = inset->idxOfScript(up); cur.pos() = 0; } else if (cur.pos() != 0 && cur.prevAtom()->asScriptInset()) { --cur.pos(); - cur.nextAtom().nucleus()->asScriptInset()->ensure(up); - cur.push(*cur.nextInset()); - cur.idx() = up; + MathScriptInset * inset = cur.nextAtom().nucleus()->asScriptInset(); + cur.push(*inset); + cur.idx() = inset->idxOfScript(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.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.idx() = up; + // convert the thing to our left to a scriptinset or create a new + // one if in the very first position of the array + if (cur.pos() == 0) { + cur.insert(new MathScriptInset(up)); + } else { + --cur.pos(); + cur.cell()[cur.pos()] = MathAtom(new MathScriptInset(cur.nextAtom(), up)); + } + MathScriptInset * inset = cur.nextAtom().nucleus()->asScriptInset(); + cur.push(*inset); + cur.idx() = 1; cur.pos() = 0; } cur.paste(safe); diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index be25b5cea8..7ccd69f88d 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -30,27 +30,19 @@ using std::endl; MathScriptInset::MathScriptInset() - : MathNestInset(3), limits_(0) -{ - script_[0] = false; - script_[1] = false; -} + : MathNestInset(1), cell_1_is_up_(false), limits_(0) +{} MathScriptInset::MathScriptInset(bool up) - : MathNestInset(3), limits_(0) -{ - script_[0] = !up; - script_[1] = up; -} + : MathNestInset(2), cell_1_is_up_(up), limits_(0) +{} MathScriptInset::MathScriptInset(MathAtom const & at, bool up) - : MathNestInset(3), limits_(0) + : MathNestInset(2), cell_1_is_up_(up), limits_(0) { - script_[0] = !up; - script_[1] = up; - cell(2).push_back(at); + cell(0).push_back(at); } @@ -75,7 +67,7 @@ MathScriptInset * MathScriptInset::asScriptInset() bool MathScriptInset::idxFirst(LCursor & cur) const { - cur.idx() = 2; + cur.idx() = 0; cur.pos() = 0; return true; } @@ -83,7 +75,7 @@ bool MathScriptInset::idxFirst(LCursor & cur) const bool MathScriptInset::idxLast(LCursor & cur) const { - cur.idx() = 2; + cur.idx() = 0; cur.pos() = nuc().size(); return true; } @@ -91,13 +83,13 @@ bool MathScriptInset::idxLast(LCursor & cur) const MathArray const & MathScriptInset::down() const { - return cell(0); + return nargs() == 2 ? cell(2) : cell(1); } MathArray & MathScriptInset::down() { - return cell(0); + return nargs() == 2 ? cell(2) : cell(1); } @@ -115,19 +107,30 @@ MathArray & MathScriptInset::up() void MathScriptInset::ensure(bool up) { - script_[up] = true; + if (nargs() == 1) { + // just nucleus so far + cells_.push_back(MathArray()); + cell_1_is_up_ = up; + } else if (nargs() == 2 && !has(up)) { + if (up) { + cells_.push_back(cell(1)); + cell(1).clear(); + } else { + cells_.push_back(MathArray()); + } + } } MathArray const & MathScriptInset::nuc() const { - return cell(2); + return cell(0); } MathArray & MathScriptInset::nuc() { - return cell(2); + return cell(0); } @@ -200,10 +203,12 @@ int MathScriptInset::ndes() const void MathScriptInset::metrics(MetricsInfo & mi, Dimension & dim) const { - cell(2).metrics(mi); - ScriptChanger dummy(mi.base); cell(0).metrics(mi); - cell(1).metrics(mi); + ScriptChanger dummy(mi.base); + if (nargs() > 1) + cell(1).metrics(mi); + if (nargs() > 2) + cell(2).metrics(mi); dim.wid = 0; if (hasLimits()) { dim.wid = nwid(); @@ -291,26 +296,51 @@ bool MathScriptInset::hasLimits() const void MathScriptInset::removeScript(bool up) { - cell(up).clear(); - script_[up] = false; + if (nargs() == 2) { + if (up == cell_1_is_up_) + cells_.pop_back(); + } else if (nargs() == 3) { + if (up == true) { + swap(cells_[1], cells_[2]); + cell_1_is_up_ = false; + } else { + cell_1_is_up_ = true; + } + } } bool MathScriptInset::has(bool up) const { - return script_[up]; + return idxOfScript(up); } bool MathScriptInset::hasUp() const { - return script_[1]; + //lyxerr << "hasUp: " << bool(idxOfScript(true)) << endl; + //lyxerr << "1up: " << bool(cell_1_is_up_) << endl; + return idxOfScript(true); } bool MathScriptInset::hasDown() const { - return script_[0]; + //lyxerr << "hasDown: " << bool(idxOfScript(false)) << endl; + //lyxerr << "1up: " << bool(cell_1_is_up_) << endl; + return idxOfScript(false); +} + + +InsetBase::idx_type MathScriptInset::idxOfScript(bool up) const +{ + if (nargs() == 1) + return 0; + if (nargs() == 2) + return cell_1_is_up_ == up ? 1 : 0; + if (nargs() == 3) + return up ? 1 : 2; + BOOST_ASSERT(false); } @@ -328,38 +358,44 @@ bool MathScriptInset::idxLeft(LCursor &) const bool MathScriptInset::idxUpDown(LCursor & cur, bool up) const { - if (cur.idx() == 1) { - // if we are 'up' we can't go further up - if (up) - return false; - // otherwise go to last base position - cur.idx() = 2; - cur.pos() = cur.lastpos(); - } - - else if (cur.idx() == 0) { - // if we are 'down' we can't go further down - if (!up) - return false; - cur.idx() = 2; - cur.pos() = cur.lastpos(); - } - - else { - // in nucleus - // don't go up/down if there is no cell. + // in nucleus? + if (cur.idx() == 0) { + // don't go up/down if there is no cell in this direction if (!has(up)) return false; // go up/down only if in the last position // or in the first position of something with displayed limits if (cur.pos() == cur.lastpos() || (cur.pos() == 0 && hasLimits())) { - cur.idx() = up; + cur.idx() = idxOfScript(up); cur.pos() = 0; return true; } return false; } - return true; + + // Are we 'up'? + if (cur.idx() == idxOfScript(true)) { + // can't go further up + if (up) + return false; + // otherwise go to last position in the nucleus + cur.idx() = 0; + cur.pos() = cur.lastpos(); + return true; + } + + // Are we 'down'? + if (cur.idx() == idxOfScript(false)) { + // can't go further down + if (!up) + return false; + // otherwise go to last position in the nucleus + cur.idx() = 0; + cur.pos() = cur.lastpos(); + return true; + } + + return false; } @@ -506,9 +542,16 @@ void MathScriptInset::notifyCursorLeaves(idx_type idx) MathNestInset::notifyCursorLeaves(idx); // remove empty scripts if possible - if (idx != 2 && script_[idx] && cell(idx).empty()) { - cell(idx).clear(); - script_[idx] = false; + if (idx == 2 && cell(2).empty()) { + removeScript(false); // must be a subscript... + } else if (idx == 1 && cell(1).empty()) { + if (nargs() == 2) { + cell_1_is_up_ = false; + cell(1) = cell(2); + cells_.pop_back(); + } else if (nargs() == 1) { + cells_.pop_back(); + } } } diff --git a/src/mathed/math_scriptinset.h b/src/mathed/math_scriptinset.h index 5a332a185d..13b95c1043 100644 --- a/src/mathed/math_scriptinset.h +++ b/src/mathed/math_scriptinset.h @@ -15,7 +15,10 @@ #include "math_nestinset.h" -/// An inset for super- and subscripts. +// An inset for super- and subscripts or both. The 'nucleus' is always +// cell 0. If there is just one script, it's cell 1 and cell_1_is_up_ +// is set accordingly. If both are used, cell 1 is up and cell 2 is down. + class MathScriptInset : public MathNestInset { public: /// create inset without scripts @@ -45,8 +48,6 @@ public: bool idxFirst(LCursor & cur) const; /// Target pos when we enter the inset from the right by pressing "Left" bool idxLast(LCursor & cur) const; - /// can we enter this cell? - bool validCell(idx_type i) const { return i == 2 || script_[i]; } /// write LaTeX and Lyx code void write(WriteStream & os) const; @@ -88,6 +89,8 @@ public: bool hasDown() const; /// do we have a script? bool has(bool up) const; + /// what idx has super/subscript? + idx_type idxOfScript(bool up) const; /// remove script void removeScript(bool up); /// make sure a script is accessible @@ -122,7 +125,7 @@ private: void notifyCursorLeaves(idx_type idx); /// possible subscript (index 0) and superscript (index 1) - bool script_[2]; + bool cell_1_is_up_; /// 1 - "limits", -1 - "nolimits", 0 - "default" int limits_; }; diff --git a/src/output_docbook.C b/src/output_docbook.C index c57bb0d321..69340132f0 100644 --- a/src/output_docbook.C +++ b/src/output_docbook.C @@ -227,8 +227,9 @@ void docbookParagraphs(Buffer const & buf, break; } - par->simpleDocBookOnePar(buf, os, outerFont(par, paragraphs), - runparams, depth + 1 + command_depth, labelid); + par->simpleDocBookOnePar(buf, os, + outerFont(par - const_cast(paragraphs).begin(), paragraphs), + runparams, depth + 1 + command_depth, labelid); // write closing SGML tags switch (style->latextype) { diff --git a/src/output_docbook.h b/src/output_docbook.h index 7b268315c8..5c5092c4ff 100644 --- a/src/output_docbook.h +++ b/src/output_docbook.h @@ -13,15 +13,13 @@ #ifndef OUTPUT_DOCBOOK_H #define OUTPUT_DOCBOOK_H -#include "ParagraphList_fwd.h" - #include class Buffer; class OutputParams; +class ParagraphList; /// - void docbookParagraphs(Buffer const & buf, ParagraphList const & paragraphs, std::ostream & os, diff --git a/src/output_latex.C b/src/output_latex.C index f775d4af12..5863c127f0 100644 --- a/src/output_latex.C +++ b/src/output_latex.C @@ -320,7 +320,7 @@ TeXOnePar(Buffer const & buf, os << everypar; bool need_par = pit->simpleTeXOnePar(buf, bparams, - outerFont(pit, paragraphs), + outerFont(pit - const_cast(paragraphs).begin(), paragraphs), os, texrow, runparams); // Make sure that \\par is done with the font of the last @@ -332,7 +332,9 @@ 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 - const_cast(paragraphs).begin(), +paragraphs); LyXFont const font = (pit->empty() diff --git a/src/output_latex.h b/src/output_latex.h index f2a47b0de3..1bd15a03ea 100644 --- a/src/output_latex.h +++ b/src/output_latex.h @@ -12,12 +12,11 @@ #ifndef OUTPUT_LATEX_H #define OUTPUT_LATEX_H -#include "ParagraphList_fwd.h" - #include class Buffer; class OutputParams; +class ParagraphList; class TexRow; /// Just a wrapper for the method below, first creating the ofstream. diff --git a/src/output_linuxdoc.C b/src/output_linuxdoc.C index 7ce1e932bc..cdf5cce3cc 100644 --- a/src/output_linuxdoc.C +++ b/src/output_linuxdoc.C @@ -17,6 +17,7 @@ #include "bufferparams.h" #include "paragraph.h" #include "paragraph_funcs.h" +#include "ParagraphList_fwd.h" #include "ParagraphParameters.h" #include "sgml.h" @@ -134,7 +135,8 @@ void linuxdocParagraphs(Buffer const & buf, break; } - pit->simpleLinuxDocOnePar(buf, os, outerFont(pit, paragraphs), + pit->simpleLinuxDocOnePar(buf, os, + outerFont(pit - const_cast(paragraphs).begin(), paragraphs), runparams, depth); os << "\n"; diff --git a/src/output_linuxdoc.h b/src/output_linuxdoc.h index 7517680e39..263c65d045 100644 --- a/src/output_linuxdoc.h +++ b/src/output_linuxdoc.h @@ -13,11 +13,10 @@ #ifndef OUTPUT_LINUXDOC_H #define OUTPUT_LINUXDOC_H -#include "ParagraphList_fwd.h" - #include class Buffer; +class ParagraphList; class OutputParams; /// diff --git a/src/output_plaintext.C b/src/output_plaintext.C index 70c72e59a7..a852a49e40 100644 --- a/src/output_plaintext.C +++ b/src/output_plaintext.C @@ -19,6 +19,7 @@ #include "output.h" #include "outputparams.h" #include "paragraph.h" +#include "ParagraphList_fwd.h" #include "ParagraphParameters.h" #include "support/gzstream.h" @@ -51,9 +52,8 @@ void writeFileAscii(Buffer const & buf, } -void writeFileAscii(Buffer const & buf, - ostream & os, - OutputParams const & runparams) +void writeFileAscii(Buffer const & buf, ostream & os, + OutputParams const & runparams) { Buffer & tmp = const_cast(buf); ParagraphList par = const_cast(tmp.paragraphs()); diff --git a/src/output_plaintext.h b/src/output_plaintext.h index 1b32a558e3..871c264644 100644 --- a/src/output_plaintext.h +++ b/src/output_plaintext.h @@ -12,16 +12,18 @@ #ifndef OUTPUT_PLAINTEXT_H #define OUTPUT_PLAINTEXT_H -#include "ParagraphList_fwd.h" - #include #include class Buffer; class OutputParams; +class Paragraph; + /// -void writeFileAscii(Buffer const & buf, std::string const &, OutputParams const &); +void writeFileAscii(Buffer const & buf, std::string const &, + OutputParams const &); + /// void writeFileAscii(Buffer const & buf, std::ostream &, OutputParams const &); diff --git a/src/paragraph.C b/src/paragraph.C index 365600571c..7a91061cd0 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -32,6 +32,7 @@ #include "lyxrow.h" #include "outputparams.h" #include "paragraph_funcs.h" +#include "ParagraphList_fwd.h" #include "sgml.h" #include "texrow.h" #include "vspace.h" @@ -64,10 +65,15 @@ using std::ostream; using std::ostringstream; +ParagraphList::ParagraphList() +{} + + Paragraph::Paragraph() : y(0), height(0), begin_of_body_(0), pimpl_(new Paragraph::Pimpl(this)) { + //lyxerr << "sizeof Paragraph::Pimpl: " << sizeof(Paragraph::Pimpl) << endl; itemdepth = 0; params().clear(); } @@ -717,8 +723,8 @@ namespace { bool noTrivlistCentering(UpdatableInset const * inset) { - if (inset && inset->owner()) { - InsetBase::Code const code = inset->owner()->lyxCode(); + if (inset) { + InsetBase::Code const code = inset->lyxCode(); return code == InsetBase::FLOAT_CODE || code == InsetBase::WRAP_CODE; } @@ -1459,21 +1465,15 @@ bool IsInsetChar(char c) bool Paragraph::isHfill(pos_type pos) const { - return IsInsetChar(getChar(pos)) - && getInset(pos)->lyxCode() == InsetBase::HFILL_CODE; -} - - -bool Paragraph::isInset(pos_type pos) const -{ - return IsInsetChar(getChar(pos)); + return + isInset(pos) && getInset(pos)->lyxCode() == InsetBase::HFILL_CODE; } bool Paragraph::isNewline(pos_type pos) const { - return IsInsetChar(getChar(pos)) - && getInset(pos)->lyxCode() == InsetBase::NEWLINE_CODE; + return + isInset(pos) && getInset(pos)->lyxCode() == InsetBase::NEWLINE_CODE; } @@ -1535,8 +1535,7 @@ bool Paragraph::isRightToLeftPar(BufferParams const & bparams) const { return lyxrc.rtl_support && getParLanguage(bparams)->RightToLeft() - && !(inInset() && inInset()->owner() && - inInset()->owner()->lyxCode() == InsetBase::ERT_CODE); + && !(inInset() && inInset()->lyxCode() == InsetBase::ERT_CODE); } @@ -1641,11 +1640,6 @@ string const Paragraph::asString(Buffer const & buffer, void Paragraph::setInsetOwner(UpdatableInset * inset) { pimpl_->inset_owner = inset; - InsetList::iterator it = insetlist.begin(); - InsetList::iterator end = insetlist.end(); - for (; it != end; ++it) - if (it->inset) - it->inset->setOwner(inset); } @@ -1802,8 +1796,8 @@ bool Paragraph::isFreeSpacing() const // for now we just need this, later should we need this in some // other way we can always add a function to InsetBase too. - if (pimpl_->inset_owner && pimpl_->inset_owner->owner()) - return pimpl_->inset_owner->owner()->lyxCode() == InsetBase::ERT_CODE; + if (pimpl_->inset_owner) + return pimpl_->inset_owner->lyxCode() == InsetBase::ERT_CODE; return false; } @@ -1812,8 +1806,8 @@ bool Paragraph::allowEmpty() const { if (layout()->keepempty) return true; - if (pimpl_->inset_owner && pimpl_->inset_owner->owner()) - return pimpl_->inset_owner->owner()->lyxCode() == InsetBase::ERT_CODE; + if (pimpl_->inset_owner) + return pimpl_->inset_owner->lyxCode() == InsetBase::ERT_CODE; return false; } @@ -1887,3 +1881,5 @@ unsigned char Paragraph::transformChar(unsigned char c, pos_type pos) const return Encodings::TransformChar(c, Encodings::FORM_ISOLATED); } } + + diff --git a/src/paragraph.h b/src/paragraph.h index 5eb1e37d99..6c54e00482 100644 --- a/src/paragraph.h +++ b/src/paragraph.h @@ -294,8 +294,8 @@ public: /// bool isHfill(lyx::pos_type pos) const; - /// - bool isInset(lyx::pos_type pos) const; + /// hinted by profiler + bool isInset(lyx::pos_type pos) const { return getChar(pos) == META_INSET; } /// bool isNewline(lyx::pos_type pos) const; /// diff --git a/src/paragraph_funcs.C b/src/paragraph_funcs.C index a88b014f65..24da4d5e99 100644 --- a/src/paragraph_funcs.C +++ b/src/paragraph_funcs.C @@ -17,30 +17,16 @@ #include "debug.h" #include "encoding.h" -#include "errorlist.h" -#include "factory.h" #include "gettext.h" #include "iterators.h" #include "language.h" -#include "lyxlex.h" -#include "lyxrc.h" +#include "lyxtext.h" #include "outputparams.h" #include "paragraph_pimpl.h" #include "sgml.h" #include "texrow.h" #include "vspace.h" -#include "insets/insetbibitem.h" -#include "insets/insethfill.h" -#include "insets/insetlatexaccent.h" -#include "insets/insetline.h" -#include "insets/insetnewline.h" -#include "insets/insetpagebreak.h" -#include "insets/insetoptarg.h" -#include "insets/insetspace.h" -#include "insets/insetspecialchar.h" -#include "insets/insettabular.h" - #include "support/filetools.h" #include "support/lstrings.h" #include "support/lyxlib.h" @@ -49,6 +35,7 @@ #include using lyx::pos_type; +using lyx::par_type; using lyx::support::ascii_lowercase; using lyx::support::atoi; @@ -98,20 +85,17 @@ bool moveItem(Paragraph & from, Paragraph & to, void breakParagraph(BufferParams const & bparams, - ParagraphList & paragraphs, - ParagraphList::iterator par, - pos_type pos, - int flag) + ParagraphList & pars, par_type par, pos_type pos, int flag) { // create a new paragraph, and insert into the list - ParagraphList::iterator tmp = paragraphs.insert(boost::next(par), - Paragraph()); + ParagraphList::iterator tmp = + pars.insert(pars.begin() + par + 1, Paragraph()); // without doing that we get a crash when typing at the // end of a paragraph tmp->layout(bparams.getLyXTextClass().defaultLayout()); // remember to set the inset_owner - tmp->setInsetOwner(par->inInset()); + tmp->setInsetOwner(pars[par].inInset()); if (bparams.tracking_changes) tmp->trackChanges(); @@ -121,19 +105,19 @@ void breakParagraph(BufferParams const & bparams, // layout stays the same with latex-environments if (flag) { - tmp->layout(par->layout()); - tmp->setLabelWidthString(par->params().labelWidthString()); + tmp->layout(pars[par].layout()); + tmp->setLabelWidthString(pars[par].params().labelWidthString()); } - bool const isempty = (par->allowEmpty() && par->empty()); + bool const isempty = (pars[par].allowEmpty() && pars[par].empty()); - if (!isempty && (par->size() > pos || par->empty() || flag == 2)) { - tmp->layout(par->layout()); - tmp->params().align(par->params().align()); - tmp->setLabelWidthString(par->params().labelWidthString()); + if (!isempty && (pars[par].size() > pos || pars[par].empty() || flag == 2)) { + tmp->layout(pars[par].layout()); + tmp->params().align(pars[par].params().align()); + tmp->setLabelWidthString(pars[par].params().labelWidthString()); - tmp->params().depth(par->params().depth()); - tmp->params().noindent(par->params().noindent()); + tmp->params().depth(pars[par].params().depth()); + tmp->params().noindent(pars[par].params().noindent()); // copy everything behind the break-position // to the new paragraph @@ -145,40 +129,40 @@ void breakParagraph(BufferParams const & bparams, * here with size() == 0. So pos_end becomes - 1. Why * doesn't this cause problems ??? */ - pos_type pos_end = par->size() - 1; + pos_type pos_end = pars[par].size() - 1; pos_type i = pos; pos_type j = pos; for (; i <= pos_end; ++i) { - Change::Type change = par->lookupChange(i); - if (moveItem(*par, *tmp, bparams, i, j - pos)) { + Change::Type change = pars[par].lookupChange(i); + if (moveItem(pars[par], *tmp, bparams, i, j - pos)) { tmp->setChange(j - pos, change); ++j; } } for (i = pos_end; i >= pos; --i) - par->eraseIntern(i); + pars[par].eraseIntern(i); } if (pos) return; - par->params().clear(); + pars[par].params().clear(); - par->layout(bparams.getLyXTextClass().defaultLayout()); + pars[par].layout(bparams.getLyXTextClass().defaultLayout()); // layout stays the same with latex-environments if (flag) { - par->layout(tmp->layout()); - par->setLabelWidthString(tmp->params().labelWidthString()); - par->params().depth(tmp->params().depth()); + pars[par].layout(tmp->layout()); + pars[par].setLabelWidthString(tmp->params().labelWidthString()); + pars[par].params().depth(tmp->params().depth()); } // subtle, but needed to get empty pars working right if (bparams.tracking_changes) { - if (!par->size()) { - par->cleanChanges(); + if (!pars[par].size()) { + pars[par].cleanChanges(); } else if (!tmp->size()) { tmp->cleanChanges(); } @@ -187,371 +171,121 @@ void breakParagraph(BufferParams const & bparams, void breakParagraphConservative(BufferParams const & bparams, - ParagraphList & paragraphs, - ParagraphList::iterator par, - pos_type pos) + ParagraphList & pars, par_type par, pos_type pos) { // create a new paragraph - ParagraphList::iterator tmp = paragraphs.insert(boost::next(par), - Paragraph()); - tmp->makeSameLayout(*par); + Paragraph & tmp = *pars.insert(pars.begin() + par + 1, Paragraph()); + tmp.makeSameLayout(pars[par]); // When can pos > size()? // I guess pos == size() is possible. - if (par->size() > pos) { + if (pars[par].size() > pos) { // copy everything behind the break-position to the new // paragraph - pos_type pos_end = par->size() - 1; + pos_type pos_end = pars[par].size() - 1; for (pos_type i = pos, j = pos; i <= pos_end; ++i) - if (moveItem(*par, *tmp, bparams, i, j - pos)) + if (moveItem(pars[par], tmp, bparams, i, j - pos)) ++j; for (pos_type k = pos_end; k >= pos; --k) - par->erase(k); + pars[par].erase(k); } } void mergeParagraph(BufferParams const & bparams, - ParagraphList & paragraphs, - ParagraphList::iterator par) + ParagraphList & pars, par_type par) { - ParagraphList::iterator the_next = boost::next(par); + Paragraph & next = pars[par + 1]; - pos_type pos_end = the_next->size() - 1; - pos_type pos_insert = par->size(); + pos_type pos_end = next.size() - 1; + pos_type pos_insert = pars[par].size(); // ok, now copy the paragraph for (pos_type i = 0, j = 0; i <= pos_end; ++i) - if (moveItem(*the_next, *par, bparams, i, pos_insert + j)) + if (moveItem(next, pars[par], bparams, i, pos_insert + j)) ++j; - paragraphs.erase(the_next); + pars.erase(pars.begin() + par + 1); } -ParagraphList::iterator depthHook(ParagraphList::iterator pit, - ParagraphList const & plist, - Paragraph::depth_type depth) +par_type depthHook(par_type pit, + ParagraphList const & pars, Paragraph::depth_type depth) { - ParagraphList::iterator newpit = pit; - ParagraphList::iterator beg = const_cast(plist).begin(); + par_type newpit = pit; - if (newpit != beg) + if (newpit != 0) --newpit; - while (newpit != beg && newpit->getDepth() > depth) { + while (newpit != 0 && pars[newpit].getDepth() > depth) --newpit; - } - if (newpit->getDepth() > depth) + if (pars[newpit].getDepth() > depth) return pit; return newpit; } -ParagraphList::iterator outerHook(ParagraphList::iterator pit, - ParagraphList const & plist) +par_type outerHook(par_type par, ParagraphList const & pars) { - if (!pit->getDepth()) - return const_cast(plist).end(); - return depthHook(pit, plist, - Paragraph::depth_type(pit->getDepth() - 1)); + if (pars[par].getDepth() == 0) + return pars.size(); + return depthHook(par, pars, Paragraph::depth_type(pars[par].getDepth() - 1)); } -bool isFirstInSequence(ParagraphList::iterator pit, - ParagraphList const & plist) +bool isFirstInSequence(par_type pit, ParagraphList const & pars) { - ParagraphList::iterator dhook = depthHook(pit, plist, pit->getDepth()); - return (dhook == pit - || dhook->layout() != pit->layout() - || dhook->getDepth() != pit->getDepth()); + par_type dhook = depthHook(pit, pars, pars[pit].getDepth()); + return dhook == pit + || pars[dhook].layout() != pars[pit].layout() + || pars[dhook].getDepth() != pars[pit].getDepth(); } -int getEndLabel(ParagraphList::iterator p, ParagraphList const & plist) +int getEndLabel(par_type p, ParagraphList const & pars) { - ParagraphList::iterator pit = p; - Paragraph::depth_type par_depth = p->getDepth(); - while (pit != const_cast(plist).end()) { - LyXLayout_ptr const & layout = pit->layout(); + par_type pit = p; + Paragraph::depth_type par_depth = pars[p].getDepth(); + while (pit != pars.size()) { + LyXLayout_ptr const & layout = pars[pit].layout(); int const endlabeltype = layout->endlabeltype; if (endlabeltype != END_LABEL_NO_LABEL) { - if (boost::next(p) == const_cast(plist).end()) + if (p + 1 == pars.size()) return endlabeltype; - Paragraph::depth_type const next_depth = boost::next(p)->getDepth(); + Paragraph::depth_type const next_depth = + pars[p + 1].getDepth(); if (par_depth > next_depth || - (par_depth == next_depth && - layout != boost::next(p)->layout())) + (par_depth == next_depth && layout != pars[p + 1].layout())) return endlabeltype; break; } if (par_depth == 0) break; - pit = outerHook(pit, plist); - if (pit != const_cast(plist).end()) - par_depth = pit->getDepth(); + pit = outerHook(pit, pars); + if (pit != pars.size()) + par_depth = pars[pit].getDepth(); } return END_LABEL_NO_LABEL; } -namespace { - -int readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex, - string const & token) +LyXFont const outerFont(par_type pit, ParagraphList const & pars) { - static LyXFont font; - static Change change; - - BufferParams const & bp = buf.params(); - - if (token[0] != '\\') { - string::const_iterator cit = token.begin(); - for (; cit != token.end(); ++cit) { - par.insertChar(par.size(), (*cit), font, change); - } - } else if (token == "\\begin_layout") { - lex.eatLine(); - string layoutname = lex.getString(); - - font = LyXFont(LyXFont::ALL_INHERIT, bp.language); - change = Change(); - - LyXTextClass const & tclass = bp.getLyXTextClass(); - - if (layoutname.empty()) { - layoutname = tclass.defaultLayoutName(); - } - - bool hasLayout = tclass.hasLayout(layoutname); - - if (!hasLayout) { - lyxerr << "Layout '" << layoutname << "' does not" - << " exist in textclass '" << tclass.name() - << "'." << endl; - lyxerr << "Trying to use default layout instead." - << endl; - layoutname = tclass.defaultLayoutName(); - } - - par.layout(bp.getLyXTextClass()[layoutname]); - - // Test whether the layout is obsolete. - LyXLayout_ptr const & layout = par.layout(); - if (!layout->obsoleted_by().empty()) - par.layout(bp.getLyXTextClass()[layout->obsoleted_by()]); - - par.params().read(lex); - - } else if (token == "\\end_layout") { - lyxerr << "Solitary \\end_layout in line " << lex.getLineNo() << "\n" - << "Missing \\begin_layout?.\n"; - } else if (token == "\\end_inset") { - lyxerr << "Solitary \\end_inset in line " << lex.getLineNo() << "\n" - << "Missing \\begin_inset?.\n"; - } else if (token == "\\begin_inset") { - InsetBase * inset = readInset(lex, buf); - if (inset) - par.insertInset(par.size(), inset, font, change); - else { - lex.eatLine(); - string line = lex.getString(); - buf.error(ErrorItem(_("Unknown Inset"), line, - par.id(), 0, par.size())); - return 1; - } - } else if (token == "\\family") { - lex.next(); - font.setLyXFamily(lex.getString()); - } else if (token == "\\series") { - lex.next(); - font.setLyXSeries(lex.getString()); - } else if (token == "\\shape") { - lex.next(); - font.setLyXShape(lex.getString()); - } else if (token == "\\size") { - lex.next(); - font.setLyXSize(lex.getString()); - } else if (token == "\\lang") { - lex.next(); - string const tok = lex.getString(); - Language const * lang = languages.getLanguage(tok); - if (lang) { - font.setLanguage(lang); - } else { - font.setLanguage(bp.language); - lex.printError("Unknown language `$$Token'"); - } - } else if (token == "\\numeric") { - lex.next(); - font.setNumber(font.setLyXMisc(lex.getString())); - } else if (token == "\\emph") { - lex.next(); - font.setEmph(font.setLyXMisc(lex.getString())); - } else if (token == "\\bar") { - lex.next(); - string const tok = lex.getString(); - - if (tok == "under") - font.setUnderbar(LyXFont::ON); - else if (tok == "no") - font.setUnderbar(LyXFont::OFF); - else if (tok == "default") - font.setUnderbar(LyXFont::INHERIT); - else - lex.printError("Unknown bar font flag " - "`$$Token'"); - } else if (token == "\\noun") { - lex.next(); - font.setNoun(font.setLyXMisc(lex.getString())); - } else if (token == "\\color") { - lex.next(); - font.setLyXColor(lex.getString()); - } else if (token == "\\InsetSpace" || token == "\\SpecialChar") { - - // Insets don't make sense in a free-spacing context! ---Kayvan - if (par.isFreeSpacing()) { - if (token == "\\InsetSpace") - par.insertChar(par.size(), ' ', font, change); - else if (lex.isOK()) { - lex.next(); - string const next_token = lex.getString(); - if (next_token == "\\-") - par.insertChar(par.size(), '-', font, change); - else { - lex.printError("Token `$$Token' " - "is in free space " - "paragraph layout!"); - } - } - } else { - auto_ptr inset; - if (token == "\\SpecialChar" ) - inset.reset(new InsetSpecialChar); - else - inset.reset(new InsetSpace); - inset->read(buf, lex); - par.insertInset(par.size(), inset.release(), - font, change); - } - } else if (token == "\\i") { - auto_ptr inset(new InsetLatexAccent); - inset->read(buf, lex); - par.insertInset(par.size(), inset.release(), font, change); - } else if (token == "\\backslash") { - par.insertChar(par.size(), '\\', font, change); - } else if (token == "\\newline") { - auto_ptr inset(new InsetNewline); - inset->read(buf, lex); - par.insertInset(par.size(), inset.release(), font, change); - } else if (token == "\\LyXTable") { - auto_ptr inset(new InsetTabular(buf)); - inset->read(buf, lex); - par.insertInset(par.size(), inset.release(), font, change); - } else if (token == "\\bibitem") { - InsetCommandParams p("bibitem", "dummy"); - auto_ptr inset(new InsetBibitem(p)); - inset->read(buf, lex); - par.insertInset(par.size(), inset.release(), font, change); - } else if (token == "\\hfill") { - par.insertInset(par.size(), new InsetHFill, font, change); - } else if (token == "\\lyxline") { - par.insertInset(par.size(), new InsetLine, font, change); - } else if (token == "\\newpage") { - par.insertInset(par.size(), new InsetPagebreak, font, change); - } else if (token == "\\change_unchanged") { - // Hack ! Needed for empty paragraphs :/ - // FIXME: is it still ?? - if (!par.size()) - par.cleanChanges(); - change = Change(Change::UNCHANGED); - } else if (token == "\\change_inserted") { - lex.nextToken(); - istringstream is(lex.getString()); - int aid; - lyx::time_type ct; - is >> aid >> ct; - change = Change(Change::INSERTED, bp.author_map[aid], ct); - } else if (token == "\\change_deleted") { - lex.nextToken(); - istringstream is(lex.getString()); - int aid; - lyx::time_type ct; - is >> aid >> ct; - change = Change(Change::DELETED, bp.author_map[aid], ct); - } else { - lex.eatLine(); - string const s = bformat(_("Unknown token: %1$s %2$s\n"), - token, lex.getString()); - - buf.error(ErrorItem(_("Unknown token"), s, - par.id(), 0, par.size())); - return 1; - } - return 0; -} - -} - - -int readParagraph(Buffer const & buf, Paragraph & par, LyXLex & lex) -{ - int unknown = 0; - - lex.nextToken(); - string token = lex.getString(); - - while (lex.isOK()) { - - unknown += readParToken(buf, par, lex, token); - - lex.nextToken(); - token = lex.getString(); - - if (token.empty()) - continue; - - if (token == "\\end_layout") { - //Ok, paragraph finished - break; - } - - lyxerr[Debug::PARSER] << "Handling paragraph token: `" - << token << '\'' << endl; - if (token == "\\begin_layout" || token == "\\end_document" - || token == "\\end_inset" || token == "\\begin_deeper" - || token == "\\end_deeper") { - lex.pushToken(token); - lyxerr << "Paragraph ended in line " - << lex.getLineNo() << "\n" - << "Missing \\end_layout.\n"; - break; - } - } - - return unknown; -} - - -LyXFont const outerFont(ParagraphList::iterator pit, - ParagraphList const & plist) -{ - Paragraph::depth_type par_depth = pit->getDepth(); + Paragraph::depth_type par_depth = pars[pit].getDepth(); LyXFont tmpfont(LyXFont::ALL_INHERIT); // Resolve against environment font information - while (pit != const_cast(plist).end() && - par_depth && !tmpfont.resolved()) { - pit = outerHook(pit, plist); - if (pit != const_cast(plist).end()) { - tmpfont.realize(pit->layout()->font); - par_depth = pit->getDepth(); + while (pit != pars.size() && par_depth && !tmpfont.resolved()) { + pit = outerHook(pit, pars); + if (pit != pars.size()) { + tmpfont.realize(pars[pit].layout()->font); + par_depth = pars[pit].getDepth(); } } @@ -559,7 +293,7 @@ LyXFont const outerFont(ParagraphList::iterator pit, } -ParagraphList::iterator outerPar(Buffer const & buf, InsetBase const * inset) +par_type outerPar(Buffer const & buf, InsetBase const * inset) { ParIterator pit = const_cast(buf).par_iterator_begin(); ParIterator end = const_cast(buf).par_iterator_end(); @@ -578,7 +312,7 @@ ParagraphList::iterator outerPar(Buffer const & buf, InsetBase const * inset) } lyxerr << "outerPar: should not happen" << endl; BOOST_ASSERT(false); - return const_cast(buf).paragraphs().end(); // shut up compiler + return buf.paragraphs().size(); // shut up compiler } @@ -591,13 +325,13 @@ Paragraph const & ownerPar(Buffer const & buf, InsetBase const * inset) // the second '=' below is intentional for (int i = 0; (text = inset->getText(i)); ++i) if (&text->paragraphs() == &pit.plist()) - return *pit.pit(); + return *pit; InsetList::const_iterator ii = pit->insetlist.begin(); InsetList::const_iterator iend = pit->insetlist.end(); for ( ; ii != iend; ++ii) if (ii->inset == inset) - return *pit.pit(); + return *pit; } lyxerr << "ownerPar: should not happen" << endl; BOOST_ASSERT(false); @@ -606,20 +340,16 @@ Paragraph const & ownerPar(Buffer const & buf, InsetBase const * inset) /// return the range of pars [beg, end[ owning the range of y [ystart, yend] -void getParsInRange(ParagraphList & pl, - int ystart, int yend, - ParagraphList::iterator & beg, - ParagraphList::iterator & end) +void getParsInRange(ParagraphList & pars, int ystart, int yend, + par_type & beg, par_type & end) { - ParagraphList::iterator const endpar = pl.end(); - ParagraphList::iterator const begpar = pl.begin(); + BOOST_ASSERT(!pars.empty()); + par_type const endpar = pars.size(); + par_type const begpar = 0; - BOOST_ASSERT(begpar != endpar); - - beg = endpar; - for (--beg; beg != begpar && beg->y > ystart; --beg) + for (beg = endpar - 1; beg != begpar && pars[beg].y > ystart; --beg) ; - for (end = beg ; end != endpar && end->y <= yend; ++end) + for (end = beg ; end != endpar && pars[end].y <= yend; ++end) ; } diff --git a/src/paragraph_funcs.h b/src/paragraph_funcs.h index 5b22c42117..bce1f343a5 100644 --- a/src/paragraph_funcs.h +++ b/src/paragraph_funcs.h @@ -12,29 +12,27 @@ #ifndef PARAGRAPH_FUNCS_H #define PARAGRAPH_FUNCS_H -#include "ParagraphList_fwd.h" #include "support/types.h" -#include - class Buffer; class BufferParams; -class LyXFont; -class LyXLex; class InsetBase; +class LyXFont; +class Paragraph; +class ParagraphList; /// void breakParagraph(BufferParams const & bparams, ParagraphList & paragraphs, - ParagraphList::iterator par, + lyx::par_type par, lyx::pos_type pos, int flag); /// void breakParagraphConservative(BufferParams const & bparams, ParagraphList & paragraphs, - ParagraphList::iterator par, + lyx::par_type par, lyx::pos_type pos); /** @@ -42,43 +40,34 @@ void breakParagraphConservative(BufferParams const & bparams, * Be careful, this doesent make any check at all. */ void mergeParagraph(BufferParams const & bparams, - ParagraphList & paragraphs, - ParagraphList::iterator par); + ParagraphList & paragraphs, lyx::par_type par); /// for the environments -ParagraphList::iterator depthHook(ParagraphList::iterator pit, - ParagraphList const & plist, - lyx::depth_type depth); +lyx::par_type depthHook(lyx::par_type par, + ParagraphList const & plist, lyx::depth_type depth); -ParagraphList::iterator outerHook(ParagraphList::iterator pit, - ParagraphList const & plist); +lyx::par_type outerHook(lyx::par_type par, ParagraphList const & plist); /// Is it the first par with same depth and layout? -bool isFirstInSequence(ParagraphList::iterator par, - ParagraphList const & plist); +bool isFirstInSequence(lyx::par_type par, ParagraphList const & plist); /** Check if the current paragraph is the last paragraph in a proof environment */ -int getEndLabel(ParagraphList::iterator pit, - ParagraphList const & plist); +int getEndLabel(lyx::par_type par, ParagraphList const & plist); -/// read a paragraph from a .lyx file. Returns number of unrecognised tokens -int readParagraph(Buffer const & buf, Paragraph & par, LyXLex & lex); - -LyXFont const outerFont(ParagraphList::iterator pit, - ParagraphList const & plist); +LyXFont const outerFont(lyx::par_type par, ParagraphList const & plist); /// find outermost paragraph containing an inset -ParagraphList::iterator outerPar(Buffer const & buf, InsetBase const * inset); +lyx::par_type outerPar(Buffer const & buf, InsetBase const * inset); /// find owning paragraph containing an inset Paragraph const & ownerPar(Buffer const & buf, InsetBase const * inset); /// return the range of pars [beg, end[ owning the range of y [ystart, yend] -void getParsInRange(ParagraphList & pl, +void getParsInRange(ParagraphList & plist, int ystart, int yend, - ParagraphList::iterator & beg, - ParagraphList::iterator & end); + lyx::par_type & beg, + lyx::par_type & end); #endif // PARAGRAPH_FUNCS_H diff --git a/src/paragraph_pimpl.C b/src/paragraph_pimpl.C index 6186259e59..d12f6b491e 100644 --- a/src/paragraph_pimpl.C +++ b/src/paragraph_pimpl.C @@ -301,9 +301,6 @@ void Paragraph::Pimpl::insertInset(pos_type pos, // Add a new entry in the insetlist. owner_->insetlist.insert(inset, pos); - - if (inset_owner) - inset->setOwner(inset_owner); } diff --git a/src/paragraph_pimpl.h b/src/paragraph_pimpl.h index a9b1e07d52..08c8c27188 100644 --- a/src/paragraph_pimpl.h +++ b/src/paragraph_pimpl.h @@ -20,11 +20,13 @@ #include "changes.h" #include "lyxfont.h" #include "ParagraphParameters.h" +#include "ShareContainer.h" #include class LyXLayout; + struct Paragraph::Pimpl { /// Pimpl(Paragraph * owner); diff --git a/src/rowpainter.C b/src/rowpainter.C index a20ce8c84e..1667a3e9dd 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -39,6 +39,7 @@ #include "support/textutils.h" using lyx::pos_type; +using lyx::par_type; using std::endl; using std::max; @@ -57,7 +58,7 @@ class RowPainter { public: /// initialise and run painter RowPainter(BufferView const & bv, LyXText const & text, - ParagraphList::iterator pit, RowList::iterator rit, int xo, int yo); + par_type pit, RowList::iterator rit, int xo, int yo); private: // paint various parts void paintBackground(); @@ -97,13 +98,14 @@ private: /// LyXText for the row LyXText const & text_; + ParagraphList & pars_; /// The row to paint RowList::iterator const rit_; Row & row_; /// Row's paragraph - mutable ParagraphList::iterator pit_; + mutable par_type pit_; // Looks ugly - is double xo_; @@ -117,14 +119,13 @@ private: RowPainter::RowPainter(BufferView const & bv, LyXText const & text, - ParagraphList::iterator pit, RowList::iterator rit, - int xo, int yo) - : bv_(bv), pain_(bv_.painter()), text_(text), rit_(rit), row_(*rit), - pit_(pit), xo_(xo), yo_(yo), width_(text_.width()) + par_type pit, RowList::iterator rit, int xo, int yo) + : bv_(bv), pain_(bv_.painter()), text_(text), pars_(text.paragraphs()), + rit_(rit), row_(*rit), pit_(pit), xo_(xo), yo_(yo), width_(text_.width()) { //lyxerr << "RowPainter: x: " << x_ << " xo: " << xo << " yo: " << yo // << " pit->y: " << pit_->y - // << " row: " << (pit_->size() ? pit_->getChar(row_.pos()) : 'X') << endl; + // << " row: " << (pars_[pit_].size() ? pars_[pit_].getChar(row_.pos()) : 'X') << endl; RowMetrics m = text_.computeRowMetrics(pit, row_); x_ = m.x + xo_; separator_ = m.separator; @@ -151,7 +152,7 @@ RowPainter::RowPainter(BufferView const & bv, LyXText const & text, if (row_.pos() == 0) paintFirst(); - if (row_.endpos() >= pit_->size()) + if (row_.endpos() >= pars_[pit_].size()) paintLast(); // paint text @@ -193,7 +194,7 @@ int RowPainter::leftMargin() const void RowPainter::paintInset(pos_type const pos) { - InsetBase const * inset = pit_->getInset(pos); + InsetBase const * inset = pars_[pit_].getInset(pos); BOOST_ASSERT(inset); PainterInfo pi(const_cast(&bv_)); pi.base.font = getFont(pos); @@ -210,7 +211,7 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos) string str; // first char - char c = pit_->getChar(pos); + char c = pars_[pit_].getChar(pos); str += c; ++vpos; @@ -219,7 +220,7 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos) int dx = 0; for (pos_type i = pos - 1; i >= 0; --i) { - c = pit_->getChar(i); + c = pars_[pit_].getChar(i); if (!Encodings::IsComposeChar_hebrew(c)) { if (IsPrintableNonspace(c)) { int const width2 = singleWidth(i, c); @@ -243,8 +244,8 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos) string str; // first char - char c = pit_->getChar(pos); - c = pit_->transformChar(c, pos); + char c = pars_[pit_].getChar(pos); + c = pars_[pit_].transformChar(c, pos); str += c; ++vpos; @@ -253,7 +254,7 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos) int dx = 0; for (pos_type i = pos - 1; i >= 0; --i) { - c = pit_->getChar(i); + c = pars_[pit_].getChar(i); if (!Encodings::IsComposeChar_arabic(c)) { if (IsPrintableNonspace(c)) { int const width2 = singleWidth(i, c); @@ -275,26 +276,26 @@ void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic) // first character string str; - str += pit_->getChar(pos); + str += pars_[pit_].getChar(pos); if (arabic) { unsigned char c = str[0]; - str[0] = pit_->transformChar(c, pos); + str[0] = pars_[pit_].transformChar(c, pos); } - bool prev_struckout = isDeletedText(*pit_, pos); - bool prev_newtext = isInsertedText(*pit_, pos); + bool prev_struckout = isDeletedText(pars_[pit_], pos); + bool prev_newtext = isInsertedText(pars_[pit_], pos); // collect as much similar chars as we can for (++vpos; vpos < end && (pos = text_.bidi.vis2log(vpos)) >= 0; ++vpos) { - char c = pit_->getChar(pos); + char c = pars_[pit_].getChar(pos); if (!IsPrintableNonspace(c)) break; - if (prev_struckout != isDeletedText(*pit_, pos)) + if (prev_struckout != isDeletedText(pars_[pit_], pos)) break; - if (prev_newtext != isInsertedText(*pit_, pos)) + if (prev_newtext != isInsertedText(pars_[pit_], pos)) break; if (arabic && Encodings::IsComposeChar_arabic(c)) @@ -307,7 +308,7 @@ void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic) break; if (arabic) - c = pit_->transformChar(c, pos); + c = pars_[pit_].transformChar(c, pos); str += c; } @@ -347,7 +348,7 @@ void RowPainter::paintFromPos(pos_type & vpos) double const orig_x = x_; - char const c = pit_->getChar(pos); + char const c = pars_[pit_].getChar(pos); if (c == Paragraph::META_INSET) { paintInset(pos); @@ -391,7 +392,7 @@ void RowPainter::paintBackground() void RowPainter::paintSelection() { - bool const is_rtl = text_.isRTL(*pit_); + bool const is_rtl = text_.isRTL(pars_[pit_]); // the current selection LCursor const & cur = bv_.cursor(); @@ -399,13 +400,13 @@ void RowPainter::paintSelection() int const endx = text_.cursorX(cur.selEnd()); int const starty = text_.cursorY(cur.selBegin()); int const endy = text_.cursorY(cur.selEnd()); - ParagraphList::iterator startpit = text_.getPar(cur.selBegin()); - ParagraphList::iterator endpit = text_.getPar(cur.selEnd()); - RowList::iterator startrow = startpit->getRow(cur.selBegin().pos()); - RowList::iterator endrow = endpit->getRow(cur.selEnd().pos()); + par_type startpit = cur.selBegin().par(); + par_type endpit = cur.selEnd().par(); + RowList::iterator startrow = pars_[startpit].getRow(cur.selBegin().pos()); + RowList::iterator endrow = pars_[endpit].getRow(cur.selEnd().pos()); int const h = row_.height(); - int const row_y = text_.yo_ + pit_->y + row_.y_offset(); + int const row_y = text_.yo_ + pars_[pit_].y + row_.y_offset(); bool const sel_starts_here = startpit == pit_ && startrow == rit_; bool const sel_ends_here = endpit == pit_ && endrow == rit_; @@ -435,7 +436,7 @@ void RowPainter::paintSelection() pain_.fillRectangle(int(xo_), yo_, int(x_), h, LColor::selection); - pos_type const body_pos = pit_->beginOfBody(); + pos_type const body_pos = pars_[pit_].beginOfBody(); pos_type const end = row_.endpos(); double tmpx = x_; @@ -443,24 +444,24 @@ void RowPainter::paintSelection() pos_type pos = text_.bidi.vis2log(vpos); double const old_tmpx = tmpx; if (body_pos > 0 && pos == body_pos - 1) { - LyXLayout_ptr const & layout = pit_->layout(); + LyXLayout_ptr const & layout = pars_[pit_].layout(); LyXFont const lfont = getLabelFont(); tmpx += label_hfill_ + font_metrics::width(layout->labelsep, lfont); - if (pit_->isLineSeparator(body_pos - 1)) + if (pars_[pit_].isLineSeparator(body_pos - 1)) tmpx -= singleWidth(body_pos - 1); } tmpx += singleWidth(pos); - if (hfillExpansion(*pit_, row_, pos)) { + if (hfillExpansion(pars_[pit_], row_, pos)) { if (pos >= body_pos) tmpx += hfill_; else tmpx += label_hfill_; } else { - if (pit_->isSeparator(pos) && pos >= body_pos) + if (pars_[pit_].isSeparator(pos) && pos >= body_pos) tmpx += separator_; } @@ -487,7 +488,7 @@ void RowPainter::paintChangeBar() pos_type const start = row_.pos(); pos_type const end = row_.endpos(); - if (start == end || !pit_->isChanged(start, end - 1)) + if (start == end || !pars_[pit_].isChanged(start, end - 1)) return; int const height = text_.isLastRow(pit_, row_) @@ -500,12 +501,12 @@ void RowPainter::paintChangeBar() void RowPainter::paintAppendix() { - if (!pit_->params().appendix()) + if (!pars_[pit_].params().appendix()) return; int y = yo_; - if (pit_->params().startOfAppendix()) + if (pars_[pit_].params().startOfAppendix()) y += 2 * defaultRowHeight(); pain_.line(1, y, 1, yo_ + row_.height(), LColor::appendix); @@ -515,25 +516,25 @@ void RowPainter::paintAppendix() void RowPainter::paintDepthBar() { - Paragraph::depth_type const depth = pit_->getDepth(); + Paragraph::depth_type const depth = pars_[pit_].getDepth(); if (depth <= 0) return; Paragraph::depth_type prev_depth = 0; if (!text_.isFirstRow(pit_, row_)) { - ParagraphList::iterator pit2 = pit_; + par_type pit2 = pit_; if (row_.pos() == 0) --pit2; - prev_depth = pit2->getDepth(); + prev_depth = pars_[pit2].getDepth(); } Paragraph::depth_type next_depth = 0; if (!text_.isLastRow(pit_, row_)) { - ParagraphList::iterator pit2 = pit_; - if (row_.endpos() >= pit2->size()) + par_type pit2 = pit_; + if (row_.endpos() >= pars_[pit2].size()) ++pit2; - next_depth = pit2->getDepth(); + next_depth = pars_[pit2].getDepth(); } for (Paragraph::depth_type i = 1; i <= depth; ++i) { @@ -580,7 +581,7 @@ int RowPainter::paintAppendixStart(int y) void RowPainter::paintFirst() { - ParagraphParameters const & parparams = pit_->params(); + ParagraphParameters const & parparams = pars_[pit_].params(); int y_top = 0; @@ -590,18 +591,17 @@ void RowPainter::paintFirst() Buffer const & buffer = *bv_.buffer(); - LyXLayout_ptr const & layout = pit_->layout(); + LyXLayout_ptr const & layout = pars_[pit_].layout(); if (buffer.params().paragraph_separation == BufferParams::PARSEP_SKIP) { - if (pit_ != text_.paragraphs().begin()) { + if (pit_ != 0) { if (layout->latextype == LATEX_PARAGRAPH - && !pit_->getDepth()) { + && !pars_[pit_].getDepth()) { y_top += buffer.params().getDefSkip().inPixels(bv_); } else { - LyXLayout_ptr const & playout = - boost::prior(pit_)->layout(); + LyXLayout_ptr const & playout = pars_[pit_ - 1].layout(); if (playout->latextype == LATEX_PARAGRAPH - && !boost::prior(pit_)->getDepth()) { + && !pars_[pit_ - 1].getDepth()) { // is it right to use defskip here, too? (AS) y_top += buffer.params().getDefSkip().inPixels(bv_); } @@ -609,9 +609,9 @@ void RowPainter::paintFirst() } } - bool const is_rtl = text_.isRTL(*pit_); + bool const is_rtl = text_.isRTL(pars_[pit_]); bool const is_seq = isFirstInSequence(pit_, text_.paragraphs()); - //lyxerr << "paintFirst: " << pit_->id() << " is_seq: " << is_seq << std::endl; + //lyxerr << "paintFirst: " << pars_[pit_].id() << " is_seq: " << is_seq << std::endl; // should we print a label? if (layout->labeltype >= LABEL_STATIC @@ -620,9 +620,9 @@ void RowPainter::paintFirst() || is_seq)) { LyXFont font = getLabelFont(); - if (!pit_->getLabelstring().empty()) { + if (!pars_[pit_].getLabelstring().empty()) { double x = x_; - string const str = pit_->getLabelstring(); + string const str = pars_[pit_].getLabelstring(); // this is special code for the chapter layout. This is // printed in an extra row and has a pagebreak at @@ -670,8 +670,8 @@ void RowPainter::paintFirst() layout->labeltype == LABEL_BIBLIO || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)) { LyXFont font = getLabelFont(); - if (!pit_->getLabelstring().empty()) { - string const str = pit_->getLabelstring(); + if (!pars_[pit_].getLabelstring().empty()) { + string const str = pars_[pit_].getLabelstring(); float spacing_val = 1.0; if (!parparams.spacing().isDefault()) { spacing_val = parparams.spacing().getValue(); @@ -686,7 +686,7 @@ void RowPainter::paintFirst() double x = x_; if (layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) { x = ((is_rtl ? leftMargin() : x_) - + width_ - text_.rightMargin(*pit_)) / 2; + + width_ - text_.rightMargin(pars_[pit_])) / 2; x -= font_metrics::width(str, font) / 2; } else if (is_rtl) { x = width_ - leftMargin() - @@ -702,7 +702,7 @@ void RowPainter::paintFirst() void RowPainter::paintLast() { - bool const is_rtl = text_.isRTL(*pit_); + bool const is_rtl = text_.isRTL(pars_[pit_]); int const endlabel = getEndLabel(pit_, text_.paragraphs()); // draw an endlabel @@ -726,10 +726,10 @@ void RowPainter::paintLast() case END_LABEL_STATIC: { LyXFont font = getLabelFont(); - string const & str = pit_->layout()->endlabelstring(); + string const & str = pars_[pit_].layout()->endlabelstring(); double const x = is_rtl ? x_ - font_metrics::width(str, font) - : - text_.rightMargin(*pit_) - row_.width(); + : - text_.rightMargin(pars_[pit_]) - row_.width(); pain_.text(int(x), yo_ + row_.baseline(), str, font); break; } @@ -743,13 +743,13 @@ void RowPainter::paintLast() void RowPainter::paintText() { pos_type const end = row_.endpos(); - pos_type body_pos = pit_->beginOfBody(); + pos_type body_pos = pars_[pit_].beginOfBody(); if (body_pos > 0 && - (body_pos > end || !pit_->isLineSeparator(body_pos - 1))) { + (body_pos > end || !pars_[pit_].isLineSeparator(body_pos - 1))) { body_pos = 0; } - LyXLayout_ptr const & layout = pit_->layout(); + LyXLayout_ptr const & layout = pars_[pit_].layout(); bool running_strikeout = false; bool is_struckout = false; @@ -761,7 +761,7 @@ void RowPainter::paintText() pos_type pos = text_.bidi.vis2log(vpos); - if (pos >= pit_->size()) { + if (pos >= pars_[pit_].size()) { ++vpos; continue; } @@ -772,15 +772,15 @@ void RowPainter::paintText() continue; } - is_struckout = isDeletedText(*pit_, pos); + is_struckout = isDeletedText(pars_[pit_], pos); if (is_struckout && !running_strikeout) { running_strikeout = true; last_strikeout_x = int(x_); } - bool const highly_editable_inset = pit_->isInset(pos) - && isHighlyEditableInset(pit_->getInset(pos)); + bool const highly_editable_inset = pars_[pit_].isInset(pos) + && isHighlyEditableInset(pars_[pit_].getInset(pos)); // if we reach the end of a struck out range, paint it // we also don't paint across things like tables @@ -798,7 +798,7 @@ void RowPainter::paintText() x_ += label_hfill_ + lwidth - singleWidth(body_pos - 1); } - if (pit_->isHfill(pos)) { + if (pars_[pit_].isHfill(pos)) { x_ += 1; int const y0 = yo_ + row_.baseline(); @@ -806,7 +806,7 @@ void RowPainter::paintText() pain_.line(int(x_), y1, int(x_), y0, LColor::added_space); - if (hfillExpansion(*pit_, row_, pos)) { + if (hfillExpansion(pars_[pit_], row_, pos)) { int const y2 = (y0 + y1) / 2; if (pos >= body_pos) { @@ -824,7 +824,7 @@ void RowPainter::paintText() } x_ += 2; ++vpos; - } else if (pit_->isSeparator(pos)) { + } else if (pars_[pit_].isSeparator(pos)) { x_ += singleWidth(pos); if (pos >= body_pos) x_ += separator_; @@ -845,17 +845,16 @@ void RowPainter::paintText() int paintPars(BufferView const & bv, LyXText const & text, - ParagraphList::iterator pit, int xo, int yo, int y) + par_type pit, int xo, int yo, int y) { //lyxerr << " paintRows: pit: " << &*pit << endl; int const y2 = bv.painter().paperHeight(); y -= bv.top_y(); - ParagraphList::iterator end = text.paragraphs().end(); - - for ( ; pit != end; ++pit) { - RowList::iterator row = pit->rows.begin(); - RowList::iterator rend = pit->rows.end(); + ParagraphList & pars = text.paragraphs(); + for ( ; pit != pars.size(); ++pit) { + RowList::iterator row = pars[pit].rows.begin(); + RowList::iterator rend = pars[pit].rows.end(); for ( ; row != rend; ++row) { RowPainter(bv, text, pit, row, xo, y + yo); @@ -873,15 +872,15 @@ int paintPars(BufferView const & bv, LyXText const & text, int paintText(BufferView const & bv) { - ParagraphList::iterator pit; + par_type pit; bv.text()->updateParPositions(); bv.text()->getRowNearY(bv.top_y(), pit); //lyxerr << "top_y: " << bv.top_y() << " y: " << pit->y << endl; - return paintPars(bv, *bv.text(), pit, 0, 0, pit->y); + return paintPars(bv, *bv.text(), pit, 0, 0, bv.text()->paragraphs()[pit].y); } void paintTextInset(LyXText const & text, PainterInfo & pi, int xo, int yo) { - paintPars(*pi.base.bv, text, text.paragraphs().begin(), xo, yo, 0); + paintPars(*pi.base.bv, text, 0, xo, yo, 0); } diff --git a/src/support/types.h b/src/support/types.h index fa04a8b5f3..cd46fcf62c 100644 --- a/src/support/types.h +++ b/src/support/types.h @@ -28,7 +28,7 @@ namespace lyx { /// a type for paragraph offsets // FIXME: should be unsigned as well. // however, simply changing it breaks a downward loop somewhere... - typedef ptrdiff_t paroffset_type; + typedef ptrdiff_t par_type; /// a type for the nesting depth of a paragraph typedef size_t depth_type; diff --git a/src/tabular.C b/src/tabular.C index e0035bbc62..06e3aa1772 100644 --- a/src/tabular.C +++ b/src/tabular.C @@ -387,17 +387,6 @@ void LyXTabular::fixCellNums() } -void LyXTabular::setOwner(InsetTabular * inset) -{ - for (int i = 0; i < rows_; ++i) { - for (int j = 0; j < columns_; ++j) { - cell_info[i][j].inset.setOwner(inset); - cell_info[i][j].inset.setDrawFrame(InsetText::LOCKED); - } - } -} - - void LyXTabular::appendRow(BufferParams const & bp, int cell) { ++rows_; @@ -2007,9 +1996,9 @@ int LyXTabular::TeXRow(ostream & os, int i, Buffer const & buf, ret += TeXCellPreamble(os, cell); InsetText & inset = getCellInset(cell); - Paragraph const & par = inset.paragraphs().front(); + Paragraph & par = inset.paragraphs().front(); bool rtl = par.isRightToLeftPar(buf.params()) - && !inset.paragraphs().begin()->empty() + && !par.empty() && getPWidth(cell).zero(); if (rtl) diff --git a/src/tabular.h b/src/tabular.h index d5df8c93f7..a54012967d 100644 --- a/src/tabular.h +++ b/src/tabular.h @@ -172,8 +172,6 @@ public: /// constructor LyXTabular(BufferParams const &, int columns_arg, int rows_arg); - /// - void setOwner(InsetTabular * inset); /// Returns true if there is a topline, returns false if not bool topLine(int cell, bool onlycolumn = false) const; diff --git a/src/text.C b/src/text.C index 38e5ae671f..e52f14da97 100644 --- a/src/text.C +++ b/src/text.C @@ -23,10 +23,13 @@ #include "bufferparams.h" #include "BufferView.h" #include "cursor.h" +#include "CutAndPaste.h" #include "debug.h" #include "dispatchresult.h" #include "encoding.h" +#include "errorlist.h" #include "funcrequest.h" +#include "factory.h" #include "FontIterator.h" #include "gettext.h" #include "language.h" @@ -49,12 +52,23 @@ #include "frontends/LyXView.h" #include "insets/insettext.h" +#include "insets/insetbibitem.h" +#include "insets/insethfill.h" +#include "insets/insetlatexaccent.h" +#include "insets/insetline.h" +#include "insets/insetnewline.h" +#include "insets/insetpagebreak.h" +#include "insets/insetoptarg.h" +#include "insets/insetspace.h" +#include "insets/insetspecialchar.h" +#include "insets/insettabular.h" #include "support/lstrings.h" #include "support/textutils.h" #include "support/tostr.h" #include "support/std_sstream.h" +using lyx::par_type; using lyx::pos_type; using lyx::word_location; @@ -64,6 +78,9 @@ using lyx::support::lowercase; using lyx::support::split; using lyx::support::uppercase; +using lyx::cap::cutSelection; + +using std::auto_ptr; using std::advance; using std::distance; using std::max; @@ -148,6 +165,239 @@ int numberOfHfills(Paragraph const & par, Row const & row) return n; } + +int readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex, + string const & token) +{ + static LyXFont font; + static Change change; + + BufferParams const & bp = buf.params(); + + if (token[0] != '\\') { + string::const_iterator cit = token.begin(); + for (; cit != token.end(); ++cit) { + par.insertChar(par.size(), (*cit), font, change); + } + } else if (token == "\\begin_layout") { + lex.eatLine(); + string layoutname = lex.getString(); + + font = LyXFont(LyXFont::ALL_INHERIT, bp.language); + change = Change(); + + LyXTextClass const & tclass = bp.getLyXTextClass(); + + if (layoutname.empty()) { + layoutname = tclass.defaultLayoutName(); + } + + bool hasLayout = tclass.hasLayout(layoutname); + + if (!hasLayout) { + lyxerr << "Layout '" << layoutname << "' does not" + << " exist in textclass '" << tclass.name() + << "'." << endl; + lyxerr << "Trying to use default layout instead." + << endl; + layoutname = tclass.defaultLayoutName(); + } + + par.layout(bp.getLyXTextClass()[layoutname]); + + // Test whether the layout is obsolete. + LyXLayout_ptr const & layout = par.layout(); + if (!layout->obsoleted_by().empty()) + par.layout(bp.getLyXTextClass()[layout->obsoleted_by()]); + + par.params().read(lex); + + } else if (token == "\\end_layout") { + lyxerr << "Solitary \\end_layout in line " << lex.getLineNo() << "\n" + << "Missing \\begin_layout?.\n"; + } else if (token == "\\end_inset") { + lyxerr << "Solitary \\end_inset in line " << lex.getLineNo() << "\n" + << "Missing \\begin_inset?.\n"; + } else if (token == "\\begin_inset") { + InsetBase * inset = readInset(lex, buf); + if (inset) + par.insertInset(par.size(), inset, font, change); + else { + lex.eatLine(); + string line = lex.getString(); + buf.error(ErrorItem(_("Unknown Inset"), line, + par.id(), 0, par.size())); + return 1; + } + } else if (token == "\\family") { + lex.next(); + font.setLyXFamily(lex.getString()); + } else if (token == "\\series") { + lex.next(); + font.setLyXSeries(lex.getString()); + } else if (token == "\\shape") { + lex.next(); + font.setLyXShape(lex.getString()); + } else if (token == "\\size") { + lex.next(); + font.setLyXSize(lex.getString()); + } else if (token == "\\lang") { + lex.next(); + string const tok = lex.getString(); + Language const * lang = languages.getLanguage(tok); + if (lang) { + font.setLanguage(lang); + } else { + font.setLanguage(bp.language); + lex.printError("Unknown language `$$Token'"); + } + } else if (token == "\\numeric") { + lex.next(); + font.setNumber(font.setLyXMisc(lex.getString())); + } else if (token == "\\emph") { + lex.next(); + font.setEmph(font.setLyXMisc(lex.getString())); + } else if (token == "\\bar") { + lex.next(); + string const tok = lex.getString(); + + if (tok == "under") + font.setUnderbar(LyXFont::ON); + else if (tok == "no") + font.setUnderbar(LyXFont::OFF); + else if (tok == "default") + font.setUnderbar(LyXFont::INHERIT); + else + lex.printError("Unknown bar font flag " + "`$$Token'"); + } else if (token == "\\noun") { + lex.next(); + font.setNoun(font.setLyXMisc(lex.getString())); + } else if (token == "\\color") { + lex.next(); + font.setLyXColor(lex.getString()); + } else if (token == "\\InsetSpace" || token == "\\SpecialChar") { + + // Insets don't make sense in a free-spacing context! ---Kayvan + if (par.isFreeSpacing()) { + if (token == "\\InsetSpace") + par.insertChar(par.size(), ' ', font, change); + else if (lex.isOK()) { + lex.next(); + string const next_token = lex.getString(); + if (next_token == "\\-") + par.insertChar(par.size(), '-', font, change); + else { + lex.printError("Token `$$Token' " + "is in free space " + "paragraph layout!"); + } + } + } else { + auto_ptr inset; + if (token == "\\SpecialChar" ) + inset.reset(new InsetSpecialChar); + else + inset.reset(new InsetSpace); + inset->read(buf, lex); + par.insertInset(par.size(), inset.release(), + font, change); + } + } else if (token == "\\i") { + auto_ptr inset(new InsetLatexAccent); + inset->read(buf, lex); + par.insertInset(par.size(), inset.release(), font, change); + } else if (token == "\\backslash") { + par.insertChar(par.size(), '\\', font, change); + } else if (token == "\\newline") { + auto_ptr inset(new InsetNewline); + inset->read(buf, lex); + par.insertInset(par.size(), inset.release(), font, change); + } else if (token == "\\LyXTable") { + auto_ptr inset(new InsetTabular(buf)); + inset->read(buf, lex); + par.insertInset(par.size(), inset.release(), font, change); + } else if (token == "\\bibitem") { + InsetCommandParams p("bibitem", "dummy"); + auto_ptr inset(new InsetBibitem(p)); + inset->read(buf, lex); + par.insertInset(par.size(), inset.release(), font, change); + } else if (token == "\\hfill") { + par.insertInset(par.size(), new InsetHFill, font, change); + } else if (token == "\\lyxline") { + par.insertInset(par.size(), new InsetLine, font, change); + } else if (token == "\\newpage") { + par.insertInset(par.size(), new InsetPagebreak, font, change); + } else if (token == "\\change_unchanged") { + // Hack ! Needed for empty paragraphs :/ + // FIXME: is it still ?? + if (!par.size()) + par.cleanChanges(); + change = Change(Change::UNCHANGED); + } else if (token == "\\change_inserted") { + lex.nextToken(); + std::istringstream is(lex.getString()); + int aid; + lyx::time_type ct; + is >> aid >> ct; + change = Change(Change::INSERTED, bp.author_map[aid], ct); + } else if (token == "\\change_deleted") { + lex.nextToken(); + std::istringstream is(lex.getString()); + int aid; + lyx::time_type ct; + is >> aid >> ct; + change = Change(Change::DELETED, bp.author_map[aid], ct); + } else { + lex.eatLine(); + buf.error(ErrorItem(_("Unknown token"), + bformat(_("Unknown token: %1$s %2$s\n"), token, lex.getString()), + par.id(), 0, par.size())); + return 1; + } + return 0; +} + + +int readParagraph(Buffer const & buf, Paragraph & par, LyXLex & lex) +{ + int unknown = 0; + + lex.nextToken(); + string token = lex.getString(); + + while (lex.isOK()) { + + unknown += readParToken(buf, par, lex, token); + + lex.nextToken(); + token = lex.getString(); + + if (token.empty()) + continue; + + if (token == "\\end_layout") { + //Ok, paragraph finished + break; + } + + lyxerr[Debug::PARSER] << "Handling paragraph token: `" + << token << '\'' << endl; + if (token == "\\begin_layout" || token == "\\end_document" + || token == "\\end_inset" || token == "\\begin_deeper" + || token == "\\end_deeper") { + lex.pushToken(token); + lyxerr << "Paragraph ended in line " + << lex.getLineNo() << "\n" + << "Missing \\end_layout.\n"; + break; + } + } + + return unknown; +} + + } // namespace anon @@ -175,11 +425,11 @@ BufferView * LyXText::bv() const void LyXText::updateParPositions() { - ParagraphList::iterator pit = paragraphs().begin(); - ParagraphList::iterator end = paragraphs().end(); + par_type pit = 0; + par_type end = pars_.size(); for (height_ = 0; pit != end; ++pit) { - pit->y = height_; - height_ += pit->height; + pars_[pit].y = height_; + height_ += pars_[pit].height; } } @@ -196,20 +446,20 @@ int LyXText::height() const } -int LyXText::singleWidth(ParagraphList::iterator pit, pos_type pos) const +int LyXText::singleWidth(par_type par, pos_type pos) const { - if (pos >= pit->size()) + if (pos >= pars_[par].size()) return 0; - char const c = pit->getChar(pos); - return singleWidth(pit, pos, c, getFont(pit, pos)); + char const c = pars_[par].getChar(pos); + return singleWidth(par, pos, c, getFont(par, pos)); } -int LyXText::singleWidth(ParagraphList::iterator pit, +int LyXText::singleWidth(par_type pit, pos_type pos, char c, LyXFont const & font) const { - if (pos >= pit->size()) { + if (pos >= pars_[pit].size()) { lyxerr << "in singleWidth(), pos: " << pos << endl; BOOST_ASSERT(false); return 0; @@ -224,7 +474,7 @@ int LyXText::singleWidth(ParagraphList::iterator pit, if (Encodings::IsComposeChar_arabic(c)) return 0; else - c = pit->transformChar(c, pos); + c = pars_[pit].transformChar(c, pos); } else if (font.language()->lang() == "hebrew" && Encodings::IsComposeChar_hebrew(c)) return 0; @@ -233,7 +483,7 @@ int LyXText::singleWidth(ParagraphList::iterator pit, } if (c == Paragraph::META_INSET) - return pit->getInset(pos)->width(); + return pars_[pit].getInset(pos)->width(); if (IsSeparatorChar(c)) c = ' '; @@ -241,17 +491,17 @@ int LyXText::singleWidth(ParagraphList::iterator pit, } -int LyXText::leftMargin(ParagraphList::iterator pit) const +int LyXText::leftMargin(par_type pit) const { - return leftMargin(pit, pit->size()); + return leftMargin(pit, pars_[pit].size()); } -int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const +int LyXText::leftMargin(par_type pit, pos_type pos) const { LyXTextClass const & tclass = bv()->buffer()->params().getLyXTextClass(); - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); string parindent = layout->parindent; @@ -262,34 +512,33 @@ int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const // This is the way LyX handles LaTeX-Environments. // I have had this idea very late, so it seems to be a // later added hack and this is true - if (pit->getDepth() == 0) { - if (pit->layout() == tclass.defaultLayout()) { + if (pars_[pit].getDepth() == 0) { + if (pars_[pit].layout() == tclass.defaultLayout()) { // find the previous same level paragraph - if (pit != paragraphs().begin()) { - ParagraphList::iterator newpit = - depthHook(pit, paragraphs(), pit->getDepth()); - if (newpit == pit && newpit->layout()->nextnoindent) + if (pit != 0) { + par_type newpit = + depthHook(pit, paragraphs(), pars_[pit].getDepth()); + if (newpit == pit && pars_[newpit].layout()->nextnoindent) parindent.erase(); } } } else { // find the next level paragraph - ParagraphList::iterator newpar = - outerHook(pit, paragraphs()); + par_type newpar = outerHook(pit, pars_); // Make a corresponding row. Need to call leftMargin() // to check whether it is a sufficent paragraph. - if (newpar != paragraphs().end() - && newpar->layout()->isEnvironment()) { + if (newpar != pars_.size() + && pars_[newpar].layout()->isEnvironment()) { x = leftMargin(newpar); } - if (newpar != paragraphs().end() - && pit->layout() == tclass.defaultLayout()) { - if (newpar->params().noindent()) + if (newpar != paragraphs().size() + && pars_[pit].layout() == tclass.defaultLayout()) { + if (pars_[newpar].params().noindent()) parindent.erase(); else - parindent = newpar->layout()->parindent; + parindent = pars_[newpar].layout()->parindent; } } @@ -299,10 +548,10 @@ int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const if (!layout->leftmargin.empty()) x += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()); - if (!pit->getLabelstring().empty()) { + if (!pars_[pit].getLabelstring().empty()) { x += font_metrics::signedWidth(layout->labelindent, labelfont); - x += font_metrics::width(pit->getLabelstring(), + x += font_metrics::width(pars_[pit].getLabelstring(), labelfont); x += font_metrics::width(layout->labelsep, labelfont); } @@ -311,9 +560,9 @@ int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const case MARGIN_MANUAL: x += font_metrics::signedWidth(layout->labelindent, labelfont); // The width of an empty par, even with manual label, should be 0 - if (!pit->empty() && pos >= pit->beginOfBody()) { - if (!pit->getLabelWidthString().empty()) { - x += font_metrics::width(pit->getLabelWidthString(), + if (!pars_[pit].empty() && pos >= pars_[pit].beginOfBody()) { + if (!pars_[pit].getLabelWidthString().empty()) { + x += font_metrics::width(pars_[pit].getLabelWidthString(), labelfont); x += font_metrics::width(layout->labelsep, labelfont); } @@ -322,12 +571,12 @@ int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const case MARGIN_STATIC: x += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()) * 4 - / (pit->getDepth() + 4); + / (pars_[pit].getDepth() + 4); break; case MARGIN_FIRST_DYNAMIC: if (layout->labeltype == LABEL_MANUAL) { - if (pos >= pit->beginOfBody()) { + if (pos >= pars_[pit].beginOfBody()) { x += font_metrics::signedWidth(layout->leftmargin, labelfont); } else { @@ -349,7 +598,7 @@ int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const x += font_metrics::signedWidth(layout->labelindent, labelfont); x += font_metrics::width(layout->labelsep, labelfont); - x += font_metrics::width(pit->getLabelstring(), + x += font_metrics::width(pars_[pit].getLabelstring(), labelfont); } break; @@ -358,8 +607,8 @@ int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const #if 0 // ok, a terrible hack. The left margin depends on the widest // row in this paragraph. - RowList::iterator rit = pit->rows.begin(); - RowList::iterator end = pit->rows.end(); + RowList::iterator rit = pars_[pit].rows.begin(); + RowList::iterator end = pars_[pit].rows.end(); #warning This is wrong. int minfill = maxwidth_; for ( ; rit != end; ++rit) @@ -376,15 +625,15 @@ int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const } - if (!pit->params().leftIndent().zero()) - x += pit->params().leftIndent().inPixels(maxwidth_); + if (!pars_[pit].params().leftIndent().zero()) + x += pars_[pit].params().leftIndent().inPixels(maxwidth_); LyXAlignment align; - if (pit->params().align() == LYX_ALIGN_LAYOUT) + if (pars_[pit].params().align() == LYX_ALIGN_LAYOUT) align = layout->align; else - align = pit->params().align(); + align = pars_[pit].params().align(); // set the correct parindent if (pos == 0 @@ -395,13 +644,12 @@ int LyXText::leftMargin(ParagraphList::iterator pit, pos_type pos) const && layout->latextype == LATEX_ENVIRONMENT && !isFirstInSequence(pit, paragraphs()))) && align == LYX_ALIGN_BLOCK - && !pit->params().noindent() + && !pars_[pit].params().noindent() // in tabulars and ert paragraphs are never indented! - && (!pit->inInset() - || !pit->inInset()->owner() - || (pit->inInset()->owner()->lyxCode() != InsetOld::TABULAR_CODE - && pit->inInset()->owner()->lyxCode() != InsetOld::ERT_CODE)) - && (pit->layout() != tclass.defaultLayout() + && (!pars_[pit].inInset() + || (pars_[pit].inInset()->lyxCode() != InsetOld::TABULAR_CODE + && pars_[pit].inInset()->lyxCode() != InsetOld::ERT_CODE)) + && (pars_[pit].layout() != tclass.defaultLayout() || bv()->buffer()->params().paragraph_separation == BufferParams::PARSEP_INDENT)) { @@ -426,10 +674,10 @@ int LyXText::rightMargin(Paragraph const & par) const } -int LyXText::labelEnd(ParagraphList::iterator pit) const +int LyXText::labelEnd(par_type pit) const { // labelEnd is only needed if the layout fills a flushleft label. - if (pit->layout()->margintype != MARGIN_MANUAL) + if (pars_[pit].layout()->margintype != MARGIN_MANUAL) return 0; // return the beginning of the body return leftMargin(pit); @@ -453,9 +701,9 @@ pos_type addressBreakPoint(pos_type i, Paragraph const & par) }; -void LyXText::rowBreakPoint(ParagraphList::iterator pit, Row & row) const +void LyXText::rowBreakPoint(par_type pit, Row & row) const { - pos_type const end = pit->size(); + pos_type const end = pars_[pit].size(); pos_type const pos = row.pos(); if (pos == end) { row.endpos(end); @@ -463,20 +711,20 @@ void LyXText::rowBreakPoint(ParagraphList::iterator pit, Row & row) const } // maximum pixel width of a row - int width = maxwidth_ - rightMargin(*pit); // - leftMargin(pit, row); + int width = maxwidth_ - rightMargin(pars_[pit]); // - leftMargin(pit, row); if (width < 0) { row.endpos(end); return; } - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) { - row.endpos(addressBreakPoint(pos, *pit)); + row.endpos(addressBreakPoint(pos, pars_[pit])); return; } - pos_type const body_pos = pit->beginOfBody(); + pos_type const body_pos = pars_[pit].beginOfBody(); // Now we iterate through until we reach the right margin @@ -493,7 +741,7 @@ void LyXText::rowBreakPoint(ParagraphList::iterator pit, Row & row) const pos_type point = end; pos_type i = pos; for ( ; i < end; ++i, ++fi) { - char const c = pit->getChar(i); + char const c = pars_[pit].getChar(i); { int thiswidth = singleWidth(pit, i, c, *fi); @@ -501,7 +749,7 @@ void LyXText::rowBreakPoint(ParagraphList::iterator pit, Row & row) const // add the auto-hfill from label end to the body if (body_pos && i == body_pos) { int add = font_metrics::width(layout->labelsep, getLabelFont(pit)); - if (pit->isLineSeparator(i - 1)) + if (pars_[pit].isLineSeparator(i - 1)) add -= singleWidth(pit, i - 1); add = std::max(add, labelEnd(pit) - x); @@ -527,26 +775,26 @@ void LyXText::rowBreakPoint(ParagraphList::iterator pit, Row & row) const break; } - if (pit->isNewline(i)) { + if (pars_[pit].isNewline(i)) { point = i + 1; break; } // Break before... if (i + 1 < end) { - if (pit->isInset(i + 1) && pit->getInset(i + 1)->display()) { + if (pars_[pit].isInset(i + 1) && pars_[pit].getInset(i + 1)->display()) { point = i + 1; break; } // ...and after. - if (pit->isInset(i) && pit->getInset(i)->display()) { + if (pars_[pit].isInset(i) && pars_[pit].getInset(i)->display()) { point = i + 1; break; } } - if (!pit->isInset(i) || pit->getInset(i)->isChar()) { + if (!pars_[pit].isInset(i) || pars_[pit].getInset(i)->isChar()) { // some insets are line separators too - if (pit->isLineSeparator(i)) { + if (pars_[pit].isLineSeparator(i)) { // register breakpoint: point = i + 1; chunkwidth = 0; @@ -568,15 +816,15 @@ void LyXText::rowBreakPoint(ParagraphList::iterator pit, Row & row) const } -void LyXText::setRowWidth(ParagraphList::iterator pit, Row & row) const +void LyXText::setRowWidth(par_type pit, Row & row) const { // get the pure distance pos_type const end = row.endpos(); - string labelsep = pit->layout()->labelsep; + string labelsep = pars_[pit].layout()->labelsep; int w = leftMargin(pit, row.pos()); - pos_type const body_pos = pit->beginOfBody(); + pos_type const body_pos = pars_[pit].beginOfBody(); pos_type i = row.pos(); if (i < end) { @@ -584,30 +832,30 @@ void LyXText::setRowWidth(ParagraphList::iterator pit, Row & row) const for ( ; i < end; ++i, ++fi) { if (body_pos > 0 && i == body_pos) { w += font_metrics::width(labelsep, getLabelFont(pit)); - if (pit->isLineSeparator(i - 1)) + if (pars_[pit].isLineSeparator(i - 1)) w -= singleWidth(pit, i - 1); w = max(w, labelEnd(pit)); } - char const c = pit->getChar(i); + char const c = pars_[pit].getChar(i); w += singleWidth(pit, i, c, *fi); } } if (body_pos > 0 && body_pos >= end) { w += font_metrics::width(labelsep, getLabelFont(pit)); - if (end > 0 && pit->isLineSeparator(end - 1)) + if (end > 0 && pars_[pit].isLineSeparator(end - 1)) w -= singleWidth(pit, end - 1); w = max(w, labelEnd(pit)); } - row.width(w + rightMargin(*pit)); + row.width(w + rightMargin(pars_[pit])); } // returns the minimum space a manual label needs on the screen in pixel -int LyXText::labelFill(ParagraphList::iterator pit, Row const & row) const +int LyXText::labelFill(par_type pit, Row const & row) const { - pos_type last = pit->beginOfBody(); + pos_type last = pars_[pit].beginOfBody(); BOOST_ASSERT(last > 0); @@ -615,14 +863,14 @@ int LyXText::labelFill(ParagraphList::iterator pit, Row const & row) const --last; // a separator at this end does not count - if (pit->isLineSeparator(last)) + if (pars_[pit].isLineSeparator(last)) --last; int w = 0; for (pos_type i = row.pos(); i <= last; ++i) w += singleWidth(pit, i); - string const & label = pit->params().labelWidthString(); + string const & label = pars_[pit].params().labelWidthString(); if (label.empty()) return 0; @@ -636,7 +884,7 @@ LColor_color LyXText::backgroundColor() const } -void LyXText::setHeightOfRow(ParagraphList::iterator pit, Row & row) +void LyXText::setHeightOfRow(par_type pit, Row & row) { // get the maximum ascent and the maximum descent double layoutasc = 0; @@ -646,7 +894,7 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, Row & row) // ok, let us initialize the maxasc and maxdesc value. // Only the fontsize count. The other properties // are taken from the layoutfont. Nicer on the screen :) - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); // as max get the first character of this row then it can // increase but not decrease the height. Just some point to @@ -661,14 +909,15 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, Row & row) LyXFont labelfont = getLabelFont(pit); // these are minimum values - double const spacing_val = layout->spacing.getValue() * spacing(*pit); + double const spacing_val = + layout->spacing.getValue() * spacing(pars_[pit]); //lyxerr << "spacing_val = " << spacing_val << endl; int maxasc = int(font_metrics::maxAscent(font) * spacing_val); int maxdesc = int(font_metrics::maxDescent(font) * spacing_val); // insets may be taller - InsetList::iterator ii = pit->insetlist.begin(); - InsetList::iterator iend = pit->insetlist.end(); + InsetList::iterator ii = pars_[pit].insetlist.begin(); + InsetList::iterator iend = pars_[pit].insetlist.end(); for ( ; ii != iend; ++ii) { if (ii->pos >= row.pos() && ii->pos < row.endpos()) { maxasc = max(maxasc, ii->inset->ascent()); @@ -683,7 +932,7 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, Row & row) pos_type const pos_end = row.endpos(); LyXFont::FONT_SIZE maxsize = - pit->highestFontInRange(row.pos(), pos_end, size); + pars_[pit].highestFontInRange(row.pos(), pos_end, size); if (maxsize > font.size()) { font.setSize(maxsize); maxasc = max(maxasc, font_metrics::maxAscent(font)); @@ -702,22 +951,23 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, Row & row) // some parksips VERY EASY IMPLEMENTATION if (bv()->buffer()->params().paragraph_separation == BufferParams::PARSEP_SKIP - && pit != paragraphs().begin() - && ((layout->isParagraph() && pit->getDepth() == 0) - || (boost::prior(pit)->layout()->isParagraph() - && boost::prior(pit)->getDepth() == 0))) + && pit != 0 + && ((layout->isParagraph() && pars_[pit].getDepth() == 0) + || (pars_[pit - 1].layout()->isParagraph() + && pars_[pit - 1].getDepth() == 0))) { maxasc += bufparams.getDefSkip().inPixels(*bv()); } - if (pit->params().startOfAppendix()) + if (pars_[pit].params().startOfAppendix()) maxasc += int(3 * dh); // This is special code for the chapter, since the label of this // layout is printed in an extra row if (layout->counter == "chapter" && bufparams.secnumdepth >= 0) { labeladdon = int(font_metrics::maxHeight(labelfont) - * layout->spacing.getValue() * spacing(*pit)); + * layout->spacing.getValue() + * spacing(pars_[pit])); } // special code for the top label @@ -725,12 +975,12 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, Row & row) || layout->labeltype == LABEL_BIBLIO || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) && isFirstInSequence(pit, paragraphs()) - && !pit->getLabelstring().empty()) + && !pars_[pit].getLabelstring().empty()) { labeladdon = int( font_metrics::maxHeight(labelfont) * layout->spacing.getValue() - * spacing(*pit) + * spacing(pars_[pit]) + (layout->topsep + layout->labelbottomsep) * dh); } @@ -738,62 +988,60 @@ void LyXText::setHeightOfRow(ParagraphList::iterator pit, Row & row) // a section, or between the items of a itemize or enumerate // environment. - ParagraphList::iterator prev = - depthHook(pit, paragraphs(), pit->getDepth()); + par_type prev = depthHook(pit, pars_, pars_[pit].getDepth()); if (prev != pit - && prev->layout() == layout - && prev->getDepth() == pit->getDepth() - && prev->getLabelWidthString() == pit->getLabelWidthString()) + && pars_[prev].layout() == layout + && pars_[prev].getDepth() == pars_[pit].getDepth() + && pars_[prev].getLabelWidthString() == pars_[pit].getLabelWidthString()) { layoutasc = layout->itemsep * dh; - } else if (pit != paragraphs().begin() || row.pos() != 0) { + } else if (pit != 0 || row.pos() != 0) { if (layout->topsep > 0) layoutasc = layout->topsep * dh; } - prev = outerHook(pit, paragraphs()); - if (prev != paragraphs().end()) { - maxasc += int(prev->layout()->parsep * dh); - } else if (pit != paragraphs().begin()) { - ParagraphList::iterator prior_pit = boost::prior(pit); - if (prior_pit->getDepth() != 0 || - prior_pit->layout() == layout) { + prev = outerHook(pit, pars_); + if (prev != pars_.size()) { + maxasc += int(pars_[prev].layout()->parsep * dh); + } else if (pit != 0) { + if (pars_[pit - 1].getDepth() != 0 || + pars_[pit - 1].layout() == layout) { maxasc += int(layout->parsep * dh); } } } // is it a bottom line? - if (row.endpos() >= pit->size()) { + if (row.endpos() >= pars_[pit].size()) { // add the layout spaces, for example before and after // a section, or between the items of a itemize or enumerate // environment - ParagraphList::iterator nextpit = boost::next(pit); - if (nextpit != paragraphs().end()) { - ParagraphList::iterator cpit = pit; + par_type nextpit = pit + 1; + if (nextpit != pars_.size()) { + par_type cpit = pit; double usual = 0; double unusual = 0; - if (cpit->getDepth() > nextpit->getDepth()) { - usual = cpit->layout()->bottomsep * dh; - cpit = depthHook(cpit, paragraphs(), nextpit->getDepth()); - if (cpit->layout() != nextpit->layout() - || nextpit->getLabelWidthString() != cpit->getLabelWidthString()) + if (pars_[cpit].getDepth() > pars_[nextpit].getDepth()) { + usual = pars_[cpit].layout()->bottomsep * dh; + cpit = depthHook(cpit, paragraphs(), pars_[nextpit].getDepth()); + if (pars_[cpit].layout() != pars_[nextpit].layout() + || pars_[nextpit].getLabelWidthString() != pars_[cpit].getLabelWidthString()) { - unusual = cpit->layout()->bottomsep * dh; + unusual = pars_[cpit].layout()->bottomsep * dh; } layoutdesc = max(unusual, usual); - } else if (cpit->getDepth() == nextpit->getDepth()) { - if (cpit->layout() != nextpit->layout() - || nextpit->getLabelWidthString() != cpit->getLabelWidthString()) - layoutdesc = int(cpit->layout()->bottomsep * dh); + } else if (pars_[cpit].getDepth() == pars_[nextpit].getDepth()) { + if (pars_[cpit].layout() != pars_[nextpit].layout() + || pars_[nextpit].getLabelWidthString() != pars_[cpit].getLabelWidthString()) + layoutdesc = int(pars_[cpit].layout()->bottomsep * dh); } } } // incalculate the layout spaces - maxasc += int(layoutasc * 2 / (2 + pit->getDepth())); - maxdesc += int(layoutdesc * 2 / (2 + pit->getDepth())); + maxasc += int(layoutasc * 2 / (2 + pars_[pit].getDepth())); + maxdesc += int(layoutdesc * 2 / (2 + pars_[pit].getDepth())); row.height(maxasc + maxdesc + labeladdon); row.baseline(maxasc + labeladdon); @@ -806,7 +1054,7 @@ void LyXText::breakParagraph(LCursor & cur, char keep_layout) BOOST_ASSERT(this == cur.text()); // allow only if at start or end, or all previous is new text Paragraph & cpar = cur.paragraph(); - ParagraphList::iterator cpit = getPar(cur.par()); + par_type cpit = cur.par(); if (cur.pos() != 0 && cur.pos() != cur.lastpos() && cpar.isChangeEdited(0, cur.pos())) @@ -823,7 +1071,7 @@ void LyXText::breakParagraph(LCursor & cur, char keep_layout) return; // a layout change may affect also the following paragraph - recUndo(cur.par(), parOffset(undoSpan(cpit)) - 1); + recUndo(cur.par(), undoSpan(cur.par()) - 1); // Always break behind a space // It is better to erase the space (Dekel) @@ -844,17 +1092,17 @@ void LyXText::breakParagraph(LCursor & cur, char keep_layout) ::breakParagraph(bv()->buffer()->params(), paragraphs(), cpit, cur.pos(), keep_layout); - cpit = getPar(cur.par()); - ParagraphList::iterator next_par = boost::next(cpit); + cpit = cur.par(); + par_type next_par = cpit + 1; // well this is the caption hack since one caption is really enough if (layout->labeltype == LABEL_SENSITIVE) { if (!cur.pos()) // set to standard-layout - cpit->applyLayout(tclass.defaultLayout()); + pars_[cpit].applyLayout(tclass.defaultLayout()); else // set to standard-layout - next_par->applyLayout(tclass.defaultLayout()); + pars_[next_par].applyLayout(tclass.defaultLayout()); } // if the cursor is at the beginning of a row without prior newline, @@ -862,13 +1110,13 @@ void LyXText::breakParagraph(LCursor & cur, char keep_layout) // This touches only the screen-update. Otherwise we would may have // an empty row on the screen if (cur.pos() != 0 && cur.textRow().pos() == cur.pos() - && !cpit->isNewline(cur.pos() - 1)) + && !pars_[cpit].isNewline(cur.pos() - 1)) { cursorLeft(cur); } - while (!next_par->empty() && next_par->isNewline(0)) - next_par->erase(0); + while (!pars_[next_par].empty() && pars_[next_par].isNewline(0)) + pars_[next_par].erase(0); updateCounters(); redoParagraph(cpit); @@ -888,7 +1136,7 @@ void LyXText::redoParagraph(LCursor & cur) { BOOST_ASSERT(this == cur.text()); cur.clearSelection(); - redoParagraph(getPar(cur.par())); + redoParagraph(cur.par()); setCursorIntern(cur, cur.par(), cur.pos()); } @@ -904,7 +1152,7 @@ void LyXText::insertChar(LCursor & cur, char c) Paragraph & par = cur.paragraph(); // try to remove this - ParagraphList::iterator pit = getPar(cur.par()); + par_type pit = cur.par(); bool const freeSpacing = par.layout()->free_spacing || par.isFreeSpacing(); @@ -1010,41 +1258,40 @@ void LyXText::charInserted() } -RowMetrics -LyXText::computeRowMetrics(ParagraphList::iterator pit, Row const & row) const +RowMetrics LyXText::computeRowMetrics(par_type pit, Row const & row) const { RowMetrics result; double w = width_ - row.width(); - bool const is_rtl = isRTL(*pit); + bool const is_rtl = isRTL(pars_[pit]); if (is_rtl) - result.x = rightMargin(*pit); + result.x = rightMargin(pars_[pit]); else result.x = leftMargin(pit, row.pos()); // is there a manual margin with a manual label - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); if (layout->margintype == MARGIN_MANUAL && layout->labeltype == LABEL_MANUAL) { /// We might have real hfills in the label part - int nlh = numberOfLabelHfills(*pit, row); + int nlh = numberOfLabelHfills(pars_[pit], row); // A manual label par (e.g. List) has an auto-hfill // between the label text and the body of the // paragraph too. // But we don't want to do this auto hfill if the par // is empty. - if (!pit->empty()) + if (!pars_[pit].empty()) ++nlh; - if (nlh && !pit->getLabelWidthString().empty()) + if (nlh && !pars_[pit].getLabelWidthString().empty()) result.label_hfill = labelFill(pit, row) / double(nlh); } // are there any hfills in the row? - int const nh = numberOfHfills(*pit, row); + int const nh = numberOfHfills(pars_[pit], row); if (nh) { if (w > 0) @@ -1056,28 +1303,28 @@ LyXText::computeRowMetrics(ParagraphList::iterator pit, Row const & row) const // is it block, flushleft or flushright? // set x how you need it int align; - if (pit->params().align() == LYX_ALIGN_LAYOUT) + if (pars_[pit].params().align() == LYX_ALIGN_LAYOUT) align = layout->align; else - align = pit->params().align(); + align = pars_[pit].params().align(); // Display-style insets should always be on a centred row - // The test on pit->size() is to catch zero-size pars, which + // The test on pars_[pit].size() is to catch zero-size pars, which // would trigger the assert in Paragraph::getInset(). - //inset = pit->size() ? pit->getInset(row.pos()) : 0; - if (!pit->empty() - && pit->isInset(row.pos()) - && pit->getInset(row.pos())->display()) + //inset = pars_[pit].size() ? pars_[pit].getInset(row.pos()) : 0; + if (!pars_[pit].empty() + && pars_[pit].isInset(row.pos()) + && pars_[pit].getInset(row.pos())->display()) { align = LYX_ALIGN_CENTER; } switch (align) { case LYX_ALIGN_BLOCK: { - int const ns = numberOfSeparators(*pit, row); + int const ns = numberOfSeparators(pars_[pit], row); bool disp_inset = false; - if (row.endpos() < pit->size()) { - InsetBase * in = pit->getInset(row.endpos()); + if (row.endpos() < pars_[pit].size()) { + InsetBase const * in = pars_[pit].getInset(row.endpos()); if (in) disp_inset = in->display(); } @@ -1085,8 +1332,8 @@ LyXText::computeRowMetrics(ParagraphList::iterator pit, Row const & row) const // par, does not end in newline, and is not row above a // display inset... then stretch it if (ns - && row.endpos() < pit->size() - && !pit->isNewline(row.endpos() - 1) + && row.endpos() < pars_[pit].size() + && !pars_[pit].isNewline(row.endpos() - 1) && !disp_inset ) { result.separator = w / ns; @@ -1104,13 +1351,13 @@ LyXText::computeRowMetrics(ParagraphList::iterator pit, Row const & row) const } } - bidi.computeTables(*pit, *bv()->buffer(), row); + bidi.computeTables(pars_[pit], *bv()->buffer(), row); if (is_rtl) { - pos_type body_pos = pit->beginOfBody(); + pos_type body_pos = pars_[pit].beginOfBody(); pos_type end = row.endpos(); if (body_pos > 0 - && (body_pos > end || !pit->isLineSeparator(body_pos - 1))) + && (body_pos > end || !pars_[pit].isLineSeparator(body_pos - 1))) { result.x += font_metrics::width(layout->labelsep, getLabelFont(pit)); if (body_pos <= end) @@ -1201,10 +1448,10 @@ void LyXText::acceptChange(LCursor & cur) CursorSlice const & endc = cur.selEnd(); if (startc.par() == endc.par()) { recordUndoSelection(cur, Undo::INSERT); - getPar(startc)->acceptChange(startc.pos(), endc.pos()); + pars_[startc.par()].acceptChange(startc.pos(), endc.pos()); finishUndo(); cur.clearSelection(); - redoParagraph(getPar(startc)); + redoParagraph(startc.par()); setCursorIntern(cur, startc.par(), 0); } #warning handle multi par selection @@ -1221,10 +1468,10 @@ void LyXText::rejectChange(LCursor & cur) CursorSlice const & endc = cur.selEnd(); if (startc.par() == endc.par()) { recordUndoSelection(cur, Undo::INSERT); - getPar(startc)->rejectChange(startc.pos(), endc.pos()); + pars_[startc.par()].rejectChange(startc.pos(), endc.pos()); finishUndo(); cur.clearSelection(); - redoParagraph(getPar(startc)); + redoParagraph(startc.par()); setCursorIntern(cur, startc.par(), 0); } #warning handle multi par selection @@ -1304,15 +1551,14 @@ void LyXText::changeCase(LCursor & cur, LyXText::TextCase action) pos_type pos = from.pos(); int par = from.par(); - while (par != int(paragraphs().size()) && - (pos != to.pos() || par != to.par())) { - ParagraphList::iterator pit = getPar(par); - if (pos == pit->size()) { + while (par != int(pars_.size()) && (pos != to.pos() || par != to.par())) { + par_type pit = par; + if (pos == pars_[pit].size()) { ++par; pos = 0; continue; } - unsigned char c = pit->getChar(pos); + unsigned char c = pars_[pit].getChar(pos); if (c != Paragraph::META_INSET) { switch (action) { case text_lowercase: @@ -1328,7 +1574,7 @@ void LyXText::changeCase(LCursor & cur, LyXText::TextCase action) } } #warning changes - pit->setChar(pos, c); + pars_[pit].setChar(pos, c); ++pos; } } @@ -1340,7 +1586,7 @@ void LyXText::Delete(LCursor & cur) // just move to the right, if we had success make a backspace CursorSlice sl = cur.top(); cursorRight(cur); - if (sl == cur.top()) { + if (sl != cur.top()) { recordUndo(cur, Undo::DELETE, cur.par(), max(par_type(0), cur.par() - 1)); backspace(cur); @@ -1382,7 +1628,7 @@ void LyXText::backspace(LCursor & cur) if (cur.par() != 0) recordUndo(cur, Undo::DELETE, cur.par() - 1); - ParagraphList::iterator tmppit = getPar(cur.par()); + par_type tmppit = cur.par(); // We used to do cursorLeftIntern() here, but it is // not a good idea since it triggers the auto-delete // mechanism. So we do a cursorLeftIntern()-lite, @@ -1390,7 +1636,7 @@ void LyXText::backspace(LCursor & cur) if (cur.par() != 0) { // steps into the above paragraph. setCursorIntern(cur, cur.par() - 1, - getPar(cur.par() - 1)->size(), + pars_[cur.par() - 1].size(), false); } @@ -1401,15 +1647,15 @@ void LyXText::backspace(LCursor & cur) Buffer & buf = *bv()->buffer(); BufferParams const & bufparams = buf.params(); LyXTextClass const & tclass = bufparams.getLyXTextClass(); - ParagraphList::iterator const cpit = getPar(cur.par()); + par_type const cpit = cur.par(); if (cpit != tmppit - && (cpit->layout() == tmppit->layout() - || tmppit->layout() == tclass.defaultLayout()) - && cpit->getAlign() == tmppit->getAlign()) { + && (pars_[cpit].layout() == pars_[tmppit].layout() + || pars_[tmppit].layout() == tclass.defaultLayout()) + && pars_[cpit].getAlign() == pars_[tmppit].getAlign()) { mergeParagraph(bufparams, buf.paragraphs(), cpit); - if (cur.pos() != 0 && cpit->isSeparator(cur.pos() - 1)) + if (cur.pos() != 0 && pars_[cpit].isSeparator(cur.pos() - 1)) --cur.pos(); // the counters may have changed @@ -1437,50 +1683,40 @@ void LyXText::backspace(LCursor & cur) } -ParagraphList::iterator LyXText::getPar(CursorSlice const & cur) const -{ - return getPar(cur.par()); -} - - -ParagraphList::iterator LyXText::getPar(par_type par) const +Paragraph & LyXText::getPar(par_type par) const { //lyxerr << "getPar: " << par << " from " << paragraphs().size() << endl; BOOST_ASSERT(par >= 0); BOOST_ASSERT(par < int(paragraphs().size())); - ParagraphList::iterator pit = paragraphs().begin(); - advance(pit, par); - return pit; + return paragraphs()[par]; } // y is relative to this LyXText's top -RowList::iterator -LyXText::getRowNearY(int y, ParagraphList::iterator & pit) const +RowList::iterator LyXText::getRowNearY(int y, par_type & pit) const { BOOST_ASSERT(!paragraphs().empty()); BOOST_ASSERT(!paragraphs().begin()->rows.empty()); #if 1 - ParagraphList::iterator const - pend = boost::prior(paragraphs().end()); - pit = paragraphs().begin(); - while (int(pit->y + pit->height) < y && pit != pend) + par_type const pend = paragraphs().size() - 1; + pit = 0; + while (int(pars_[pit].y + pars_[pit].height) < y && pit != pend) ++pit; - RowList::iterator rit = pit->rows.end(); - RowList::iterator const rbegin = pit->rows.begin(); + RowList::iterator rit = pars_[pit].rows.end(); + RowList::iterator const rbegin = pars_[pit].rows.begin(); do { --rit; - } while (rit != rbegin && int(pit->y + rit->y_offset()) > y); + } while (rit != rbegin && int(pars_[pit].y + rit->y_offset()) > y); return rit; #else - pit = boost::prior(paragraphs().end()); + pit = paragraphs().size() - 1; RowList::iterator rit = lastRow(); RowList::iterator rbegin = firstRow(); - while (rit != rbegin && int(pit->y + rit->y_offset()) > y) + while (rit != rbegin && int(pars_[pit].y + rit->y_offset()) > y) previousRow(pit, rit); return rit; @@ -1506,81 +1742,72 @@ RowList::iterator LyXText::endRow() const } -void LyXText::nextRow(ParagraphList::iterator & pit, - RowList::iterator & rit) const +void LyXText::nextRow(par_type & pit, RowList::iterator & rit) const { ++rit; - if (rit == pit->rows.end()) { + if (rit == pars_[pit].rows.end()) { ++pit; - if (pit == paragraphs().end()) + if (pit == paragraphs().size()) --pit; else - rit = pit->rows.begin(); + rit = pars_[pit].rows.begin(); } } -void LyXText::previousRow(ParagraphList::iterator & pit, - RowList::iterator & rit) const +void LyXText::previousRow(par_type & pit, RowList::iterator & rit) const { - if (rit != pit->rows.begin()) + if (rit != pars_[pit].rows.begin()) --rit; else { - BOOST_ASSERT(pit != paragraphs().begin()); + BOOST_ASSERT(pit != 0); --pit; - rit = boost::prior(pit->rows.end()); + rit = boost::prior(pars_[pit].rows.end()); } } -int LyXText::parOffset(ParagraphList::iterator pit) const -{ - return distance(paragraphs().begin(), pit); -} - - -void LyXText::redoParagraphInternal(ParagraphList::iterator pit) +void LyXText::redoParagraphInternal(par_type pit) { // remove rows of paragraph, keep track of height changes - height_ -= pit->height; + height_ -= pars_[pit].height; // clear old data - pit->rows.clear(); - pit->height = 0; - pit->width = 0; + pars_[pit].rows.clear(); + pars_[pit].height = 0; + pars_[pit].width = 0; // redo insets - InsetList::iterator ii = pit->insetlist.begin(); - InsetList::iterator iend = pit->insetlist.end(); + InsetList::iterator ii = pars_[pit].insetlist.begin(); + InsetList::iterator iend = pars_[pit].insetlist.end(); for (; ii != iend; ++ii) { Dimension dim; - int const w = maxwidth_ - leftMargin(pit) - rightMargin(*pit); + int const w = maxwidth_ - leftMargin(pit) - rightMargin(pars_[pit]); MetricsInfo mi(bv(), getFont(pit, ii->pos), w); ii->inset->metrics(mi, dim); } // rebreak the paragraph - pit->setBeginOfBody(); + pars_[pit].setBeginOfBody(); pos_type z = 0; do { Row row(z); rowBreakPoint(pit, row); setRowWidth(pit, row); setHeightOfRow(pit, row); - row.y_offset(pit->height); - pit->rows.push_back(row); - pit->width = std::max(pit->width, row.width()); - pit->height += row.height(); + row.y_offset(pars_[pit].height); + pars_[pit].rows.push_back(row); + pars_[pit].width = std::max(pars_[pit].width, row.width()); + pars_[pit].height += row.height(); z = row.endpos(); - } while (z < pit->size()); + } while (z < pars_[pit].size()); - height_ += pit->height; - //lyxerr << "redoParagraph: " << pit->rows.size() << " rows\n"; + height_ += pars_[pit].height; + //lyxerr << "redoParagraph: " << pars_[pit].rows.size() << " rows\n"; } -void LyXText::redoParagraphs(ParagraphList::iterator pit, - ParagraphList::iterator end) +void LyXText::redoParagraphs(par_type pit, par_type end) { for ( ; pit != end; ++pit) redoParagraphInternal(pit); @@ -1588,7 +1815,7 @@ void LyXText::redoParagraphs(ParagraphList::iterator pit, } -void LyXText::redoParagraph(ParagraphList::iterator pit) +void LyXText::redoParagraph(par_type pit) { redoParagraphInternal(pit); updateParPositions(); @@ -1597,7 +1824,7 @@ void LyXText::redoParagraph(ParagraphList::iterator pit) void LyXText::fullRebreak() { - redoParagraphs(paragraphs().begin(), paragraphs().end()); + redoParagraphs(0, paragraphs().size()); bv()->cursor().resetAnchor(); } @@ -1612,7 +1839,7 @@ void LyXText::metrics(MetricsInfo & mi, Dimension & dim) //<< endl; // Rebuild row cache. This recomputes height as well. - redoParagraphs(paragraphs().begin(), paragraphs().end()); + redoParagraphs(0, paragraphs().size()); width_ = maxParagraphWidth(paragraphs()); @@ -1639,23 +1866,22 @@ void LyXText::drawSelection(PainterInfo &, int, int) const } -bool LyXText::isLastRow(ParagraphList::iterator pit, Row const & row) const +bool LyXText::isLastRow(par_type pit, Row const & row) const { - return row.endpos() >= pit->size() - && boost::next(pit) == paragraphs().end(); + return row.endpos() >= pars_[pit].size() && pit + 1 == paragraphs().size(); } -bool LyXText::isFirstRow(ParagraphList::iterator pit, Row const & row) const +bool LyXText::isFirstRow(par_type pit, Row const & row) const { - return row.pos() == 0 && pit == paragraphs().begin(); + return row.pos() == 0 && pit == 0; } void LyXText::getWord(CursorSlice & from, CursorSlice & to, word_location const loc) { - Paragraph & from_par = *getPar(from); + Paragraph & from_par = pars_[from.par()]; switch (loc) { case lyx::WHOLE_WORD_STRICT: if (from.pos() == 0 || from.pos() == from_par.size() @@ -1689,7 +1915,7 @@ void LyXText::getWord(CursorSlice & from, CursorSlice & to, break; } to = from; - Paragraph & to_par = *getPar(to); + Paragraph & to_par = pars_[to.par()]; while (to.pos() < to_par.size() && !to_par.isSeparator(to.pos()) && !to_par.isKomma(to.pos()) @@ -1717,7 +1943,6 @@ bool LyXText::read(Buffer const & buf, LyXLex & lex) static Change current_change; bool the_end_read = false; - ParagraphList::iterator pit = paragraphs().begin(); Paragraph::depth_type depth = 0; while (lex.isOK()) { @@ -1751,16 +1976,11 @@ bool LyXText::read(Buffer const & buf, LyXLex & lex) if (buf.params().tracking_changes) par.trackChanges(); par.setFont(0, LyXFont(LyXFont::ALL_INHERIT, buf.params().language)); - - // insert after - if (pit != paragraphs().end()) - ++pit; - - pit = paragraphs().insert(pit, par); + pars_.push_back(par); // FIXME: goddamn InsetTabular makes us pass a Buffer // not BufferParams - ::readParagraph(buf, *pit, lex); + ::readParagraph(buf, pars_.back(), lex); } else if (token == "\\begin_deeper") { ++depth; @@ -1793,11 +2013,11 @@ int LyXText::descent() const int LyXText::cursorX(CursorSlice const & cur) const { - ParagraphList::iterator pit = getPar(cur); - if (pit->rows.empty()) + par_type pit = cur.par(); + if (pars_[pit].rows.empty()) return xo_; - Row const & row = *pit->getRow(cur.pos()); + Row const & row = *pars_[pit].getRow(cur.pos()); pos_type pos = cur.pos(); pos_type cursor_vpos = 0; @@ -1811,7 +2031,7 @@ int LyXText::cursorX(CursorSlice const & cur) const if (end <= row_pos) cursor_vpos = row_pos; else if (pos >= end) - cursor_vpos = isRTL(*pit) ? row_pos : end; + cursor_vpos = isRTL(pars_[pit]) ? row_pos : end; else if (pos > row_pos && pos >= end) // Place cursor after char at (logical) position pos - 1 cursor_vpos = (bidi.level(pos - 1) % 2 == 0) @@ -1821,28 +2041,28 @@ int LyXText::cursorX(CursorSlice const & cur) const cursor_vpos = (bidi.level(pos) % 2 == 0) ? bidi.log2vis(pos) : bidi.log2vis(pos) + 1; - pos_type body_pos = pit->beginOfBody(); + pos_type body_pos = pars_[pit].beginOfBody(); if (body_pos > 0 && - (body_pos > end || !pit->isLineSeparator(body_pos - 1))) + (body_pos > end || !pars_[pit].isLineSeparator(body_pos - 1))) body_pos = 0; for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) { pos_type pos = bidi.vis2log(vpos); if (body_pos > 0 && pos == body_pos - 1) { x += m.label_hfill - + font_metrics::width(pit->layout()->labelsep, + + font_metrics::width(pars_[pit].layout()->labelsep, getLabelFont(pit)); - if (pit->isLineSeparator(body_pos - 1)) + if (pars_[pit].isLineSeparator(body_pos - 1)) x -= singleWidth(pit, body_pos - 1); } - if (hfillExpansion(*pit, row, pos)) { + if (hfillExpansion(pars_[pit], row, pos)) { x += singleWidth(pit, pos); if (pos >= body_pos) x += m.hfill; else x += m.label_hfill; - } else if (pit->isSeparator(pos)) { + } else if (pars_[pit].isSeparator(pos)) { x += singleWidth(pit, pos); if (pos >= body_pos) x += m.separator; @@ -1855,22 +2075,12 @@ int LyXText::cursorX(CursorSlice const & cur) const int LyXText::cursorY(CursorSlice const & cur) const { - Paragraph & par = *getPar(cur); + Paragraph & par = getPar(cur.par()); Row & row = *par.getRow(cur.pos()); return yo_ + par.y + row.y_offset() + row.baseline(); } -void LyXText::replaceSelection(LCursor & cur) -{ - BOOST_ASSERT(this == cur.text()); - if (cur.selection()) { - cutSelection(cur, true, false); - cur.update(); - } -} - - // Returns the current font and depth as a message. string LyXText::currentState(LCursor & cur) { @@ -1938,12 +2148,7 @@ string LyXText::currentState(LCursor & cur) os << _(", Position: ") << cur.pos(); Row & row = cur.textRow(); os << bformat(_(", Row b:%1$d e:%2$d"), row.pos(), row.endpos()); - os << _(", Inset: "); - InsetOld * inset = par.inInset(); - if (inset) - os << inset << " owner: " << inset->owner(); - else - os << -1; + os << _(", Inset: ") << par.inInset(); #endif return os.str(); } @@ -1951,18 +2156,14 @@ string LyXText::currentState(LCursor & cur) string LyXText::getPossibleLabel(LCursor & cur) const { - ParagraphList & plist = paragraphs(); - ParagraphList::iterator pit = getPar(cur.par()); + par_type pit = cur.par(); - LyXLayout_ptr layout = pit->layout(); - - if (layout->latextype == LATEX_PARAGRAPH && pit != plist.begin()) { - ParagraphList::iterator pit2 = boost::prior(pit); - - LyXLayout_ptr const & layout2 = pit2->layout(); + LyXLayout_ptr layout = pars_[pit].layout(); + if (layout->latextype == LATEX_PARAGRAPH && pit != 0) { + LyXLayout_ptr const & layout2 = pars_[pit - 1].layout(); if (layout2->latextype != LATEX_PARAGRAPH) { - pit = pit2; + --pit; layout = layout2; } } @@ -1975,7 +2176,7 @@ string LyXText::getPossibleLabel(LCursor & cur) const if (layout->latextype == LATEX_PARAGRAPH || lyxrc.label_init_length < 0) text.erase(); - string par_text = pit->asString(*cur.bv().buffer(), false); + string par_text = pars_[pit].asString(*cur.bv().buffer(), false); for (int i = 0; i < lyxrc.label_init_length; ++i) { if (par_text.empty()) break; diff --git a/src/text2.C b/src/text2.C index 889cbfed51..226d342687 100644 --- a/src/text2.C +++ b/src/text2.C @@ -44,7 +44,6 @@ #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" -#include "PosIterator.h" #include "undo.h" #include "vspace.h" @@ -61,8 +60,7 @@ #include "support/tostr.h" #include "support/std_sstream.h" -#include - +using lyx::par_type; using lyx::pos_type; using lyx::support::bformat; @@ -80,23 +78,18 @@ LyXText::LyXText(BufferView * bv) void LyXText::init(BufferView * bv) { + BOOST_ASSERT(bv); bv_owner = bv; - - ParagraphList::iterator const beg = paragraphs().begin(); - ParagraphList::iterator const end = paragraphs().end(); - for (ParagraphList::iterator pit = beg; pit != end; ++pit) - pit->rows.clear(); - maxwidth_ = bv->workWidth(); width_ = maxwidth_; height_ = 0; - current_font = getFont(beg, 0); - - redoParagraphs(beg, end); - // why? - bv->cursor().resetAnchor(); + par_type const end = paragraphs().size(); + for (par_type pit = 0; pit != end; ++pit) + pars_[pit].rows.clear(); + current_font = getFont(0, 0); + redoParagraphs(0, end); updateCounters(); } @@ -112,18 +105,18 @@ bool LyXText::isMainText() const // The difference is that this one is used for displaying, and thus we // are allowed to make cosmetic improvements. For instance make footnotes // smaller. (Asger) -LyXFont LyXText::getFont(ParagraphList::iterator pit, pos_type pos) const +LyXFont LyXText::getFont(par_type pit, pos_type pos) const { BOOST_ASSERT(pos >= 0); - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); #warning broken? BufferParams const & params = bv()->buffer()->params(); - pos_type const body_pos = pit->beginOfBody(); + pos_type const body_pos = pars_[pit].beginOfBody(); // We specialize the 95% common case: - if (!pit->getDepth()) { - LyXFont f = pit->getFontSettings(params, pos); + if (!pars_[pit].getDepth()) { + LyXFont f = pars_[pit].getFontSettings(params, pos); if (!isMainText()) f.realize(font_); if (layout->labeltype == LABEL_MANUAL && pos < body_pos) @@ -139,7 +132,7 @@ LyXFont LyXText::getFont(ParagraphList::iterator pit, pos_type pos) const else layoutfont = layout->font; - LyXFont font = pit->getFontSettings(params, pos); + LyXFont font = pars_[pit].getFontSettings(params, pos); font.realize(layoutfont); if (!isMainText()) @@ -153,11 +146,11 @@ LyXFont LyXText::getFont(ParagraphList::iterator pit, pos_type pos) const } -LyXFont LyXText::getLayoutFont(ParagraphList::iterator pit) const +LyXFont LyXText::getLayoutFont(par_type pit) const { - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); - if (!pit->getDepth()) + if (!pars_[pit].getDepth()) return layout->resfont; LyXFont font = layout->font; @@ -169,11 +162,11 @@ LyXFont LyXText::getLayoutFont(ParagraphList::iterator pit) const } -LyXFont LyXText::getLabelFont(ParagraphList::iterator pit) const +LyXFont LyXText::getLabelFont(par_type pit) const { - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); - if (!pit->getDepth()) + if (!pars_[pit].getDepth()) return layout->reslabelfont; LyXFont font = layout->labelfont; @@ -185,29 +178,28 @@ LyXFont LyXText::getLabelFont(ParagraphList::iterator pit) const } -void LyXText::setCharFont( - ParagraphList::iterator pit, pos_type pos, LyXFont const & fnt) +void LyXText::setCharFont(par_type pit, pos_type pos, LyXFont const & fnt) { LyXFont font = fnt; - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); // Get concrete layout font to reduce against LyXFont layoutfont; - if (pos < pit->beginOfBody()) + if (pos < pars_[pit].beginOfBody()) layoutfont = layout->labelfont; else layoutfont = layout->font; // Realize against environment font information - if (pit->getDepth()) { - ParagraphList::iterator tp = pit; + if (pars_[pit].getDepth()) { + par_type tp = pit; while (!layoutfont.resolved() && - tp != paragraphs().end() && - tp->getDepth()) { + tp != paragraphs().size() && + pars_[tp].getDepth()) { tp = outerHook(tp, paragraphs()); - if (tp != paragraphs().end()) - layoutfont.realize(tp->layout()->font); + if (tp != paragraphs().size()) + layoutfont.realize(pars_[tp].layout()->font); } } @@ -216,7 +208,7 @@ void LyXText::setCharFont( // Now, reduce font against full layout font font.reduce(layoutfont); - pit->setFont(pos, font); + pars_[pit].setFont(pos, font); } @@ -243,42 +235,38 @@ void LyXText::makeFontEntriesLayoutSpecific(BufferParams const & params, // return past-the-last paragraph influenced by a layout change on pit -ParagraphList::iterator LyXText::undoSpan(ParagraphList::iterator pit) +par_type LyXText::undoSpan(par_type pit) { - ParagraphList::iterator end = paragraphs().end(); - ParagraphList::iterator nextpit = boost::next(pit); + par_type end = paragraphs().size(); + par_type nextpit = pit + 1; if (nextpit == end) return nextpit; //because of parindents - if (!pit->getDepth()) + if (!pars_[pit].getDepth()) return boost::next(nextpit); //because of depth constrains for (; nextpit != end; ++pit, ++nextpit) { - if (!pit->getDepth()) + if (!pars_[pit].getDepth()) break; } return nextpit; } -ParagraphList::iterator -LyXText::setLayout(ParagraphList::iterator start, - ParagraphList::iterator end, - string const & layout) +par_type LyXText::setLayout(par_type start, par_type end, string const & layout) { BOOST_ASSERT(start != end); - ParagraphList::iterator undopit = undoSpan(boost::prior(end)); - recUndo(parOffset(start), parOffset(undopit) - 1); + par_type undopit = undoSpan(end - 1); + recUndo(start, undopit - 1); BufferParams const & bufparams = bv()->buffer()->params(); - LyXLayout_ptr const & lyxlayout = - bufparams.getLyXTextClass()[layout]; + LyXLayout_ptr const & lyxlayout = bufparams.getLyXTextClass()[layout]; - for (ParagraphList::iterator pit = start; pit != end; ++pit) { - pit->applyLayout(lyxlayout); - makeFontEntriesLayoutSpecific(bufparams, *pit); + for (par_type pit = start; pit != end; ++pit) { + pars_[pit].applyLayout(lyxlayout); + makeFontEntriesLayoutSpecific(bufparams, pars_[pit]); if (lyxlayout->margintype == MARGIN_MANUAL) - pit->setLabelWidthString(lyxlayout->labelstring()); + pars_[pit].setLabelWidthString(lyxlayout->labelstring()); } return undopit; @@ -305,9 +293,9 @@ void LyXText::setLayout(LCursor & cur, string const & layout) return; } - ParagraphList::iterator start = getPar(cur.selBegin().par()); - ParagraphList::iterator end = boost::next(getPar(cur.selEnd().par())); - ParagraphList::iterator endpit = setLayout(start, end, layout); + par_type start = cur.selBegin().par(); + par_type end = cur.selEnd().par() + 1; + par_type endpit = setLayout(start, end, layout); redoParagraphs(start, endpit); updateCounters(); } @@ -316,16 +304,14 @@ void LyXText::setLayout(LCursor & cur, string const & layout) namespace { -void getSelectionSpan(LCursor & cur, LyXText & text, - ParagraphList::iterator & beg, - ParagraphList::iterator & end) +void getSelectionSpan(LCursor & cur, par_type & beg, par_type & end) { if (!cur.selection()) { - beg = text.getPar(cur.par()); - end = boost::next(beg); + beg = cur.par(); + end = cur.par() + 1; } else { - beg = text.getPar(cur.selBegin()); - end = boost::next(text.getPar(cur.selEnd())); + beg = cur.selBegin().par(); + end = cur.selEnd().par() + 1; } } @@ -350,16 +336,16 @@ bool changeDepthAllowed(LyXText::DEPTH_CHANGE type, bool LyXText::changeDepthAllowed(LCursor & cur, DEPTH_CHANGE type) const { BOOST_ASSERT(this == cur.text()); - ParagraphList::iterator beg, end; - getSelectionSpan(cur, const_cast(*this), beg, end); + par_type beg, end; + getSelectionSpan(cur, beg, end); int max_depth = 0; - if (beg != paragraphs().begin()) - max_depth = boost::prior(beg)->getMaxDepthAfter(); + if (beg != 0) + max_depth = pars_[beg - 1].getMaxDepthAfter(); - for (ParagraphList::iterator pit = beg; pit != end; ++pit) { - if (::changeDepthAllowed(type, *pit, max_depth)) + for (par_type pit = beg; pit != end; ++pit) { + if (::changeDepthAllowed(type, pars_[pit], max_depth)) return true; - max_depth = pit->getMaxDepthAfter(); + max_depth = pars_[pit].getMaxDepthAfter(); } return false; } @@ -368,23 +354,23 @@ bool LyXText::changeDepthAllowed(LCursor & cur, DEPTH_CHANGE type) const void LyXText::changeDepth(LCursor & cur, DEPTH_CHANGE type) { BOOST_ASSERT(this == cur.text()); - ParagraphList::iterator beg, end; - getSelectionSpan(cur, *this, beg, end); + par_type beg, end; + getSelectionSpan(cur, beg, end); recordUndoSelection(cur); int max_depth = 0; - if (beg != paragraphs().begin()) - max_depth = boost::prior(beg)->getMaxDepthAfter(); + if (beg != 0) + max_depth = pars_[beg - 1].getMaxDepthAfter(); - for (ParagraphList::iterator pit = beg; pit != end; ++pit) { - if (::changeDepthAllowed(type, *pit, max_depth)) { - int const depth = pit->params().depth(); + for (par_type pit = beg; pit != end; ++pit) { + if (::changeDepthAllowed(type, pars_[pit], max_depth)) { + int const depth = pars_[pit].params().depth(); if (type == INC_DEPTH) - pit->params().depth(depth + 1); + pars_[pit].params().depth(depth + 1); else - pit->params().depth(depth - 1); + pars_[pit].params().depth(depth - 1); } - max_depth = pit->getMaxDepthAfter(); + max_depth = pars_[pit].getMaxDepthAfter(); } // this handles the counter labels, and also fixes up // depth values for follow-on (child) paragraphs @@ -392,7 +378,7 @@ void LyXText::changeDepth(LCursor & cur, DEPTH_CHANGE type) } -// set font over selection and make a total rebreak of those paragraphs +// set font over selection void LyXText::setFont(LCursor & cur, LyXFont const & font, bool toggleall) { BOOST_ASSERT(this == cur.text()); @@ -400,8 +386,8 @@ void LyXText::setFont(LCursor & cur, LyXFont const & font, bool toggleall) if (!cur.selection()) { // Determine basis font LyXFont layoutfont; - ParagraphList::iterator pit = getPar(cur.par()); - if (cur.pos() < pit->beginOfBody()) + par_type pit = cur.par(); + if (cur.pos() < pars_[pit].beginOfBody()) layoutfont = getLabelFont(pit); else layoutfont = getLayoutFont(pit); @@ -423,21 +409,21 @@ void LyXText::setFont(LCursor & cur, LyXFont const & font, bool toggleall) // Ok, we have a selection. recordUndoSelection(cur); - ParagraphList::iterator beg = getPar(cur.selBegin().par()); - ParagraphList::iterator end = getPar(cur.selEnd().par()); - - PosIterator pos(¶graphs(), beg, cur.selBegin().pos()); - PosIterator posend(¶graphs(), end, cur.selEnd().pos()); + par_type const beg = cur.selBegin().par(); + par_type const end = cur.selEnd().par(); + + DocumentIterator pos = cur.selectionBegin(); + DocumentIterator posend = cur.selectionEnd(); BufferParams const & params = bv()->buffer()->params(); - for (; pos != posend; ++pos) { - LyXFont f = getFont(pos.pit(), pos.pos()); + for (; pos != posend; pos.forwardChar()) { + LyXFont f = getFont(pos.par(), pos.pos()); f.update(font, params.language, toggleall); - setCharFont(pos.pit(), pos.pos(), f); + setCharFont(pos.par(), pos.pos(), f); } - redoParagraphs(beg, ++end); + redoParagraphs(beg, end + 1); } @@ -538,30 +524,23 @@ string LyXText::getStringToIndex(LCursor & cur) } -// the DTP switches for paragraphs(). LyX will store them in the first -// physical paragraph. When a paragraph is broken, the top settings rest, -// the bottom settings are given to the new one. So I can make sure, -// they do not duplicate themself and you cannot play dirty tricks with -// them! - void LyXText::setParagraph(LCursor & cur, Spacing const & spacing, LyXAlignment align, string const & labelwidthstring, bool noindent) { BOOST_ASSERT(cur.text()); // make sure that the depth behind the selection are restored, too - ParagraphList::iterator undopit = undoSpan(getPar(cur.selEnd())); - recUndo(cur.selBegin().par(), parOffset(undopit) - 1); + par_type undopit = undoSpan(cur.selEnd().par()); + recUndo(cur.selBegin().par(), undopit - 1); - ParagraphList::reverse_iterator pit(getPar(cur.selEnd().par())); - ParagraphList::reverse_iterator beg(getPar(cur.selBegin().par())); - - for (--pit; pit != beg; ++pit) { - ParagraphParameters & params = pit->params(); + for (par_type pit = cur.selBegin().par(), end = cur.selEnd().par(); + pit <= end; ++pit) { + Paragraph & par = pars_[pit]; + ParagraphParameters & params = par.params(); params.spacing(spacing); // does the layout allow the new alignment? - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = par.layout(); if (align == LYX_ALIGN_LAYOUT) align = layout->align; @@ -571,11 +550,11 @@ void LyXText::setParagraph(LCursor & cur, else params.align(align); } - pit->setLabelWidthString(labelwidthstring); + par.setLabelWidthString(labelwidthstring); params.noindent(noindent); } - redoParagraphs(getPar(cur.selBegin()), undopit); + redoParagraphs(cur.selBegin().par(), undopit); } @@ -603,33 +582,32 @@ string expandLabel(LyXTextClass const & textclass, namespace { -void incrementItemDepth(ParagraphList::iterator pit, - ParagraphList::iterator first_pit) +void incrementItemDepth(ParagraphList & pars, par_type pit, par_type first_pit) { - int const cur_labeltype = pit->layout()->labeltype; + int const cur_labeltype = pars[pit].layout()->labeltype; if (cur_labeltype != LABEL_ENUMERATE && cur_labeltype != LABEL_ITEMIZE) return; - int const cur_depth = pit->getDepth(); + int const cur_depth = pars[pit].getDepth(); - ParagraphList::iterator prev_pit = boost::prior(pit); + par_type prev_pit = pit - 1; while (true) { - int const prev_depth = prev_pit->getDepth(); - int const prev_labeltype = prev_pit->layout()->labeltype; + int const prev_depth = pars[prev_pit].getDepth(); + int const prev_labeltype = pars[prev_pit].layout()->labeltype; if (prev_depth == 0 && cur_depth > 0) { if (prev_labeltype == cur_labeltype) { - pit->itemdepth = prev_pit->itemdepth + 1; + pars[pit].itemdepth = pars[prev_pit].itemdepth + 1; } break; } else if (prev_depth < cur_depth) { if (prev_labeltype == cur_labeltype) { - pit->itemdepth = prev_pit->itemdepth + 1; + pars[pit].itemdepth = pars[prev_pit].itemdepth + 1; break; } } else if (prev_depth == cur_depth) { if (prev_labeltype == cur_labeltype) { - pit->itemdepth = prev_pit->itemdepth; + pars[pit].itemdepth = pars[prev_pit].itemdepth; break; } } @@ -641,21 +619,20 @@ void incrementItemDepth(ParagraphList::iterator pit, } -void resetEnumCounterIfNeeded(ParagraphList::iterator pit, - ParagraphList::iterator firstpit, - Counters & counters) +void resetEnumCounterIfNeeded(ParagraphList & pars, par_type pit, + par_type firstpit, Counters & counters) { if (pit == firstpit) return; - int const cur_depth = pit->getDepth(); - ParagraphList::iterator prev_pit = boost::prior(pit); + int const cur_depth = pars[pit].getDepth(); + par_type prev_pit = pit - 1; while (true) { - int const prev_depth = prev_pit->getDepth(); - int const prev_labeltype = prev_pit->layout()->labeltype; + int const prev_depth = pars[prev_pit].getDepth(); + int const prev_labeltype = pars[prev_pit].layout()->labeltype; if (prev_depth <= cur_depth) { if (prev_labeltype != LABEL_ENUMERATE) { - switch (pit->itemdepth) { + switch (pars[pit].itemdepth) { case 0: counters.reset("enumi"); case 1: @@ -680,39 +657,39 @@ void resetEnumCounterIfNeeded(ParagraphList::iterator pit, // set the counter of a paragraph. This includes the labels -void LyXText::setCounter(Buffer const & buf, ParagraphList::iterator pit) +void LyXText::setCounter(Buffer const & buf, par_type pit) { BufferParams const & bufparams = buf.params(); LyXTextClass const & textclass = bufparams.getLyXTextClass(); - LyXLayout_ptr const & layout = pit->layout(); - ParagraphList::iterator first_pit = paragraphs().begin(); + LyXLayout_ptr const & layout = pars_[pit].layout(); + par_type first_pit = 0; Counters & counters = textclass.counters(); // Always reset - pit->itemdepth = 0; + pars_[pit].itemdepth = 0; if (pit == first_pit) { - pit->params().appendix(pit->params().startOfAppendix()); + pars_[pit].params().appendix(pars_[pit].params().startOfAppendix()); } else { - pit->params().appendix(boost::prior(pit)->params().appendix()); - if (!pit->params().appendix() && - pit->params().startOfAppendix()) { - pit->params().appendix(true); + pars_[pit].params().appendix(pars_[pit - 1].params().appendix()); + if (!pars_[pit].params().appendix() && + pars_[pit].params().startOfAppendix()) { + pars_[pit].params().appendix(true); textclass.counters().reset(); } // Maybe we have to increment the item depth. - incrementItemDepth(pit, first_pit); + incrementItemDepth(pars_, pit, first_pit); } // erase what was there before - pit->params().labelString(string()); + pars_[pit].params().labelString(string()); if (layout->margintype == MARGIN_MANUAL) { - if (pit->params().labelWidthString().empty()) - pit->setLabelWidthString(layout->labelstring()); + if (pars_[pit].params().labelWidthString().empty()) + pars_[pit].setLabelWidthString(layout->labelstring()); } else { - pit->setLabelWidthString(string()); + pars_[pit].setLabelWidthString(string()); } // is it a layout that has an automatic label? @@ -720,16 +697,16 @@ void LyXText::setCounter(Buffer const & buf, ParagraphList::iterator pit) BufferParams const & bufparams = buf.params(); LyXTextClass const & textclass = bufparams.getLyXTextClass(); counters.step(layout->counter); - string label = expandLabel(textclass, layout, pit->params().appendix()); - pit->params().labelString(label); + string label = expandLabel(textclass, layout, pars_[pit].params().appendix()); + pars_[pit].params().labelString(label); } else if (layout->labeltype == LABEL_ITEMIZE) { // At some point of time we should do something more // clever here, like: - // pit->params().labelString( - // bufparams.user_defined_bullet(pit->itemdepth).getText()); + // pars_[pit].params().labelString( + // bufparams.user_defined_bullet(pars_[pit].itemdepth).getText()); // for now, use a simple hardcoded label string itemlabel; - switch (pit->itemdepth) { + switch (pars_[pit].itemdepth) { case 0: itemlabel = "*"; break; @@ -744,17 +721,17 @@ void LyXText::setCounter(Buffer const & buf, ParagraphList::iterator pit) break; } - pit->params().labelString(itemlabel); + pars_[pit].params().labelString(itemlabel); } else if (layout->labeltype == LABEL_ENUMERATE) { // Maybe we have to reset the enumeration counter. - resetEnumCounterIfNeeded(pit, first_pit, counters); + resetEnumCounterIfNeeded(pars_, pit, first_pit, counters); // FIXME // Yes I know this is a really, really! bad solution // (Lgb) string enumcounter = "enum"; - switch (pit->itemdepth) { + switch (pars_[pit].itemdepth) { case 2: enumcounter += 'i'; case 1: @@ -772,13 +749,13 @@ void LyXText::setCounter(Buffer const & buf, ParagraphList::iterator pit) counters.step(enumcounter); - pit->params().labelString(counters.enumLabel(enumcounter)); + pars_[pit].params().labelString(counters.enumLabel(enumcounter)); } else if (layout->labeltype == LABEL_BIBLIO) {// ale970302 counters.step("bibitem"); int number = counters.value("bibitem"); - if (pit->bibitem()) { - pit->bibitem()->setCounter(number); - pit->params().labelString(layout->labelstring()); + if (pars_[pit].bibitem()) { + pars_[pit].bibitem()->setCounter(number); + pars_[pit].params().labelString(layout->labelstring()); } // In biblio should't be following counters but... } else { @@ -786,13 +763,13 @@ void LyXText::setCounter(Buffer const & buf, ParagraphList::iterator pit) // the caption hack: if (layout->labeltype == LABEL_SENSITIVE) { - ParagraphList::iterator end = paragraphs().end(); - ParagraphList::iterator tmppit = pit; + par_type end = paragraphs().size(); + par_type tmppit = pit; InsetBase * in = 0; bool isOK = false; - while (tmppit != end && tmppit->inInset() + while (tmppit != end && pars_[tmppit].inInset() // the single '=' is intended below - && (in = tmppit->inInset()->owner())) + && (in = pars_[tmppit].inInset())) { if (in->lyxCode() == InsetBase::FLOAT_CODE || in->lyxCode() == InsetBase::WRAP_CODE) { @@ -802,7 +779,7 @@ void LyXText::setCounter(Buffer const & buf, ParagraphList::iterator pit) Paragraph const * owner = &ownerPar(buf, in); tmppit = first_pit; for ( ; tmppit != end; ++tmppit) - if (&*tmppit == owner) + if (&pars_[tmppit] == owner) break; } } @@ -829,7 +806,7 @@ void LyXText::setCounter(Buffer const & buf, ParagraphList::iterator pit) s = _("Senseless: "); } } - pit->params().labelString(s); + pars_[pit].params().labelString(s); } } @@ -843,25 +820,25 @@ void LyXText::updateCounters() bool update_pos = false; - ParagraphList::iterator beg = paragraphs().begin(); - ParagraphList::iterator end = paragraphs().end(); - for (ParagraphList::iterator pit = beg; pit != end; ++pit) { - string const oldLabel = pit->params().labelString(); + par_type end = paragraphs().size(); + for (par_type pit = 0; pit != end; ++pit) { + string const oldLabel = pars_[pit].params().labelString(); size_t maxdepth = 0; - if (pit != beg) - maxdepth = boost::prior(pit)->getMaxDepthAfter(); + if (pit != 0) + maxdepth = pars_[pit - 1].getMaxDepthAfter(); - if (pit->params().depth() > maxdepth) - pit->params().depth(maxdepth); + if (pars_[pit].params().depth() > maxdepth) + pars_[pit].params().depth(maxdepth); // setCounter can potentially change the labelString. setCounter(*bv()->buffer(), pit); - string const & newLabel = pit->params().labelString(); + string const & newLabel = pars_[pit].params().labelString(); if (oldLabel != newLabel) { + //lyxerr << "changing labels: old: " << oldLabel << " new: " + // << newLabel << endl; redoParagraphInternal(pit); update_pos = true; } - } if (update_pos) updateParPositions(); @@ -877,172 +854,19 @@ void LyXText::insertInset(LCursor & cur, InsetBase * inset) } -void LyXText::cutSelection(LCursor & cur, bool doclear, bool realcut) -{ - BOOST_ASSERT(this == cur.text()); - // Stuff what we got on the clipboard. Even if there is no selection. - - // There is a problem with having the stuffing here in that the - // larger the selection the slower LyX will get. This can be - // solved by running the line below only when the selection has - // finished. The solution used currently just works, to make it - // faster we need to be more clever and probably also have more - // calls to stuffClipboard. (Lgb) - bv()->stuffClipboard(cur.selectionAsString(true)); - - // This doesn't make sense, if there is no selection - if (!cur.selection()) - return; - - // OK, we have a selection. This is always between cur.selBegin() - // and cur.selEnd() - - // make sure that the depth behind the selection are restored, too - recordUndoSelection(cur); - ParagraphList::iterator begpit = getPar(cur.selBegin().par()); - ParagraphList::iterator endpit = getPar(cur.selEnd().par()); - ParagraphList::iterator undopit = undoSpan(endpit); - - int endpos = cur.selEnd().pos(); - - BufferParams const & bufparams = bv()->buffer()->params(); - boost::tie(endpit, endpos) = realcut ? - CutAndPaste::cutSelection(bufparams, - paragraphs(), - begpit, endpit, - cur.selBegin().pos(), endpos, - bufparams.textclass, - doclear) - : CutAndPaste::eraseSelection(bufparams, - paragraphs(), - begpit, endpit, - cur.selBegin().pos(), endpos, - doclear); - // sometimes necessary - if (doclear) - begpit->stripLeadingSpaces(); - - redoParagraphs(begpit, undopit); - // cutSelection can invalidate the cursor so we need to set - // it anew. (Lgb) - // we prefer the end for when tracking changes - cur.pos() = endpos; - cur.par() = parOffset(endpit); - - // need a valid cursor. (Lgb) - cur.clearSelection(); - updateCounters(); -} - - -void LyXText::copySelection(LCursor & cur) -{ - BOOST_ASSERT(this == cur.text()); - // stuff the selection onto the X clipboard, from an explicit copy request - bv()->stuffClipboard(cur.selectionAsString(true)); - - // this doesnt make sense, if there is no selection - if (!cur.selection()) - return; - - // ok we have a selection. This is always between cur.selBegin() - // and sel_end cursor - - // copy behind a space if there is one - while (getPar(cur.selBegin())->size() > cur.selBegin().pos() - && getPar(cur.selBegin())->isLineSeparator(cur.selBegin().pos()) - && (cur.selBegin().par() != cur.selEnd().par() - || cur.selBegin().pos() < cur.selEnd().pos())) - ++cur.selBegin().pos(); - - CutAndPaste::copySelection(getPar(cur.selBegin().par()), - getPar(cur.selEnd().par()), - cur.selBegin().pos(), - cur.selEnd().pos(), - bv()->buffer()->params().textclass); -} - - -void LyXText::pasteSelection(LCursor & cur, size_t sel_index) -{ - // this does not make sense, if there is nothing to paste - if (!CutAndPaste::checkPastePossible()) - return; - - recordUndo(cur); - - ParagraphList::iterator endpit; - PitPosPair ppp; - - ErrorList el; - - boost::tie(ppp, endpit) = - CutAndPaste::pasteSelection(*bv()->buffer(), - paragraphs(), - getPar(cur.par()), cur.pos(), - bv()->buffer()->params().textclass, - sel_index, el); - bufferErrors(*bv()->buffer(), el); - bv()->showErrorList(_("Paste")); - - redoParagraphs(getPar(cur.par()), endpit); - - cur.clearSelection(); - cur.resetAnchor(); - setCursor(cur, parOffset(ppp.first), ppp.second); - cur.setSelection(); - updateCounters(); -} - - -void LyXText::setSelectionRange(LCursor & cur, lyx::pos_type length) -{ - if (!length) - return; - cur.resetAnchor(); - while (length--) - cursorRight(cur); - cur.setSelection(); -} - - -// simple replacing. The font of the first selected character is used -void LyXText::replaceSelectionWithString(LCursor & cur, string const & str) -{ - recordUndo(cur); - - // Get font setting before we cut - pos_type pos = cur.selEnd().pos(); - LyXFont const font = getPar(cur.selBegin()) - ->getFontSettings(bv()->buffer()->params(), - cur.selBegin().pos()); - - // Insert the new string - string::const_iterator cit = str.begin(); - string::const_iterator end = str.end(); - for (; cit != end; ++cit) { - getPar(cur.selEnd())->insertChar(pos, (*cit), font); - ++pos; - } - - // Cut the selection - cutSelection(cur, true, false); -} - - // needed to insert the selection void LyXText::insertStringAsLines(LCursor & cur, string const & str) { - ParagraphList::iterator pit = getPar(cur.par()); - ParagraphList::iterator endpit = boost::next(pit); + par_type pit = cur.par(); + par_type endpit = cur.par() + 1; pos_type pos = cur.pos(); recordUndo(cur); // only to be sure, should not be neccessary cur.clearSelection(); - bv()->buffer()->insertStringAsLines(pit, pos, current_font, str); + bv()->buffer()->insertStringAsLines(pars_, pit, pos, current_font, str); - redoParagraphs(getPar(cur.par()), endpit); + redoParagraphs(cur.par(), endpit); cur.resetAnchor(); setCursor(cur, cur.par(), pos); cur.setSelection(); @@ -1079,9 +903,9 @@ void LyXText::insertStringAsParagraphs(LCursor & cur, string const & str) bool LyXText::setCursor(LCursor & cur, par_type par, pos_type pos, bool setfont, bool boundary) { - CursorSlice old_cursor = cur.top(); + LCursor old = cur; setCursorIntern(cur, par, pos, setfont, boundary); - return deleteEmptyParagraphMechanism(cur.top(), old_cursor); + return deleteEmptyParagraphMechanism(cur, old); } @@ -1099,7 +923,7 @@ void LyXText::setCursor(CursorSlice & cur, par_type par, return; // now some strict checking - Paragraph & para = *getPar(par); + Paragraph & para = getPar(par); Row const & row = *para.getRow(pos); pos_type const end = row.endpos(); @@ -1150,7 +974,7 @@ void LyXText::setCurrentFont(LCursor & cur) { BOOST_ASSERT(this == cur.text()); pos_type pos = cur.pos(); - ParagraphList::iterator pit = getPar(cur.par()); + par_type pit = cur.par(); if (cur.boundary() && pos > 0) --pos; @@ -1159,7 +983,7 @@ void LyXText::setCurrentFont(LCursor & cur) if (pos == cur.lastpos()) --pos; else // potentional bug... BUG (Lgb) - if (pit->isSeparator(pos)) { + if (pars_[pit].isSeparator(pos)) { if (pos > cur.textRow().pos() && bidi.level(pos) % 2 == bidi.level(pos - 1) % 2) @@ -1170,13 +994,13 @@ void LyXText::setCurrentFont(LCursor & cur) } BufferParams const & bufparams = bv()->buffer()->params(); - current_font = pit->getFontSettings(bufparams, pos); + current_font = pars_[pit].getFontSettings(bufparams, pos); real_current_font = getFont(pit, pos); if (cur.pos() == cur.lastpos() - && bidi.isBoundary(*bv()->buffer(), *pit, cur.pos()) + && bidi.isBoundary(*bv()->buffer(), pars_[pit], cur.pos()) && !cur.boundary()) { - Language const * lang = pit->getParLanguage(bufparams); + Language const * lang = pars_[pit].getParLanguage(bufparams); current_font.setLanguage(lang); current_font.setNumber(LyXFont::OFF); real_current_font.setLanguage(lang); @@ -1188,7 +1012,7 @@ void LyXText::setCurrentFont(LCursor & cur) // x is an absolute screen coord // returns the column near the specified x-coordinate of the row // x is set to the real beginning of this column -pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, +pos_type LyXText::getColumnNearX(par_type pit, Row const & row, int & x, bool & boundary) const { x -= xo_; @@ -1197,17 +1021,17 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, pos_type vc = row.pos(); pos_type end = row.endpos(); pos_type c = 0; - LyXLayout_ptr const & layout = pit->layout(); + LyXLayout_ptr const & layout = pars_[pit].layout(); bool left_side = false; - pos_type body_pos = pit->beginOfBody(); + pos_type body_pos = pars_[pit].beginOfBody(); double tmpx = r.x; double last_tmpx = tmpx; if (body_pos > 0 && - (body_pos > end || !pit->isLineSeparator(body_pos - 1))) + (body_pos > end || !pars_[pit].isLineSeparator(body_pos - 1))) body_pos = 0; // check for empty row @@ -1222,17 +1046,17 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, if (body_pos > 0 && c == body_pos - 1) { tmpx += r.label_hfill + font_metrics::width(layout->labelsep, getLabelFont(pit)); - if (pit->isLineSeparator(body_pos - 1)) + if (pars_[pit].isLineSeparator(body_pos - 1)) tmpx -= singleWidth(pit, body_pos - 1); } - if (hfillExpansion(*pit, row, c)) { + if (hfillExpansion(pars_[pit], row, c)) { tmpx += singleWidth(pit, c); if (c >= body_pos) tmpx += r.hfill; else tmpx += r.label_hfill; - } else if (pit->isSeparator(c)) { + } else if (pars_[pit].isSeparator(c)) { tmpx += singleWidth(pit, c); if (c >= body_pos) tmpx += r.separator; @@ -1252,11 +1076,11 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, boundary = false; // This (rtl_support test) is not needed, but gives // some speedup if rtl_support == false - bool const lastrow = lyxrc.rtl_support && row.endpos() == pit->size(); + bool const lastrow = lyxrc.rtl_support && row.endpos() == pars_[pit].size(); // If lastrow is false, we don't need to compute // the value of rtl. - bool const rtl = lastrow ? isRTL(*pit) : false; + bool const rtl = lastrow ? isRTL(pars_[pit]) : false; if (lastrow && ((rtl && left_side && vc == row.pos() && x < tmpx - 5) || (!rtl && !left_side && vc == end && x > tmpx + 5))) @@ -1270,11 +1094,11 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, bool const rtl = (bidi.level(c) % 2 == 1); if (left_side == rtl) { ++c; - boundary = bidi.isBoundary(*bv()->buffer(), *pit, c); + boundary = bidi.isBoundary(*bv()->buffer(), pars_[pit], c); } } - if (row.pos() < end && c >= end && pit->isNewline(end - 1)) { + if (row.pos() < end && c >= end && pars_[pit].isNewline(end - 1)) { if (bidi.level(end -1) % 2 == 0) tmpx -= singleWidth(pit, end - 1); else @@ -1292,27 +1116,26 @@ void LyXText::setCursorFromCoordinates(LCursor & cur, int x, int y) { x -= xo_; y -= yo_; - CursorSlice old_cursor = cur.top(); - ParagraphList::iterator pit; + par_type pit; Row const & row = *getRowNearY(y, pit); - lyxerr << "hit row at: " << row.pos() << endl; + lyxerr << "setCursorFromCoordinates:: hit row at: " << row.pos() << endl; bool bound = false; int xx = x + xo_; // getRowNearX get absolute x coords pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound); - setCursor(cur, parOffset(pit), pos, true, bound); + setCursor(cur, pit, pos, true, bound); } // x,y are absolute screen coordinates InsetBase * LyXText::editXY(LCursor & cur, int x, int y) { - ParagraphList::iterator pit; + par_type pit; Row const & row = *getRowNearY(y - yo_, pit); bool bound = false; int xx = x; // is modified by getColumnNearX pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound); - cur.par() = parOffset(pit); + cur.par() = pit; cur.pos() = pos; cur.boundary() = bound; @@ -1323,11 +1146,11 @@ InsetBase * LyXText::editXY(LCursor & cur, int x, int y) // This should be just before or just behind the // cursor position set above. - BOOST_ASSERT((pos != 0 && inset == pit->getInset(pos - 1)) - || inset == pit->getInset(pos)); + BOOST_ASSERT((pos != 0 && inset == pars_[pit].getInset(pos - 1)) + || inset == pars_[pit].getInset(pos)); // Make sure the cursor points to the position before // this inset. - if (inset == pit->getInset(pos - 1)) + if (inset == pars_[pit].getInset(pos - 1)) --cur.pos(); return inset->editXY(cur, x, y); } @@ -1362,7 +1185,7 @@ void LyXText::cursorLeft(LCursor & cur) if (cur.par() != 0) { // steps into the paragraph above - setCursor(cur, cur.par() - 1, getPar(cur.par() - 1)->size()); + setCursor(cur, cur.par() - 1, getPar(cur.par() - 1).size()); } } @@ -1457,20 +1280,18 @@ void LyXText::fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where) } -bool LyXText::deleteEmptyParagraphMechanism(CursorSlice & cur, - CursorSlice const & old_cursor) +bool LyXText::deleteEmptyParagraphMechanism(LCursor & cur, LCursor const & old) { -#warning Disabled as it crashes after the cursor data shift... (Andre) - return false; - + BOOST_ASSERT(cur.size() == old.size()); // Would be wrong to delete anything if we have a selection. - //if (cur.selection()) - // return false; + if (cur.selection()) + return false; + + //lyxerr << "DEPM: cur:\n" << cur << "old:\n" << old << endl; + Paragraph const & oldpar = pars_[old.par()]; -#if 0 // We allow all kinds of "mumbo-jumbo" when freespacing. - ParagraphList::iterator const old_pit = getPar(old_cursor.par()); - if (old_pit->isFreeSpacing()) + if (oldpar.isFreeSpacing()) return false; /* Ok I'll put some comments here about what is missing. @@ -1488,104 +1309,95 @@ bool LyXText::deleteEmptyParagraphMechanism(CursorSlice & cur, that I can get some feedback. (Lgb) */ - // If old_cursor.pos() == 0 and old_cursor.pos()(1) == LineSeparator + // If old.pos() == 0 and old.pos()(1) == LineSeparator // delete the LineSeparator. // MISSING - // If old_cursor.pos() == 1 and old_cursor.pos()(0) == LineSeparator + // If old.pos() == 1 and old.pos()(0) == LineSeparator // delete the LineSeparator. // MISSING - // If the pos around the old_cursor were spaces, delete one of them. - if (old_cursor.par() != cur.par() || old_cursor.pos() != cur.pos()) { + // If the chars around the old cursor were spaces, delete one of them. + if (old.par() != cur.par() || old.pos() != cur.pos()) { - // Only if the cursor has really moved - if (old_cursor.pos() > 0 - && old_cursor.pos() < old_pit->size() - && old_pit->isLineSeparator(old_cursor.pos()) - && old_pit->isLineSeparator(old_cursor.pos() - 1)) { - bool erased = old_pit->erase(old_cursor.pos() - 1); - redoParagraph(old_pit); - - if (!erased) - return false; + // Only if the cursor has really moved. + if (old.pos() > 0 + && old.pos() < oldpar.size() + && oldpar.isLineSeparator(old.pos()) + && oldpar.isLineSeparator(old.pos() - 1)) { + pars_[old.par()].erase(old.pos() - 1); #ifdef WITH_WARNINGS #warning This will not work anymore when we have multiple views of the same buffer // In this case, we will have to correct also the cursors held by // other bufferviews. It will probably be easier to do that in a more // automated way in CursorSlice code. (JMarc 26/09/2001) #endif - // correct all cursors held by the LyXText - fixCursorAfterDelete(cursor(), old_cursor); - fixCursorAfterDelete(anchor(), old_cursor); + // correct all cursor parts + fixCursorAfterDelete(cur.top(), old.top()); + fixCursorAfterDelete(cur.anchor(), old.top()); return false; } } + // only do our magic if we changed paragraph + if (old.par() == cur.par()) + return false; + // don't delete anything if this is the ONLY paragraph! - if (paragraphs().size() == 1) + if (pars_.size() == 1) return false; // Do not delete empty paragraphs with keepempty set. - if (old_pit->allowEmpty()) - return false; - - // only do our magic if we changed paragraph - if (old_cursor.par() == cur.par()) + if (oldpar.allowEmpty()) return false; // record if we have deleted a paragraph // we can't possibly have deleted a paragraph before this point bool deleted = false; - if (old_pit->empty() - || (old_pit->size() == 1 && old_pit->isLineSeparator(0))) { + if (oldpar.empty() || (oldpar.size() == 1 && oldpar.isLineSeparator(0))) { // ok, we will delete something CursorSlice tmpcursor; deleted = true; bool selection_position_was_oldcursor_position = - anchor().par() == old_cursor.par() - && anchor().pos() == old_cursor.pos(); + cur.anchor().par() == old.par() && cur.anchor().pos() == old.pos(); - tmpcursor = cursor(); - cursor() = old_cursor; // that undo can restore the right cursor position + // This is a bit of a overkill. We change the old and the cur par + // at max, certainly not everything in between... + recUndo(old.par(), cur.par()); - ParagraphList::iterator endpit = boost::next(old_pit); - while (endpit != paragraphs().end() && endpit->getDepth()) - ++endpit; + // Delete old par. + pars_.erase(pars_.begin() + old.par()); - recUndo(parOffset(old_pit), parOffset(endpit) - 1); - cursor() = tmpcursor; - - // delete old par - paragraphs().erase(old_pit); - // update cursor par offset - --cur.par(); - redoParagraph(); + // Update cursor par offset if necessary. + // Some 'iterator registration' would be nice that takes care of + // such events. Maybe even signal/slot? + if (cur.par() > old.par()) + --cur.par(); + if (cur.anchor().par() > old.par()) + --cur.anchor().par(); if (selection_position_was_oldcursor_position) { // correct selection - bv()->resetAnchor(); + cur.resetAnchor(); } } if (deleted) return true; - if (old_pit->stripLeadingSpaces()) { - redoParagraph(old_pit); - bv()->resetAnchor(); - } + if (pars_[old.par()].stripLeadingSpaces()) + cur.resetAnchor(); + return false; -#endif } ParagraphList & LyXText::paragraphs() const { - return const_cast(paragraphs_); + return const_cast(pars_); } diff --git a/src/text3.C b/src/text3.C index a277437185..00f48fcc04 100644 --- a/src/text3.C +++ b/src/text3.C @@ -23,6 +23,7 @@ #include "bufferparams.h" #include "BufferView.h" #include "cursor.h" +#include "CutAndPaste.h" #include "debug.h" #include "dispatchresult.h" #include "factory.h" @@ -62,6 +63,11 @@ using lyx::pos_type; +using lyx::cap::copySelection; +using lyx::cap::cutSelection; +using lyx::cap::pasteSelection; +using lyx::cap::replaceSelection; + using lyx::support::isStrUnsignedInt; using lyx::support::strToUnsignedInt; using lyx::support::atoi; @@ -124,8 +130,7 @@ namespace { } - void mathDispatch(LCursor & cur, LyXText * text, - FuncRequest const & cmd, bool display) + void mathDispatch(LCursor & cur, FuncRequest const & cmd, bool display) { recordUndo(cur); string sel = cur.selectionAsString(false); @@ -144,7 +149,7 @@ namespace { } else { // create a macro if we see "\\newcommand" somewhere, and an ordinary // formula otherwise - text->cutSelection(cur, true, true); + cutSelection(cur, true, true); if (sel.find("\\newcommand") == string::npos && sel.find("\\def") == string::npos) { @@ -180,23 +185,22 @@ string const freefont2string() //takes absolute x,y coordinates InsetBase * LyXText::checkInsetHit(int x, int y) { - ParagraphList::iterator pit; - ParagraphList::iterator end; + par_type pit; + par_type end; getParsInRange(paragraphs(), bv()->top_y() - yo_, bv()->top_y() - yo_ + bv()->workHeight(), pit, end); - lyxerr << "checkInsetHit: x: " << x << " y: " << y << endl; + //lyxerr << "checkInsetHit: x: " << x << " y: " << y << endl; for ( ; pit != end; ++pit) { - InsetList::iterator iit = pit->insetlist.begin(); - InsetList::iterator iend = pit->insetlist.end(); + InsetList::iterator iit = pars_[pit].insetlist.begin(); + InsetList::iterator iend = pars_[pit].insetlist.end(); for ( ; iit != iend; ++iit) { InsetBase * inset = iit->inset; -#if 1 +#if 0 lyxerr << "examining inset " << inset - //<< " xo/yo: " << inset->xo() << "/" << inset->yo() << " xo: " << inset->xo() << "..." << inset->xo() + inset->width() << " yo: " << inset->yo() - inset->ascent() << "..." << inset->yo() + inset->descent() << endl; @@ -207,7 +211,7 @@ InsetBase * LyXText::checkInsetHit(int x, int y) } } } - lyxerr << "No inset hit. " << endl; + //lyxerr << "No inset hit. " << endl; return 0; } @@ -216,13 +220,13 @@ bool LyXText::gotoNextInset(LCursor & cur, vector const & codes, string const & contents) { BOOST_ASSERT(this == cur.text()); - ParagraphList::iterator end = paragraphs().end(); - ParagraphList::iterator pit = getPar(cur.par()); + par_type end = paragraphs().size(); + par_type pit = cur.par(); pos_type pos = cur.pos(); InsetBase * inset; do { - if (pos + 1 < pit->size()) { + if (pos + 1 < pars_[pit].size()) { ++pos; } else { ++pit; @@ -230,17 +234,17 @@ bool LyXText::gotoNextInset(LCursor & cur, } } while (pit != end && - !(pit->isInset(pos) && - (inset = pit->getInset(pos)) != 0 && + !(pars_[pit].isInset(pos) && + (inset = pars_[pit].getInset(pos)) != 0 && find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end() && (contents.empty() || - static_cast(pit->getInset(pos))->getContents() + static_cast(pars_[pit].getInset(pos))->getContents() == contents))); if (pit == end) return false; - setCursor(cur, parOffset(pit), pos, false); + setCursor(cur, pit, pos, false); return true; } @@ -273,7 +277,6 @@ void LyXText::gotoInset(LCursor & cur, cur.message(_("No more insets")); } } - cur.update(); cur.resetAnchor(); } @@ -287,7 +290,7 @@ void LyXText::gotoInset(LCursor & cur, InsetOld_code code, bool same_content) void LyXText::cursorPrevious(LCursor & cur) { pos_type cpos = cur.pos(); - lyx::paroffset_type cpar = cur.par(); + lyx::par_type cpar = cur.par(); int x = cur.x_target(); int y = bv()->top_y(); @@ -307,7 +310,7 @@ void LyXText::cursorPrevious(LCursor & cur) void LyXText::cursorNext(LCursor & cur) { pos_type cpos = cur.pos(); - lyx::paroffset_type cpar = cur.par(); + lyx::par_type cpar = cur.par(); int x = cur.x_target(); int y = bv()->top_y() + bv()->workHeight(); @@ -326,11 +329,10 @@ void LyXText::cursorNext(LCursor & cur) namespace { -void specialChar(LCursor & cur, LyXText * text, InsetSpecialChar::Kind kind) +void specialChar(LCursor & cur, InsetSpecialChar::Kind kind) { - text->replaceSelection(cur); + lyx::cap::replaceSelection(cur); cur.insert(new InsetSpecialChar(kind)); - cur.update(); } @@ -387,13 +389,10 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) bool start = !par.params().startOfAppendix(); // ensure that we have only one start_of_appendix in this document - ParagraphList::iterator tmp = paragraphs().begin(); - ParagraphList::iterator end = paragraphs().end(); - - for (; tmp != end; ++tmp) { - if (tmp->params().startOfAppendix()) { - recUndo(parOffset(tmp)); - tmp->params().startOfAppendix(false); + for (par_type tmp = 0, end = pars_.size(); tmp != end; ++tmp) { + if (pars_[tmp].params().startOfAppendix()) { + recUndo(tmp); + pars_[tmp].params().startOfAppendix(false); redoParagraph(tmp); break; } @@ -405,7 +404,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) // we can set the refreshing parameters now updateCounters(); redoParagraph(cur); - cur.update(); break; } @@ -463,40 +461,52 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_RIGHT: case LFUN_RIGHTSEL: + //lyxerr << "handle LFUN_RIGHT[SEL]:\n" << cur << endl; cur.selHandle(cmd.action == LFUN_RIGHTSEL); if (isRTL(cur.paragraph())) cursorLeft(cur); else cursorRight(cur); - if (sl == cur.top()) + if (sl == cur.top()) { + cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_RIGHT); + } break; case LFUN_LEFT: case LFUN_LEFTSEL: + //lyxerr << "handle LFUN_LEFT[SEL]:\n" << cur << endl; cur.selHandle(cmd.action == LFUN_LEFTSEL); if (isRTL(cur.paragraph())) cursorRight(cur); else cursorLeft(cur); - if (sl == cur.top()) + if (sl == cur.top()) { + cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_LEFT); + } break; case LFUN_UP: case LFUN_UPSEL: + //lyxerr << "handle LFUN_UP[SEL]:\n" << cur << endl; cur.selHandle(cmd.action == LFUN_UPSEL); cursorUp(cur); - if (sl == cur.top()) + if (sl == cur.top()) { + cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_UP); + } break; case LFUN_DOWN: case LFUN_DOWNSEL: + //lyxerr << "handle LFUN_DOWN[SEL]:\n" << cur << endl; cur.selHandle(cmd.action == LFUN_DOWNSEL); cursorDown(cur); - if (sl == cur.top()) + if (sl == cur.top()) { + cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_DOWN); + } break; case LFUN_UP_PARAGRAPHSEL: @@ -585,10 +595,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) if (!cur.mark()) cur.clearSelection(); finishChange(cur, false); - if (cur.par() == 0 && cur.textRow().pos() == 0) + if (cur.par() == 0 && cur.textRow().pos() == 0) { + cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_UP); - else + } else { cursorPrevious(cur); + } break; case LFUN_NEXT: @@ -596,10 +608,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.clearSelection(); finishChange(cur, false); if (cur.par() == cur.lastpar() - && cur.textRow().endpos() == cur.lastpos()) + && cur.textRow().endpos() == cur.lastpos()) { + cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_DOWN); - else + } else { cursorNext(cur); + } break; case LFUN_HOME: @@ -619,7 +633,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_BREAKLINE: { // Not allowed by LaTeX (labels or empty par) if (cur.pos() > cur.paragraph().beginOfBody()) { - replaceSelection(cur); + lyx::cap::replaceSelection(cur); cur.insert(new InsetNewline); moveCursor(cur, false); } @@ -650,7 +664,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } else { cutSelection(cur, true, false); } - cur.update(); break; @@ -666,7 +679,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cutSelection(cur, true, false); } bv->switchKeyMap(); - cur.update(); break; case LFUN_BACKSPACE_SKIP: @@ -679,41 +691,31 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } else { cutSelection(cur, true, false); } - cur.update(); break; case LFUN_BREAKPARAGRAPH: - replaceSelection(cur); + lyx::cap::replaceSelection(cur); breakParagraph(cur, 0); - cur.update(); cur.resetAnchor(); bv->switchKeyMap(); break; case LFUN_BREAKPARAGRAPHKEEPLAYOUT: - replaceSelection(cur); + lyx::cap::replaceSelection(cur); breakParagraph(cur, 1); - cur.update(); cur.resetAnchor(); bv->switchKeyMap(); break; case LFUN_BREAKPARAGRAPH_SKIP: { // When at the beginning of a paragraph, remove - // indentation and add a "defskip" at the top. - // Otherwise, do the same as LFUN_BREAKPARAGRAPH. - replaceSelection(cur); - if (cur.pos() == 0) { - ParagraphParameters & params = cur.paragraph().params(); - setParagraph(cur, - params.spacing(), - params.align(), - params.labelWidthString(), 1); - } else { + // indentation. Otherwise, do the same as LFUN_BREAKPARAGRAPH. + lyx::cap::replaceSelection(cur); + if (cur.pos() == 0) + cur.paragraph().params().labelWidthString(string()); + else breakParagraph(cur, 0); - } - cur.update(); -// anchor() = cur; + cur.resetAnchor(); bv->switchKeyMap(); break; } @@ -755,7 +757,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) if (cur_spacing != new_spacing || cur_value != new_value) { par.params().spacing(Spacing(new_spacing, new_value)); redoParagraph(cur); - cur.update(); } break; } @@ -803,56 +804,51 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) break; case LFUN_HYPHENATION: - specialChar(cur, this, InsetSpecialChar::HYPHENATION); + specialChar(cur, InsetSpecialChar::HYPHENATION); break; case LFUN_LIGATURE_BREAK: - specialChar(cur, this, InsetSpecialChar::LIGATURE_BREAK); + specialChar(cur, InsetSpecialChar::LIGATURE_BREAK); break; case LFUN_LDOTS: - specialChar(cur, this, InsetSpecialChar::LDOTS); + specialChar(cur, InsetSpecialChar::LDOTS); break; case LFUN_END_OF_SENTENCE: - specialChar(cur, this, InsetSpecialChar::END_OF_SENTENCE); + specialChar(cur, InsetSpecialChar::END_OF_SENTENCE); break; case LFUN_MENU_SEPARATOR: - specialChar(cur, this, InsetSpecialChar::MENU_SEPARATOR); + specialChar(cur, InsetSpecialChar::MENU_SEPARATOR); break; case LFUN_UPCASE_WORD: changeCase(cur, LyXText::text_uppercase); - cur.update(); break; case LFUN_LOWCASE_WORD: changeCase(cur, LyXText::text_lowercase); - cur.update(); break; case LFUN_CAPITALIZE_WORD: changeCase(cur, LyXText::text_capitalization); - cur.update(); break; case LFUN_TRANSPOSE_CHARS: recordUndo(cur); redoParagraph(cur); - cur.update(); break; case LFUN_PASTE: cur.message(_("Paste")); - replaceSelection(cur); + lyx::cap::replaceSelection(cur); #warning FIXME Check if the arg is in the domain of available selections. if (isStrUnsignedInt(cmd.argument)) pasteSelection(cur, strToUnsignedInt(cmd.argument)); else pasteSelection(cur, 0); cur.clearSelection(); // bug 393 - cur.update(); bv->switchKeyMap(); finishUndo(); break; @@ -860,7 +856,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_CUT: cutSelection(cur, true, true); cur.message(_("Cut")); - cur.update(); break; case LFUN_COPY: @@ -937,10 +932,10 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) if (!change_layout && cur.selection() && cur.selBegin().par() != cur.selEnd().par()) { - ParagraphList::iterator spit = getPar(cur.selBegin()); - ParagraphList::iterator epit = boost::next(getPar(cur.selEnd())); + par_type spit = cur.selBegin().par(); + par_type epit = cur.selEnd().par() + 1; while (spit != epit) { - if (spit->layout()->name() != current_layout) { + if (pars_[spit].layout()->name() != current_layout) { change_layout = true; break; } @@ -952,7 +947,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) current_layout = layout; setLayout(cur, layout); bv->owner()->setLayout(layout); - cur.update(); bv->switchKeyMap(); } break; @@ -966,7 +960,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) insertStringAsParagraphs(cur, clip); else insertStringAsLines(cur, clip); - cur.update(); } break; } @@ -988,7 +981,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } case LFUN_QUOTE: { - replaceSelection(cur); + lyx::cap::replaceSelection(cur); Paragraph & par = cur.paragraph(); lyx::pos_type pos = cur.pos(); char c; @@ -1022,7 +1015,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } case LFUN_DATE_INSERT: { - replaceSelection(cur); + lyx::cap::replaceSelection(cur); time_t now_time_t = time(NULL); struct tm * now_tm = localtime(&now_time_t); setlocale(LC_TIME, ""); @@ -1066,12 +1059,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) // Only use motion with button 1 //if (cmd.button() != mouse_button::button1) // return false; - // The test for not selection possible is needed, that - // only motion events are used, where the bottom press - // event was on the drawing area too + // We want to use only motion events for which + // the button press event was on the drawing area too. if (!selection_possible) { lyxerr[Debug::ACTION] << "BufferView::Pimpl::" - "Dispatch: no selection possible\n"; + "dispatch: no selection possible\n"; + lyxerr << "BufferView::Pimpl::dispatch: no selection possible\n"; break; } CursorSlice old = cur.top(); @@ -1087,14 +1080,15 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } // don't set anchor_ - bv->cursor().setCursor(cur, false); + bv->cursor().setCursor(cur, true); + lyxerr << "MOTION: " << bv->cursor() << endl; break; } // Single-click on work area case LFUN_MOUSE_PRESS: { // ok ok, this is a hack (for xforms) - // We shouldn't go further down as we really should only do the + // We shouldn't go further down as we really need to. Only do the // scrolling and be done with this. Otherwise we may open some // dialogs (Jug 20020424). if (cmd.button() == mouse_button::button4) { @@ -1134,9 +1128,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) finishUndo(); cur.x_target() = cursorX(cur.top()); - // set cursor and anchor to this position - bv->cursor() = cur; - if (bv->fitCursor()) selection_possible = false; @@ -1273,21 +1264,19 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_DEPTH_MIN: changeDepth(cur, DEC_DEPTH); - cur.update(); break; case LFUN_DEPTH_PLUS: changeDepth(cur, INC_DEPTH); - cur.update(); break; case LFUN_MATH_DISPLAY: - mathDispatch(cur, this, cmd, true); + mathDispatch(cur, cmd, true); break; case LFUN_MATH_IMPORT_SELECTION: case LFUN_MATH_MODE: - mathDispatch(cur, this, cmd, false); + mathDispatch(cur, cmd, false); break; case LFUN_MATH_MACRO: @@ -1407,29 +1396,22 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } case LFUN_FINISHED_LEFT: - lyxerr << "handle LFUN_FINISHED_LEFT" << endl; - if (isRTL(cur.paragraph())) - cursorLeft(cur); - cur.bv().cursor() = cur; + lyxerr << "handle LFUN_FINISHED_LEFT:\n" << cur << endl; break; case LFUN_FINISHED_RIGHT: - lyxerr << "handle LFUN_FINISHED_RIGHT" << endl; - if (!isRTL(cur.paragraph())) - cursorRight(cur); - cur.bv().cursor() = cur; + lyxerr << "handle LFUN_FINISHED_RIGHT:\n" << cur << endl; + ++cur.pos(); break; case LFUN_FINISHED_UP: - lyxerr << "handle LFUN_FINISHED_UP" << endl; + lyxerr << "handle LFUN_FINISHED_UP:\n" << cur << endl; cursorUp(cur); - cur.bv().cursor() = cur; break; case LFUN_FINISHED_DOWN: - lyxerr << "handle LFUN_FINISHED_DOWN" << endl; + lyxerr << "handle LFUN_FINISHED_DOWN:\n" << cur << endl; cursorDown(cur); - cur.bv().cursor() = cur; break; case LFUN_LAYOUT_PARAGRAPH: { @@ -1503,13 +1485,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_ACCEPT_CHANGE: { acceptChange(cur); - cur.update(); break; } case LFUN_REJECT_CHANGE: { rejectChange(cur); - cur.update(); break; } @@ -1542,7 +1522,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) params.align(), params.labelWidthString(), params.noindent()); - cur.update(); cur.message(_("Paragraph layout set")); break; } @@ -1557,10 +1536,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } case LFUN_ESCAPE: - if (cur.selection()) + if (cur.selection()) { cur.selection() = false; - else + } else { + cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_LEFT); + } break; default: diff --git a/src/toc.C b/src/toc.C index f9080e0143..65bcc5673b 100644 --- a/src/toc.C +++ b/src/toc.C @@ -75,7 +75,7 @@ TocList const getTocList(Buffer const & buf) for (; pit != end; ++pit) { int const toclevel = pit->layout()->toclevel; - if (toclevel > 0 && toclevel <= bufparams.tocdepth) { + if (toclevel > 0 && toclevel <= bufparams.tocdepth) { // insert this into the table of contents TocItem const item(pit->id(), toclevel - 1, pit->asString(buf, true)); toclist["TOC"].push_back(item); @@ -87,14 +87,11 @@ TocList const getTocList(Buffer const & buf) InsetList::const_iterator end = pit->insetlist.end(); for (; it != end; ++it) { if (it->inset->lyxCode() == InsetOld::FLOAT_CODE) { - InsetFloat * il = - static_cast(it->inset); - il->addToToc(toclist, buf); + static_cast(it->inset) + ->addToToc(toclist, buf); } else if (it->inset->lyxCode() == InsetOld::WRAP_CODE) { - InsetWrap * il = - static_cast(it->inset); - - il->addToToc(toclist, buf); + static_cast(it->inset) + ->addToToc(toclist, buf); } } } diff --git a/src/undo.C b/src/undo.C index b3e3334d37..2388542327 100644 --- a/src/undo.C +++ b/src/undo.C @@ -27,7 +27,7 @@ #include -using lyx::paroffset_type; +using lyx::par_type; namespace { @@ -45,7 +45,7 @@ std::ostream & operator<<(std::ostream & os, Undo const & undo) void recordUndo(Undo::undo_kind kind, - LCursor & cur, paroffset_type first_par, paroffset_type last_par, + LCursor & cur, par_type first_par, par_type last_par, limited_stack & stack) { BOOST_ASSERT(first_par <= cur.lastpar()); @@ -200,14 +200,14 @@ bool textRedo(BufferView & bv) void recordUndo(Undo::undo_kind kind, - LCursor & cur, paroffset_type first, paroffset_type last) + LCursor & cur, par_type first, par_type last) { Buffer * buf = cur.bv().buffer(); recordUndo(kind, cur, first, last, buf->undostack()); buf->redostack().clear(); - lyxerr << "undostack:\n"; - for (size_t i = 0, n = buf->undostack().size(); i != n && i < 6; ++i) - lyxerr << " " << i << ": " << buf->undostack()[i] << std::endl; + //lyxerr << "undostack:\n"; + //for (size_t i = 0, n = buf->undostack().size(); i != n && i < 6; ++i) + // lyxerr << " " << i << ": " << buf->undostack()[i] << std::endl; } @@ -223,14 +223,14 @@ void recordUndoSelection(LCursor & cur, Undo::undo_kind kind) } -void recordUndo(LCursor & cur, Undo::undo_kind kind, paroffset_type from) +void recordUndo(LCursor & cur, Undo::undo_kind kind, par_type from) { recordUndo(kind, cur, cur.par(), from); } void recordUndo(LCursor & cur, Undo::undo_kind kind, - paroffset_type from, paroffset_type to) + par_type from, par_type to) { recordUndo(kind, cur, from, to); } diff --git a/src/undo.h b/src/undo.h index 6c3dcdd59a..3759ae067c 100644 --- a/src/undo.h +++ b/src/undo.h @@ -17,7 +17,7 @@ #define UNDO_H #include "dociterator.h" -#include "ParagraphList_fwd.h" +#include "ParagraphList_fwd.h" #include "support/types.h" @@ -54,9 +54,9 @@ struct Undo { /// the position of the cursor StableDocumentIterator cursor; /// counted from begin of buffer - lyx::paroffset_type from; + lyx::par_type from; /// complement to end of this cell - lyx::paroffset_type end; + lyx::par_type end; /// the contents of the saved paragraphs (for texted) ParagraphList pars; /// the contents of the saved matharray (for mathed) @@ -83,10 +83,10 @@ void finishUndo(); /// the common case: prepare undo for an arbitrary range void recordUndo(LCursor & cur, Undo::undo_kind kind, - lyx::paroffset_type from, lyx::paroffset_type to); + lyx::par_type from, lyx::par_type to); /// convienience: prepare undo for the range between 'from' and cursor. -void recordUndo(LCursor & cur, Undo::undo_kind kind, lyx::paroffset_type from); +void recordUndo(LCursor & cur, Undo::undo_kind kind, lyx::par_type from); /// convienience: prepare undo for the single paragraph containing the cursor void recordUndo(LCursor & cur, Undo::undo_kind kind = Undo::ATOMIC);