10 #include "minibuffer.h"
11 #include "lyx_gui_misc.h"
12 #include "support/textutils.h"
13 #include "support/lstrings.h"
14 #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=false)
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;
90 ltCur->cursor = forward ? ltCur->sel_end_cursor
91 : ltCur->sel_start_cursor;
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(LyXParagraph * par, LyXParagraph::size_type pos,
113 string const & str, bool const & cs = true,
114 bool const & mw = false)
119 string::size_type size = str.length();
120 LyXParagraph::size_type i = 0;
121 while (((pos + i) < par->Last())
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 + size >= par->Last()
133 || !IsLetterCharOrDigit(par->GetChar(pos + size))))
142 // if the string can be found: return true and set the cursor to
143 // the new position, cs = casesensitive, mw = matchword
144 bool SearchForward(BufferView * bv, string const & str,
145 bool const & cs = true, bool const & mw = false)
147 LyXParagraph * par = bv->text->cursor.par();
148 LyXParagraph::size_type pos = bv->text->cursor.pos();
150 while (par && !IsStringInText(par, pos, str, cs, mw)) {
151 if (pos < par->Last() - 1)
159 bv->text->SetCursor(bv, par, pos);
168 // if the string can be found: return true and set the cursor to
169 // the new position, cs = casesensitive, mw = matchword
170 bool SearchBackward(BufferView * bv, string const & str,
171 bool const & cs = true, bool const & mw = false)
173 LyXParagraph * par = bv->text->cursor.par();
174 LyXParagraph::size_type pos = bv->text->cursor.pos();
180 // We skip empty paragraphs (Asger)
182 par = par->Previous();
184 pos = par->Last() - 1;
185 } while (par && pos < 0);
187 } while (par && !IsStringInText(par, pos, str, cs, mw));
190 bv->text->SetCursor(bv, par, pos);