]> git.lyx.org Git - lyx.git/blobdiff - src/iterators.C
more cursor dispatch
[lyx.git] / src / iterators.C
index 817e72587b5a5f02953fcdb1a75191c063ee8cf3..befe0a971c9aec986842d3f604fef0b911f63a79 100644 (file)
 
 #include "iterators.h"
 #include "paragraph.h"
+#include "PosIterator.h"
 #include "cursor.h"
+#include "buffer.h"
+#include "BufferView.h"
+#include "dispatchresult.h"
 
 #include "insets/inset.h"
+#include "insets/updatableinset.h"
+#include "insets/insettext.h"
 
 #include <boost/next_prior.hpp>
-#include <boost/optional.hpp>
 
 using boost::next;
-using boost::optional;
-using std::vector;
 
 ///
 /// ParPosition
 ///
 
-class ParPosition {
-public:
-       ///
-       ParPosition(ParagraphList::iterator p, ParagraphList const & pl);
-       ///
-       ParagraphList::iterator pit;
-       ///
-       ParagraphList const * plist;
-       ///
-       optional<InsetList::iterator> it;
-       ///
-       optional<int> index;
-};
-
 
 ParPosition::ParPosition(ParagraphList::iterator p, ParagraphList const & pl)
        : pit(p), plist(&pl)
@@ -68,15 +57,9 @@ bool operator!=(ParPosition const & pos1, ParPosition const & pos2)
 /// ParIterator
 ///
 
-struct ParIterator::Pimpl {
-       typedef vector<ParPosition> PosHolder;
-       PosHolder positions;
-};
-
 ParIterator::ParIterator(ParagraphList::iterator pit, ParagraphList const & pl)
-       : pimpl_(new Pimpl)
 {
-       pimpl_->positions.push_back(ParPosition(pit, pl));
+       positions_.push_back(ParPosition(pit, pl));
 }
 
 
@@ -85,51 +68,56 @@ ParIterator::~ParIterator()
 
 
 ParIterator::ParIterator(ParIterator const & pi)
-       : pimpl_(new Pimpl(*pi.pimpl_))
+       : positions_(pi.positions_)
 {}
 
 
 void ParIterator::operator=(ParIterator const & pi)
 {
        ParIterator tmp(pi);
-       pimpl_.swap(tmp.pimpl_);
+       swap(positions_ , tmp.positions_);
 }
 
 
 ParIterator & ParIterator::operator++()
 {
-       while (!pimpl_->positions.empty()) {
-               ParPosition & p = pimpl_->positions.back();
+       while (!positions_.empty()) {
+               ParPosition & p = positions_.back();
 
                // Does the current inset contain more "cells" ?
                if (p.index) {
                        ++(*p.index);
-                       ParagraphList * plist = (*p.it)->inset->getParagraphs(*p.index);
-                       if (plist && !plist->empty()) {
-                               pimpl_->positions.push_back(ParPosition(plist->begin(), *plist));
-                               return *this;
+                       if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
+                               ParagraphList & plist = text->paragraphs();
+                               if (!plist.empty()) {
+                                       positions_.push_back(ParPosition(plist.begin(), plist));
+                                       return *this;
+                               }
                        }
                        ++(*p.it);
-               } else
+               } else {
                        // 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());
+               }
 
                // Try to find the next inset that contains paragraphs
                InsetList::iterator end = p.pit->insetlist.end();
                for (; *p.it != end; ++(*p.it)) {
-                       ParagraphList * plist = (*p.it)->inset->getParagraphs(0);
-                       if (plist && !plist->empty()) {
-                               p.index.reset(0);
-                               pimpl_->positions.push_back(ParPosition(plist->begin(), *plist));
-                               return *this;
+                       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));
+                                       return *this;
+                               }
                        }
                }
 
                // Try to go to the next paragarph
                if (next(p.pit) != const_cast<ParagraphList*>(p.plist)->end()
-                   || pimpl_->positions.size() == 1) {
+                   || positions_.size() == 1) {
                        ++p.pit;
                        p.index.reset();
                        p.it.reset();
@@ -138,98 +126,104 @@ ParIterator & ParIterator::operator++()
                }
 
                // Drop end and move up in the stack.
-               pimpl_->positions.pop_back();
+               positions_.pop_back();
        }
        return *this;
 }
 
 
-LyXText * ParIterator::text() const
+LyXText * ParIterator::text(Buffer & buf) const
 {
-       //lyxerr << "positions.size: " << pimpl_->positions.size() << std::endl;
-       if (pimpl_->positions.size() <= 1)
-               return 0;
+       //lyxerr << "positions.size: " << positions.size() << std::endl;
+       if (positions_.size() <= 1)
+               return &buf.text();
 
-       ParPosition const & pos = pimpl_->positions[pimpl_->positions.size() - 2];
+       ParPosition const & pos = positions_[positions_.size() - 2];
        return (*pos.it)->inset->getText(*pos.index);
 }
 
 
-InsetOld * ParIterator::inset() const
+InsetBase * ParIterator::inset() const
 {
-       //lyxerr << "positions.size: " << pimpl_->positions.size() << std::endl;
-       if (pimpl_->positions.size() <= 1)
+       //lyxerr << "positions.size: " << positions.size() << std::endl;
+       if (positions_.size() <= 1)
                return 0;
 
-       ParPosition const & pos = pimpl_->positions[pimpl_->positions.size() - 2];
+       ParPosition const & pos = positions_[positions_.size() - 2];
        return (*pos.it)->inset;
 }
 
 
 int ParIterator::index() const
 {
-       if (pimpl_->positions.size() <= 1)
+       if (positions_.size() <= 1)
                return 0;
 
-       return *(pimpl_->positions[pimpl_->positions.size() - 2].index);
-}
-
-
-void ParIterator::asCursor(Cursor & cursor) const
-{
-       cursor.data_.clear();
-       for (size_t i = 1, n = size(); i < n; ++i) {
-               ParPosition const & pos = pimpl_->positions[i - 1];
-               CursorItem item;
-               item.inset_ = (*pos.it)->inset;
-               item.idx_   = (*pos.index);
-               item.text_  = (*pos.it)->inset->getText(*pos.index);
-               item.par_   = 0;
-               item.pos_   = 0;
-               cursor.data_.push_back(item);
-       }
+       return *(positions_[positions_.size() - 2].index);
 }
 
 
 Paragraph & ParIterator::operator*() const
 {
-       return *pimpl_->positions.back().pit;
+       return *positions_.back().pit;
 }
 
 
 ParagraphList::iterator ParIterator::pit() const
 {
-       return pimpl_->positions.back().pit;
+       return positions_.back().pit;
 }
 
 
 ParagraphList::iterator ParIterator::operator->() const
 {
-       return pimpl_->positions.back().pit;
+       return positions_.back().pit;
 }
 
 
 ParagraphList::iterator ParIterator::outerPar() const
 {
-       return pimpl_->positions[0].pit;
+       return positions_[0].pit;
 }
 
 
 size_t ParIterator::size() const
 {
-       return pimpl_->positions.size();
+       return positions_.size();
 }
 
 
 ParagraphList & ParIterator::plist() const
 {
-       return *const_cast<ParagraphList*>(pimpl_->positions.back().plist);
+       return *const_cast<ParagraphList*>(positions_.back().plist);
+}
+
+
+ParIterator::ParIterator(PosIterator const & pos)
+{
+       int const size = pos.stack_.size();
+
+       for (int i = 0; i < size; ++i) {
+               PosIteratorItem const & it = pos.stack_[i];
+               ParPosition pp(it.pit, *it.pl);
+               if (i < size - 1) {
+                       InsetBase * inset = it.pit->getInset(it.pos);
+                       BOOST_ASSERT(inset);
+                       InsetList::iterator beg = it.pit->insetlist.begin();
+                       InsetList::iterator end = it.pit->insetlist.end();
+                       for ( ; beg != end && beg->inset != inset; ++beg)
+                               ;
+                       pp.it.reset(beg);
+                       pp.index.reset(it.index - 1);
+               }
+               positions_.push_back(pp);
+       }
 }
 
 
 bool operator==(ParIterator const & iter1, ParIterator const & iter2)
 {
-       return iter1.pimpl_->positions == iter2.pimpl_->positions;
+       return iter1.positions() == iter2.positions();
 }
 
 
@@ -244,17 +238,10 @@ bool operator!=(ParIterator const & iter1, ParIterator const & iter2)
 ///
 
 
-struct ParConstIterator::Pimpl {
-       typedef vector<ParPosition> PosHolder;
-       PosHolder positions;
-};
-
-
 ParConstIterator::ParConstIterator(ParagraphList::iterator pit,
                                   ParagraphList const & pl)
-       : pimpl_(new Pimpl)
 {
-       pimpl_->positions.push_back(ParPosition(pit, pl));
+       positions_.push_back(ParPosition(pit, pl));
 }
 
 
@@ -263,44 +250,49 @@ ParConstIterator::~ParConstIterator()
 
 
 ParConstIterator::ParConstIterator(ParConstIterator const & pi)
-       : pimpl_(new Pimpl(*pi.pimpl_))
+       : positions_(pi.positions_)
 {}
 
 
 ParConstIterator & ParConstIterator::operator++()
 {
-       while (!pimpl_->positions.empty()) {
-               ParPosition & p = pimpl_->positions.back();
+       while (!positions_.empty()) {
+               ParPosition & p = positions_.back();
 
                // Does the current inset contain more "cells" ?
                if (p.index) {
                        ++(*p.index);
-                       ParagraphList * plist = (*p.it)->inset->getParagraphs(*p.index);
-                       if (plist && !plist->empty()) {
-                               pimpl_->positions.push_back(ParPosition(plist->begin(), *plist));
-                               return *this;
+                       if (LyXText * text = (*p.it)->inset->getText(*p.index)) {
+                               ParagraphList & plist = text->paragraphs();
+                               if (!plist.empty()) {
+                                       positions_.push_back(ParPosition(plist.begin(), plist));
+                                       return *this;
+                               }
                        }
                        ++(*p.it);
-               } else
+               } else {
                        // 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());
+               }
 
                // Try to find the next inset that contains paragraphs
                InsetList::iterator end = p.pit->insetlist.end();
                for (; *p.it != end; ++(*p.it)) {
-                       ParagraphList * plist = (*p.it)->inset->getParagraphs(0);
-                       if (plist && !plist->empty()) {
-                               p.index.reset(0);
-                               pimpl_->positions.push_back(ParPosition(plist->begin(), *plist));
-                               return *this;
+                       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));
+                                       return *this;
+                               }
                        }
                }
 
                // Try to go to the next paragarph
                if (next(p.pit) != const_cast<ParagraphList*>(p.plist)->end()
-                   || pimpl_->positions.size() == 1) {
+                   || positions_.size() == 1) {
                        ++p.pit;
                        p.index.reset();
                        p.it.reset();
@@ -309,7 +301,7 @@ ParConstIterator & ParConstIterator::operator++()
                }
 
                // Drop end and move up in the stack.
-               pimpl_->positions.pop_back();
+               positions_.pop_back();
        }
 
        return *this;
@@ -318,37 +310,37 @@ ParConstIterator & ParConstIterator::operator++()
 
 Paragraph const & ParConstIterator::operator*() const
 {
-       return *pimpl_->positions.back().pit;
+       return *positions_.back().pit;
 }
 
 
 ParagraphList::const_iterator ParConstIterator::pit() const
 {
-       return pimpl_->positions.back().pit;
+       return positions_.back().pit;
 }
 
 
 ParagraphList::const_iterator ParConstIterator::operator->() const
 {
-       return pimpl_->positions.back().pit;
+       return positions_.back().pit;
 }
 
 
 ParagraphList const & ParConstIterator::plist() const
 {
-       return *pimpl_->positions.back().plist;
+       return *positions_.back().plist;
 }
 
 
 size_t ParConstIterator::size() const
 {
-       return pimpl_->positions.size();
+       return positions_.size();
 }
 
 
 bool operator==(ParConstIterator const & iter1, ParConstIterator const & iter2)
 {
-       return iter1.pimpl_->positions == iter2.pimpl_->positions;
+       return iter1.positions() == iter2.positions();
 }