From 0d43ba149a41e8860dde316ccbd4336d6b0bbdfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Thu, 25 Mar 2004 09:16:36 +0000 Subject: [PATCH] the stuff from the sneak preview: For one, it still contains a few things that are already in CVS (the 'brown paperbag' changes). Secondly, this changes the ParagraphList to a std::vector but does not yet take full advantage of it except removing LyXText::parOffset() and similar. I had an extensive talk with my profiler and we are happy nevertheless. This also moves almost all Cut&Paste specific stuff from text.C to CutAndPaste.C. Much smaller interface now... Namespace CutAndPaste is now lyx::cap::. Was inconsistent with the rest.... Make ParagraphList a proper class. We'll need this later for a specialized erase/insert. Remove some unneeded prototypes and function declarations Use ParameterStruct directly instead of ShareContainer Inline a few accesses to CursorSlice members as suggested by the profiler. Fix commandline conversion crash reported by Kayvan. Replace PosIterator by DocumentIterator. The latter can also iterate through math and nested text in math... Remove math specific hack from Documentiterator Derive InsetCollapsable from InsetText instead of using an InsetText member. This give us the opportunity to get rid of the InsetOld::owner_ backpointer. Cosmetics in CutAndPaste.C and cursor.C. Fix nasty crash (popping slices off an empty selection anchor). Add a few asserts. Remove all 'manual' update calls. We do now one per user interaction which is completely sufficient. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8527 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Bidi.C | 3 +- src/BufferView.C | 31 +- src/BufferView.h | 5 +- src/BufferView_pimpl.C | 148 ++-- src/ChangeLog | 80 ++ src/CutAndPaste.C | 486 +++++++---- src/CutAndPaste.h | 61 +- src/FontIterator.C | 14 +- src/FontIterator.h | 21 +- src/Makefile.am | 3 - src/MenuBackend.C | 8 +- src/ParagraphList_fwd.h | 19 +- src/ParagraphParameters.C | 110 ++- src/ParagraphParameters.h | 26 +- src/ParameterStruct.h | 73 -- src/PosIterator.C | 173 ---- src/PosIterator.h | 75 -- src/buffer.C | 99 +-- src/buffer.h | 34 +- src/bufferlist.C | 1 + src/cursor.C | 128 ++- src/cursor.h | 8 +- src/cursor_slice.C | 52 +- src/cursor_slice.h | 20 +- src/dociterator.C | 85 +- src/dociterator.h | 19 +- src/errorlist.C | 2 +- src/errorlist.h | 3 +- src/factory.C | 1 - src/frontends/controllers/ControlDocument.C | 2 +- src/frontends/controllers/ControlErrorList.C | 5 +- .../controllers/ControlSpellchecker.C | 66 +- src/insets/ChangeLog | 23 + src/insets/inset.C | 14 +- src/insets/inset.h | 6 - src/insets/insetbase.h | 7 - src/insets/insetbibitem.C | 1 + src/insets/insetbox.C | 13 +- src/insets/insetbranch.C | 12 +- src/insets/insetcaption.C | 9 + src/insets/insetcharstyle.C | 53 +- src/insets/insetcharstyle.h | 6 +- src/insets/insetcollapsable.C | 242 ++---- src/insets/insetcollapsable.h | 53 +- src/insets/insetert.C | 20 +- src/insets/insetfloat.C | 18 +- src/insets/insetfoot.C | 4 +- src/insets/insetmarginal.C | 4 +- src/insets/insetnote.C | 12 +- src/insets/insetoptarg.C | 2 +- src/insets/insettabular.C | 35 +- src/insets/insettext.C | 47 +- src/insets/insettext.h | 27 +- src/insets/insetwrap.C | 20 +- src/iterators.C | 78 +- src/iterators.h | 39 +- src/lfuns.h | 8 +- src/lyxfind.C | 393 +++++---- src/lyxfunc.C | 53 +- src/lyxtext.h | 124 +-- src/mathed/math_mboxinset.C | 3 +- src/mathed/math_nestinset.C | 40 +- src/mathed/math_scriptinset.C | 151 ++-- src/mathed/math_scriptinset.h | 11 +- src/output_docbook.C | 5 +- src/output_docbook.h | 4 +- src/output_latex.C | 6 +- src/output_latex.h | 3 +- src/output_linuxdoc.C | 4 +- src/output_linuxdoc.h | 3 +- src/output_plaintext.C | 6 +- src/output_plaintext.h | 8 +- src/paragraph.C | 42 +- src/paragraph.h | 4 +- src/paragraph_funcs.C | 438 ++-------- src/paragraph_funcs.h | 43 +- src/paragraph_pimpl.C | 3 - src/paragraph_pimpl.h | 2 + src/rowpainter.C | 157 ++-- src/support/types.h | 2 +- src/tabular.C | 15 +- src/tabular.h | 2 - src/text.C | 765 +++++++++++------- src/text2.C | 636 +++++---------- src/text3.C | 203 +++-- src/toc.C | 13 +- src/undo.C | 16 +- src/undo.h | 10 +- 88 files changed, 2545 insertions(+), 3234 deletions(-) delete mode 100644 src/ParameterStruct.h delete mode 100644 src/PosIterator.C delete mode 100644 src/PosIterator.h 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);