Add dumb special casing to DialogSearchReplace so that replacing '$' with 'str' with regular expressions enabled results in 'str' being appended once rather than 1000 times.

Originally committed to SVN as r6062.
This commit is contained in:
Thomas Goyne 2011-12-22 21:19:12 +00:00
parent 3ecc731ff3
commit 0201b8ea9b
2 changed files with 43 additions and 46 deletions

View file

@ -257,9 +257,11 @@ void SearchReplaceEngine::ReplaceNext(bool DoReplace) {
// Search for it
while (!found) {
Text = GetText(curLine,field);
if (DoReplace && LastWasFind) tempPos = pos;
else tempPos = pos+replaceLen;
Text = GetText(context->subsGrid->GetDialogue(curLine), field);
if (DoReplace && LastWasFind)
tempPos = pos;
else
tempPos = pos+replaceLen;
// RegExp
if (isReg) {
@ -347,55 +349,55 @@ void SearchReplaceEngine::ReplaceNext(bool DoReplace) {
/// @brief Replace all instances
void SearchReplaceEngine::ReplaceAll() {
wxString *Text;
int nrows = context->subsGrid->GetRows();
size_t count = 0;
int regFlags = wxRE_ADVANCED;
if (!matchCase) {
if (isReg) regFlags |= wxRE_ICASE;
//else LookFor.MakeLower();
}
bool replaced;
context->subsGrid->BeginBatch();
if (!matchCase)
regFlags |= wxRE_ICASE;
wxRegEx reg;
if (isReg)
reg.Compile(LookFor, regFlags);
// Selection
bool hasSelection = false;
wxArrayInt sels = context->subsGrid->GetSelection();
if (sels.Count() > 0) hasSelection = true;
bool inSel = false;
if (affect == 1) inSel = true;
std::set<AssDialogue*> sel = context->selectionController->GetSelectedSet();
bool hasSelection = !sel.empty();
bool inSel = affect == 1;
// Scan
for (int i=0;i<nrows;i++) {
// Check if row is selected
if (inSel && hasSelection && sels.Index(i) == wxNOT_FOUND) {
continue;
}
for (std::list<AssEntry*>::iterator it = context->ass->Line.begin(); it != context->ass->Line.end(); ++it) {
AssDialogue *diag = dynamic_cast<AssDialogue*>(*it);
if (!diag) continue;
// Prepare
replaced = false;
Text = GetText(i,field);
// Check if row is selected
if (inSel && hasSelection && !sel.count(diag))
continue;
wxString *Text = GetText(diag, field);
// Regular expressions
if (isReg) {
wxRegEx reg(LookFor,regFlags);
if (reg.IsValid()) {
size_t reps = reg.Replace(Text,ReplaceWith,1000);
if (reps > 0) replaced = true;
count += reps;
if (reg.Matches(*Text)) {
size_t start, len;
reg.GetMatch(&start, &len);
// A zero length match (such as '$') will always be replaced
// maxMatches times, which is almost certainly not what the user
// wanted, so limit it to one replacement in that situation
count += reg.Replace(Text, ReplaceWith, len > 0 ? 1000 : 1);
}
}
// Normal replace
else {
if (!Search.matchCase) {
wxString Left = "", Right = *Text;
int pos = 0;
Left.Alloc(Right.Len());
while (pos <= (int)(Right.Len() - LookFor.Len())) {
if (Right.Mid(pos, LookFor.Len()).CmpNoCase(LookFor) == 0) {
Left.Append(Right.Mid(0,pos)).Append(ReplaceWith);
bool replaced = false;
wxString Left, Right = *Text;
size_t pos = 0;
Left.reserve(Right.size());
while (pos + LookFor.size() <= Right.size()) {
if (Right.Mid(pos, LookFor.size()).CmpNoCase(LookFor) == 0) {
Left.Append(Right.Left(pos)).Append(ReplaceWith);
Right = Right.Mid(pos + LookFor.Len());
count++;
++count;
replaced = true;
pos = 0;
}
@ -407,11 +409,8 @@ void SearchReplaceEngine::ReplaceAll() {
*Text = Left + Right;
}
}
else {
if(Text->Contains(LookFor)) {
else if(Text->Contains(LookFor)) {
count += Text->Replace(LookFor, ReplaceWith);
replaced = true;
}
}
}
}
@ -423,7 +422,6 @@ void SearchReplaceEngine::ReplaceAll() {
else {
wxMessageBox(_("No matches found."));
}
context->subsGrid->EndBatch();
LastWasFind = false;
}
@ -462,8 +460,7 @@ void SearchReplaceEngine::OpenDialog (bool replace) {
hasReplace = replace;
}
wxString *SearchReplaceEngine::GetText(int n,int field) {
AssDialogue *cur = context->subsGrid->GetDialogue(n);
wxString *SearchReplaceEngine::GetText(AssDialogue *cur, int field) {
if (field == 0) return &cur->Text;
else if (field == 1) return &cur->Style;
else if (field == 2) return &cur->Actor;

View file

@ -101,7 +101,7 @@ class SearchReplaceEngine {
wxString ReplaceWith;
wxString *GetText(int n,int field);
wxString *GetText(AssDialogue *cur, int field);
public:
/// DOCME