10 #include "lyx_gui_misc.h"
11 #include "support/textutils.h"
12 #include "support/lstrings.h"
13 #include "BufferView.h"
17 int LyXReplace(BufferView * bv,
18 string const & searchstr,
19 string const & replacestr,
20 bool const & casesens,
21 bool const & matchwrd,
23 bool const & replaceall)
25 int replace_count = 0;
27 if (!bv->available() || bv->buffer()->isReadonly())
30 // CutSelection cannot cut a single space, so we have to stop
31 // in order to avoid endless loop :-(
32 if (searchstr.length() == 0
33 || (searchstr.length() == 1 && searchstr[0] == ' ')) {
34 WriteAlert(_("Sorry!"), _("You cannot replace a single space, "
35 "nor an empty character."));
38 // now we can start searching for the first
39 // start at top if replaceall
42 bv->text->clearSelection(bv);
43 bv->text->cursorTop(bv);
44 // override search direction because we search top to bottom
48 // if nothing selected or selection does not equal search string
49 // search and select next occurance and return if no replaceall
50 if (searchstr!=bv->text->selectionAsString(bv->buffer())) {
51 LyXFind(bv, searchstr, casesens, matchwrd, fw);
59 bv->update(bv->text, BufferView::SELECT|BufferView::FITCUR);
60 bv->toggleSelection(false);
61 bv->text->replaceSelectionWithString(bv, replacestr);
62 bv->text->setSelectionOverString(bv, replacestr);
63 bv->update(bv->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
65 found = LyXFind(bv, searchstr, casesens, matchwrd, fw);
66 } while (replaceall && found);
74 bool LyXFind(BufferView * bv,
75 string const & searchstr,
76 bool const & casesens,
77 bool const & matchwrd,
82 if (!bv->available() || searchstr.empty())
86 bv->update(bv->text, BufferView::SELECT|BufferView::FITCUR);
88 LyXText * ltCur = bv->text;
89 if (ltCur->selection.set())
90 ltCur->cursor = forward ? ltCur->selection.end
91 : ltCur->selection.start;
94 ? SearchForward(bv, searchstr, casesens, matchwrd)
95 : SearchBackward(bv, searchstr, casesens, matchwrd)) {
96 bv->update(bv->text, BufferView::SELECT|BufferView::FITCUR);
97 bv->toggleSelection();
98 bv->text->clearSelection(bv);
99 bv->text->setSelectionOverString(bv, searchstr);
100 bv->toggleSelection(false);
111 // returns true if the specified string is at the specified position
112 bool IsStringInText(Paragraph * par, Paragraph::size_type pos,
113 string const & str, bool const & cs,
119 string::size_type size = str.length();
120 Paragraph::size_type i = 0;
121 while (((pos + i) < par->size())
122 && (string::size_type(i) < size)
123 && (cs ? (str[i] == par->getChar(pos + i))
124 : (toupper(str[i]) == toupper(par->getChar(pos + i)))))
128 if (size == string::size_type(i)) {
129 // if necessary, check whether string matches word
131 (mw && ((pos <= 0 || !IsLetterCharOrDigit(par->getChar(pos - 1)))
132 && (pos + Paragraph::size_type(size) >= par->size()
133 || !IsLetterCharOrDigit(par->getChar(pos + size))))
141 // if the string can be found: return true and set the cursor to
142 // the new position, cs = casesensitive, mw = matchword
143 bool SearchForward(BufferView * bv, string const & str,
144 bool const & cs, bool const & mw)
146 Paragraph * par = bv->text->cursor.par();
147 Paragraph::size_type pos = bv->text->cursor.pos();
149 while (par && !IsStringInText(par, pos, str, cs, mw)) {
150 if (pos < par->size() - 1)
158 bv->text->setCursor(bv, par, pos);
167 // if the string can be found: return true and set the cursor to
168 // the new position, cs = casesensitive, mw = matchword
169 bool SearchBackward(BufferView * bv, string const & str,
170 bool const & cs, bool const & mw)
172 Paragraph * par = bv->text->cursor.par();
173 Paragraph::size_type pos = bv->text->cursor.pos();
179 // We skip empty paragraphs (Asger)
181 par = par->previous();
183 pos = par->size() - 1;
184 } while (par && pos < 0);
186 } while (par && !IsStringInText(par, pos, str, cs, mw));
189 bv->text->setCursor(bv, par, pos);