]> git.lyx.org Git - lyx.git/blobdiff - src/text_funcs.C
ws changes only
[lyx.git] / src / text_funcs.C
index 74c8dfd0ef4ba679a444719a7a7f5f0d4d6ea15a..ea091d509f95625d8e84b1f4a2ba67924bc8627d 100644 (file)
  * \author Lars Gullik Bjønnes
  * \author John Levon
  *
- * Full author contact details are available in file CREDITS
+ * Full author contact details are available in file CREDITS.
  *
  * This file contains some utility functions for actually mutating
- * the text contents of a document 
+ * the text contents of a document
  */
 
 #include <config.h>
 
+#include "text_funcs.h"
+#include "debug.h"
+#include "lyxcursor.h"
 #include "lyxtext.h"
 #include "paragraph.h"
-#include "lyxcursor.h"
-#include "undo_funcs.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(LyXText & text, LyXCursor const & cursor)
+{
+       ParagraphList::iterator tmppit = text.cursorPar();
        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(LyXText & text,
+       LyXCursor & cursor, ParagraphList const & pars)
+{
+       // treat HFills, floats and Insets as words
+
+       ParagraphList::iterator pit = text.cursorPar();
+       size_t pos = cursor.pos();
 
-       bool const erased = tmppar->erase(tmppos - 1, tmppos + 1);
-       pos_type const ipos(erased ? tmppos - 1 : tmppos + 1);
+       while (pos &&
+              (pit->isSeparator(pos - 1) ||
+               pit->isKomma(pos - 1) ||
+               pit->isNewline(pos - 1)) &&
+              !(pit->isHfill(pos - 1) ||
+                pit->isInset(pos - 1)))
+               --pos;
 
-       tmppar->insertChar(ipos, c1);
-       tmppar->insertChar(ipos + 1, c2);
+       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;
+       }
+
+       cursor.par(text.parOffset(pit));
+       cursor.pos(pos);
+}
+
+
+void cursorRightOneWord(LyXText & text,
+       LyXCursor & cursor, ParagraphList const & pars)
+{
+       // treat floats, HFills and Insets as words
+       ParagraphList::iterator pit = text.cursorPar();
+       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(text.parOffset(pit));
+       cursor.pos(pos);
+}
+
+
+// Select current word. This depends on behaviour of
+// CursorLeftOneWord(), so it is patched as well.
+void getWord(LyXText & text, LyXCursor & from, LyXCursor & to,
+       word_location const loc, ParagraphList const & pars)
+{
+       ParagraphList::iterator from_par = text.getPar(from);
+       ParagraphList::iterator to_par = text.getPar(to);
+       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(text, from, pars);
+               break;
+       case lyx::PREVIOUS_WORD:
+               // always move the cursor to the beginning of previous word
+               cursorLeftOneWord(text, 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);
+       }
 }