3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
9 * Full author contact details are available in file CREDITS.
11 * This file contains some utility functions for actually mutating
12 * the text contents of a document
17 #include "text_funcs.h"
19 #include "lyxcursor.h"
21 #include "paragraph.h"
23 #include <boost/next_prior.hpp>
26 using lyx::word_location;
31 bool transposeChars(LyXText & text, LyXCursor const & cursor)
33 ParagraphList::iterator tmppit = text.cursorPar();
34 pos_type tmppos = cursor.pos();
36 // First decide if it is possible to transpose at all
38 if (tmppos == 0 || tmppos == tmppit->size())
41 if (isDeletedText(*tmppit, tmppos - 1)
42 || isDeletedText(*tmppit, tmppos))
45 unsigned char c1 = tmppit->getChar(tmppos);
46 unsigned char c2 = tmppit->getChar(tmppos - 1);
48 // We should have an implementation that handles insets
49 // as well, but that will have to come later. (Lgb)
50 if (c1 == Paragraph::META_INSET || c2 == Paragraph::META_INSET)
53 bool const erased = tmppit->erase(tmppos - 1, tmppos + 1);
54 size_t const ipos = erased ? tmppos - 1 : tmppos + 1;
56 tmppit->insertChar(ipos, c1);
57 tmppit->insertChar(ipos + 1, c2);
62 void cursorLeftOneWord(LyXText & text,
63 LyXCursor & cursor, ParagraphList const & pars)
65 // treat HFills, floats and Insets as words
67 ParagraphList::iterator pit = text.cursorPar();
68 size_t pos = cursor.pos();
71 (pit->isSeparator(pos - 1) ||
72 pit->isKomma(pos - 1) ||
73 pit->isNewline(pos - 1)) &&
74 !(pit->isHfill(pos - 1) ||
75 pit->isInset(pos - 1)))
79 (pit->isInset(pos - 1) ||
80 pit->isHfill(pos - 1))) {
83 // cast only for BSD's g++ 2.95
84 if (pit != const_cast<ParagraphList &>(pars).begin()) {
88 } else { // Here, cur != 0
89 while (pos > 0 && pit->isWord(pos - 1))
93 cursor.par(text.parOffset(pit));
98 void cursorRightOneWord(LyXText & text,
99 LyXCursor & cursor, ParagraphList const & pars)
101 // treat floats, HFills and Insets as words
102 ParagraphList::iterator pit = text.cursorPar();
103 pos_type pos = cursor.pos();
105 // CHECK See comment on top of text.C
107 // cast only for BSD's g++ 2.95
108 if (pos == pit->size() &&
109 boost::next(pit) != const_cast<ParagraphList &>(pars).end()) {
113 // Skip through initial nonword stuff.
114 while (pos < pit->size() && !pit->isWord(pos)) {
117 // Advance through word.
118 while (pos < pit->size() && pit->isWord(pos)) {
123 cursor.par(text.parOffset(pit));
128 // Select current word. This depends on behaviour of
129 // CursorLeftOneWord(), so it is patched as well.
130 void getWord(LyXText & text, LyXCursor & from, LyXCursor & to,
131 word_location const loc, ParagraphList const & pars)
133 ParagraphList::iterator from_par = text.getPar(from);
134 ParagraphList::iterator to_par = text.getPar(to);
136 case lyx::WHOLE_WORD_STRICT:
137 if (from.pos() == 0 || from.pos() == from_par->size()
138 || from_par->isSeparator(from.pos())
139 || from_par->isKomma(from.pos())
140 || from_par->isNewline(from.pos())
141 || from_par->isSeparator(from.pos() - 1)
142 || from_par->isKomma(from.pos() - 1)
143 || from_par->isNewline(from.pos() - 1)) {
147 // no break here, we go to the next
149 case lyx::WHOLE_WORD:
150 // Move cursor to the beginning, when not already there.
151 if (from.pos() && !from_par->isSeparator(from.pos() - 1)
152 && !(from_par->isKomma(from.pos() - 1)
153 || from_par->isNewline(from.pos() - 1)))
154 cursorLeftOneWord(text, from, pars);
156 case lyx::PREVIOUS_WORD:
157 // always move the cursor to the beginning of previous word
158 cursorLeftOneWord(text, from, pars);
161 lyxerr << "LyXText::getWord: NEXT_WORD not implemented yet"
164 case lyx::PARTIAL_WORD:
168 while (to.pos() < to_par->size()
169 && !to_par->isSeparator(to.pos())
170 && !to_par->isKomma(to.pos())
171 && !to_par->isNewline(to.pos())
172 && !to_par->isHfill(to.pos())
173 && !to_par->isInset(to.pos()))
175 to.pos(to.pos() + 1);