]> git.lyx.org Git - features.git/commitdiff
add PosIterator
authorAlfredo Braunstein <abraunst@lyx.org>
Sun, 2 Nov 2003 17:56:26 +0000 (17:56 +0000)
committerAlfredo Braunstein <abraunst@lyx.org>
Sun, 2 Nov 2003 17:56:26 +0000 (17:56 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8014 a592a061-630c-0410-9148-cb99ea01b6c8

src/ChangeLog
src/Makefile.am
src/PosIterator.C [new file with mode: 0644]
src/PosIterator.h [new file with mode: 0644]
src/buffer.C
src/buffer.h
src/iterators.C
src/iterators.h

index 43aed57ff6abcb97e128847da27589ddc91beb97..67c99bcb15729f009c3589371ea558269e46a7c4 100644 (file)
@@ -1,3 +1,10 @@
+
+2003-11-02  Alfredo Braunstein  <abraunst@libero.it>
+
+       * iterators.[Ch] (asPosIterator): added
+       * buffer.[Ch] (pos_iterator_begin, pos_iterator_end): added
+       * PosIterator.[Ch]: added
+
 2003-11-01  Lars Gullik Bjønnes  <larsbj@gullik.net>
 
        * text3.C:
index bae5416a49e71781651d3097045c9c60c5290bb6..25ff4213c9286e492ec677220a5cf311849ded69 100644 (file)
@@ -228,6 +228,8 @@ lyx_SOURCES = \
        paragraph.h \
        paragraph_pimpl.C \
        paragraph_pimpl.h \
+       PosIterator.h \
+       PosIterator.C \
        SpellBase.h \
        ispell.C \
        ispell.h \
diff --git a/src/PosIterator.C b/src/PosIterator.C
new file mode 100644 (file)
index 0000000..f89ef75
--- /dev/null
@@ -0,0 +1,149 @@
+/* \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 <config.h>
+
+#include "PosIterator.h"
+
+#include "buffer.h"
+#include "BufferView.h"
+#include "iterators.h"
+#include "lyxtext.h"
+#include "paragraph.h"
+
+#include "insets/insettext.h"
+#include "insets/updatableinset.h"
+#include "insets/inset.h"
+
+#include <boost/next_prior.hpp>
+
+using boost::prior;
+
+PosIterator & PosIterator::operator++()
+{
+       BOOST_ASSERT(!stack_.empty());
+       while (true) {
+               PosIteratorItem & p = stack_.top();
+               
+               if (p.pos < p.pit->size()) {
+                       InsetOld * inset = p.pit->getInset(p.pos);
+                       if (inset) {
+                               ParagraphList * pl = inset->getParagraphs(p.index);
+                               if (pl) {
+                                       p.index++;
+                                       stack_.push(PosIteratorItem(pl));
+                                       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();
+       }
+       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_.top();
+       if (p.pos > 0) {
+               --p.pos;
+               InsetOld * inset = p.pit->getInset(p.pos);
+               if (inset)
+                       p.index = inset->numParagraphs();
+       } else {
+               if (p.pit == p.pl->begin()) {
+                       if (stack_.size() == 1)
+                               return *this;
+                       stack_.pop();
+                       --stack_.top().index;
+               } else {
+                       --p.pit;
+                       p.pos = p.pit->size();
+               }
+       }
+       // try to push an item if there is some left unexplored
+       PosIteratorItem & q = stack_.top();
+       if (q.pos < q.pit->size()) {
+               InsetOld * inset = q.pit->getInset(q.pos);
+               if (inset && q.index > 0) {
+                       ParagraphList *
+                               pl = inset->getParagraphs(q.index - 1);
+                       BOOST_ASSERT(pl);
+                       stack_.push(PosIteratorItem(pl, prior(pl->end()), pl->back().size()));
+               }
+       }
+       return *this;
+}
+
+
+bool operator!=(PosIterator const & lhs, PosIterator const & rhs)
+{
+       return !(lhs == rhs);
+}
+
+
+bool operator==(PosIterator const & lhs, PosIterator const & rhs)
+{
+       
+       PosIteratorItem const & li = lhs.stack_.top();
+       PosIteratorItem const & ri = rhs.stack_.top();
+       
+       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();
+}
+
+
+PosIterator::PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
+                        lyx::pos_type pos)
+{
+       stack_.push(PosIteratorItem(pl, pit, pos));
+}
+
+
+PosIterator::PosIterator(ParagraphList * pl)
+{
+       stack_.push(PosIteratorItem(pl, pl->begin(), 0));
+}
+
+
+PosIterator::PosIterator(BufferView & bv)
+{
+       LyXText * text = bv.getLyXText();
+       lyx::pos_type pos = text->cursor.pos();
+       ParagraphList::iterator pit = text->cursorPar();
+       
+       ParIterator par = bv.buffer()->par_iterator_begin();
+       ParIterator end = bv.buffer()->par_iterator_end();
+       for ( ; par != end; ++par) {
+               if (par.pit() == pit)
+                       break;
+       }
+
+       operator=(par.asPosIterator(pos));
+}
diff --git a/src/PosIterator.h b/src/PosIterator.h
new file mode 100644 (file)
index 0000000..2fb5e47
--- /dev/null
@@ -0,0 +1,68 @@
+// -*- 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 <stack>
+
+
+class BufferView;
+
+struct PosIteratorItem 
+{
+       PosIteratorItem(ParagraphList * pl): pl(pl), pit(pl->begin()),
+                                            pos(0), index(0) {};
+       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:
+       PosIterator(BufferView & bv);
+       PosIterator(ParIterator & par, lyx::pos_type pos);
+       PosIterator(ParagraphList * pl);
+       PosIterator(ParagraphList * pl, ParagraphList::iterator pit,
+                   lyx::pos_type pos);
+       PosIterator(ParIterator const & parit, lyx::pos_type p);
+       PosIterator & operator++();
+       PosIterator & operator--();
+       friend bool operator==(PosIterator const &, PosIterator const &);
+
+       ParagraphList::iterator pit() const { return stack_.top().pit; }
+       lyx::pos_type pos() const { return stack_.top().pos; }
+       bool at_end() const;
+       friend PosIterator ParIterator::asPosIterator(lyx::pos_type) const;
+       
+private:
+       PosIterator() {};
+       std::stack<PosIteratorItem> stack_;
+};
+
+bool operator!=(PosIterator const &, PosIterator const &);
+
+
+#endif
+
index 7f8d0b033faa87f84be29141f2049b384b1e4917..81d1ee2887bb096a3ab30e80e9bb52e2c3973545 100644 (file)
@@ -36,6 +36,7 @@
 #include "paragraph.h"
 #include "paragraph_funcs.h"
 #include "ParagraphParameters.h"
+#include "PosIterator.h"
 #include "sgml.h"
 #include "texrow.h"
 #include "undo.h"
@@ -1472,6 +1473,18 @@ bool Buffer::hasParWithID(int id) const
 }
 
 
+PosIterator Buffer::pos_iterator_begin()
+{
+       return PosIterator(&paragraphs(), paragraphs().begin(), 0);     
+}
+
+
+PosIterator Buffer::pos_iterator_end()
+{
+       return PosIterator(&paragraphs(), paragraphs().end(), 0);       
+}
+
+
 ParIterator Buffer::par_iterator_begin()
 {
        return ParIterator(paragraphs().begin(), paragraphs());
index 9637b9d059fe44c1a3f9ca9c8ebf0de452032d7c..12fb74ea92051be2cabc877f94bb028739e38d2a 100644 (file)
@@ -40,6 +40,7 @@ class LatexRunParams;
 class Language;
 class Messages;
 class ParIterator;
+class PosIterator;
 class ParConstIterator;
 class TeXErrors;
 class TexRow;
@@ -345,6 +346,10 @@ 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();
        ///
index 817e72587b5a5f02953fcdb1a75191c063ee8cf3..acbe21237c7090aa349a9fb4cc8651a7be8628a8 100644 (file)
 
 #include "iterators.h"
 #include "paragraph.h"
+#include "PosIterator.h"
 #include "cursor.h"
 
+
 #include "insets/inset.h"
 
 #include <boost/next_prior.hpp>
@@ -356,3 +358,19 @@ bool operator!=(ParConstIterator const & iter1, ParConstIterator const & iter2)
 {
        return !(iter1 == iter2);
 }
+
+
+PosIterator ParIterator::asPosIterator(lyx::pos_type pos) const
+{
+       PosIterator p;
+       
+       int const last = size() - 1;
+       for (int i = 0; i < last; ++i) {
+               ParPosition & pp = pimpl_->positions[i];
+               p.stack_.push(PosIteratorItem(const_cast<ParagraphList *>(pp.plist), pp.pit, (*pp.it)->pos, *pp.index + 1));
+       }
+       ParPosition const & pp = pimpl_->positions[last];
+       p.stack_.push(PosIteratorItem(const_cast<ParagraphList *>(pp.plist),
+                                     pp.pit, pos, 0));
+       return p;
+}
index cad565e8583db4c901c4f899a26d74afb965ffd3..88711f667b4b433859cc2de4afe1d4a34f121310 100644 (file)
 #define ITERATORS_H
 
 #include "ParagraphList_fwd.h"
+#include "support/types.h"
 
 #include <boost/scoped_ptr.hpp>
 
 class LyXText;
 class InsetOld;
 class Cursor;
+class PosIterator;
+
 
 class ParIterator {
 public:
@@ -56,6 +59,9 @@ public:
        ///
        friend
        bool operator==(ParIterator const & iter1, ParIterator const & iter2);
+
+       ///
+       PosIterator asPosIterator(lyx::pos_type) const;
 private:
        struct Pimpl;
        boost::scoped_ptr<Pimpl> pimpl_;
@@ -93,6 +99,7 @@ public:
        friend
        bool operator==(ParConstIterator const & iter1,
                        ParConstIterator const & iter2);
+
 private:
        struct Pimpl;
        boost::scoped_ptr<Pimpl> pimpl_;