]> git.lyx.org Git - lyx.git/blobdiff - src/text_funcs.C
More 'standard conformant blurb' nonsense.
[lyx.git] / src / text_funcs.C
index 01f4d089dbe3a78f2e14b07ccecfc26c44a1e8d6..2656f53fe7bbc92aae31fd9d0541e536823a330c 100644 (file)
 
 #include <config.h>
 
-#include "lyxtext.h"
-#include "paragraph.h"
+#include "debug.h"
 #include "lyxcursor.h"
-#include "undo_funcs.h"
+#include "ParagraphList.h"
+
+#include "support/types.h"
+
+#include <boost/next_prior.hpp>
 
 using lyx::pos_type;
+using lyx::word_location;
 
-void transposeChars(LyXText & text, LyXCursor const & cursor)
-{
-       Paragraph * tmppar = &*cursor.par();
+using std::endl;
 
-       setUndo(text.bv(), Undo::FINISH, tmppar, tmppar->next());
 
+bool transposeChars(LyXCursor const & cursor)
+{
+       ParagraphList::iterator tmppit = cursor.par();
        pos_type tmppos = cursor.pos();
 
        // First decide if it is possible to transpose at all
 
-       if (tmppos == 0 || tmppos == tmppar->size())
-               return;
+       if (tmppos == 0 || tmppos == tmppit->size())
+               return false;
 
-       if (isDeletedText(*tmppar, tmppos - 1)
-               || isDeletedText(*tmppar, tmppos))
-               return;
+       if (isDeletedText(*tmppit, tmppos - 1)
+               || isDeletedText(*tmppit, tmppos))
+               return false;
 
-       unsigned char c1 = tmppar->getChar(tmppos);
-       unsigned char c2 = tmppar->getChar(tmppos - 1);
+       unsigned char c1 = tmppit->getChar(tmppos);
+       unsigned char c2 = tmppit->getChar(tmppos - 1);
 
        // We should have an implementation that handles insets
        // as well, but that will have to come later. (Lgb)
        if (c1 == Paragraph::META_INSET || c2 == Paragraph::META_INSET)
-               return;
+               return false;
+
+       bool const erased = tmppit->erase(tmppos - 1, tmppos + 1);
+       size_t const ipos = erased ? tmppos - 1 : tmppos + 1;
+
+       tmppit->insertChar(ipos, c1);
+       tmppit->insertChar(ipos + 1, c2);
+       return true;
+}
+
+
+void cursorLeftOneWord(LyXCursor & cursor, ParagraphList const & pars)
+{
+       // treat HFills, floats and Insets as words
+
+       ParagraphList::iterator pit = cursor.par();
+       size_t pos = cursor.pos();
+
+       while (pos &&
+              (pit->isSeparator(pos - 1) ||
+               pit->isKomma(pos - 1) ||
+               pit->isNewline(pos - 1)) &&
+              !(pit->isHfill(pos - 1) ||
+                pit->isInset(pos - 1)))
+               --pos;
 
-       bool const erased = tmppar->erase(tmppos - 1, tmppos + 1);
-       pos_type const ipos(erased ? tmppos - 1 : tmppos + 1);
+       if (pos &&
+           (pit->isInset(pos - 1) ||
+            pit->isHfill(pos - 1))) {
+               --pos;
+       } else if (!pos) {
+               // cast only for BSD's g++ 2.95
+               if (pit != const_cast<ParagraphList &>(pars).begin()) {
+                       --pit;
+                       pos = pit->size();
+               }
+       } else {                // Here, cur != 0
+               while (pos > 0 && pit->isWord(pos - 1))
+                       --pos;
+       }
 
-       tmppar->insertChar(ipos, c1);
-       tmppar->insertChar(ipos + 1, c2);
+       cursor.par(pit);
+       cursor.pos(pos);
+}
+
+
+void cursorRightOneWord(LyXCursor & cursor, ParagraphList const & pars)
+{
+       // treat floats, HFills and Insets as words
+       ParagraphList::iterator pit = cursor.par();
+       pos_type pos = cursor.pos();
+
+       // CHECK See comment on top of text.C
+
+       // cast only for BSD's g++ 2.95
+       if (pos == pit->size() &&
+               boost::next(pit) != const_cast<ParagraphList &>(pars).end()) {
+               ++pit;
+               pos = 0;
+       } else {
+               // Skip through initial nonword stuff.
+               while (pos < pit->size() && !pit->isWord(pos)) {
+                       ++pos;
+               }
+               // Advance through word.
+               while (pos < pit->size() && pit->isWord(pos)) {
+                       ++pos;
+               }
+       }
+
+       cursor.par(pit);
+       cursor.pos(pos);
+}
+
+
+// Select current word. This depends on behaviour of
+// CursorLeftOneWord(), so it is patched as well.
+void getWord(LyXCursor & from, LyXCursor & to, word_location const loc,
+       ParagraphList const & pars)
+{
+       switch (loc) {
+       case lyx::WHOLE_WORD_STRICT:
+               if (from.pos() == 0 || from.pos() == from.par()->size()
+                   || from.par()->isSeparator(from.pos())
+                   || from.par()->isKomma(from.pos())
+                   || from.par()->isNewline(from.pos())
+                   || from.par()->isSeparator(from.pos() - 1)
+                   || from.par()->isKomma(from.pos() - 1)
+                   || from.par()->isNewline(from.pos() - 1)) {
+                       to = from;
+                       return;
+               }
+               // no break here, we go to the next
 
-       text.checkParagraph(tmppar, tmppos);
+       case lyx::WHOLE_WORD:
+               // Move cursor to the beginning, when not already there.
+               if (from.pos() && !from.par()->isSeparator(from.pos() - 1)
+                   && !(from.par()->isKomma(from.pos() - 1)
+                        || from.par()->isNewline(from.pos() - 1)))
+                       cursorLeftOneWord(from, pars);
+               break;
+       case lyx::PREVIOUS_WORD:
+               // always move the cursor to the beginning of previous word
+               cursorLeftOneWord(from, pars);
+               break;
+       case lyx::NEXT_WORD:
+               lyxerr << "LyXText::getWord: NEXT_WORD not implemented yet"
+                      << endl;
+               break;
+       case lyx::PARTIAL_WORD:
+               break;
+       }
+       to = from;
+       while (to.pos() < to.par()->size()
+              && !to.par()->isSeparator(to.pos())
+              && !to.par()->isKomma(to.pos())
+              && !to.par()->isNewline(to.pos())
+              && !to.par()->isHfill(to.pos())
+              && !to.par()->isInset(to.pos()))
+       {
+               to.pos(to.pos() + 1);
+       }
 }