]> git.lyx.org Git - lyx.git/blob - src/text_funcs.C
Small clean-up.
[lyx.git] / src / text_funcs.C
1 /**
2  * \file text_funcs.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author John Levon
8  *
9  * Full author contact details are available in file CREDITS.
10  *
11  * This file contains some utility functions for actually mutating
12  * the text contents of a document
13  */
14
15 #include <config.h>
16
17 #include "text_funcs.h"
18 #include "debug.h"
19 #include "lyxcursor.h"
20 #include "paragraph.h"
21
22 #include <boost/next_prior.hpp>
23
24 using lyx::pos_type;
25 using lyx::word_location;
26
27 using std::endl;
28
29
30 bool transposeChars(LyXCursor const & cursor)
31 {
32         ParagraphList::iterator tmppit = cursor.par();
33         pos_type tmppos = cursor.pos();
34
35         // First decide if it is possible to transpose at all
36
37         if (tmppos == 0 || tmppos == tmppit->size())
38                 return false;
39
40         if (isDeletedText(*tmppit, tmppos - 1)
41                 || isDeletedText(*tmppit, tmppos))
42                 return false;
43
44         unsigned char c1 = tmppit->getChar(tmppos);
45         unsigned char c2 = tmppit->getChar(tmppos - 1);
46
47         // We should have an implementation that handles insets
48         // as well, but that will have to come later. (Lgb)
49         if (c1 == Paragraph::META_INSET || c2 == Paragraph::META_INSET)
50                 return false;
51
52         bool const erased = tmppit->erase(tmppos - 1, tmppos + 1);
53         size_t const ipos = erased ? tmppos - 1 : tmppos + 1;
54
55         tmppit->insertChar(ipos, c1);
56         tmppit->insertChar(ipos + 1, c2);
57         return true;
58 }
59
60
61 void cursorLeftOneWord(LyXCursor & cursor, ParagraphList const & pars)
62 {
63         // treat HFills, floats and Insets as words
64
65         ParagraphList::iterator pit = cursor.par();
66         size_t pos = cursor.pos();
67
68         while (pos &&
69                (pit->isSeparator(pos - 1) ||
70                 pit->isKomma(pos - 1) ||
71                 pit->isNewline(pos - 1)) &&
72                !(pit->isHfill(pos - 1) ||
73                  pit->isInset(pos - 1)))
74                 --pos;
75
76         if (pos &&
77             (pit->isInset(pos - 1) ||
78              pit->isHfill(pos - 1))) {
79                 --pos;
80         } else if (!pos) {
81                 // cast only for BSD's g++ 2.95
82                 if (pit != const_cast<ParagraphList &>(pars).begin()) {
83                         --pit;
84                         pos = pit->size();
85                 }
86         } else {                // Here, cur != 0
87                 while (pos > 0 && pit->isWord(pos - 1))
88                         --pos;
89         }
90
91         cursor.par(pit);
92         cursor.pos(pos);
93 }
94
95
96 void cursorRightOneWord(LyXCursor & cursor, ParagraphList const & pars)
97 {
98         // treat floats, HFills and Insets as words
99         ParagraphList::iterator pit = cursor.par();
100         pos_type pos = cursor.pos();
101
102         // CHECK See comment on top of text.C
103
104         // cast only for BSD's g++ 2.95
105         if (pos == pit->size() &&
106                 boost::next(pit) != const_cast<ParagraphList &>(pars).end()) {
107                 ++pit;
108                 pos = 0;
109         } else {
110                 // Skip through initial nonword stuff.
111                 while (pos < pit->size() && !pit->isWord(pos)) {
112                         ++pos;
113                 }
114                 // Advance through word.
115                 while (pos < pit->size() && pit->isWord(pos)) {
116                         ++pos;
117                 }
118         }
119
120         cursor.par(pit);
121         cursor.pos(pos);
122 }
123
124
125 // Select current word. This depends on behaviour of
126 // CursorLeftOneWord(), so it is patched as well.
127 void getWord(LyXCursor & from, LyXCursor & to, word_location const loc,
128         ParagraphList const & pars)
129 {
130         switch (loc) {
131         case lyx::WHOLE_WORD_STRICT:
132                 if (from.pos() == 0 || from.pos() == from.par()->size()
133                     || from.par()->isSeparator(from.pos())
134                     || from.par()->isKomma(from.pos())
135                     || from.par()->isNewline(from.pos())
136                     || from.par()->isSeparator(from.pos() - 1)
137                     || from.par()->isKomma(from.pos() - 1)
138                     || from.par()->isNewline(from.pos() - 1)) {
139                         to = from;
140                         return;
141                 }
142                 // no break here, we go to the next
143
144         case lyx::WHOLE_WORD:
145                 // Move cursor to the beginning, when not already there.
146                 if (from.pos() && !from.par()->isSeparator(from.pos() - 1)
147                     && !(from.par()->isKomma(from.pos() - 1)
148                          || from.par()->isNewline(from.pos() - 1)))
149                         cursorLeftOneWord(from, pars);
150                 break;
151         case lyx::PREVIOUS_WORD:
152                 // always move the cursor to the beginning of previous word
153                 cursorLeftOneWord(from, pars);
154                 break;
155         case lyx::NEXT_WORD:
156                 lyxerr << "LyXText::getWord: NEXT_WORD not implemented yet"
157                        << endl;
158                 break;
159         case lyx::PARTIAL_WORD:
160                 break;
161         }
162         to = from;
163         while (to.pos() < to.par()->size()
164                && !to.par()->isSeparator(to.pos())
165                && !to.par()->isKomma(to.pos())
166                && !to.par()->isNewline(to.pos())
167                && !to.par()->isHfill(to.pos())
168                && !to.par()->isInset(to.pos()))
169         {
170                 to.pos(to.pos() + 1);
171         }
172 }