1 #include "StdAfx.h" 2 #include "FindReplaceForm.h" 3 #include "Document.h" 4 5 using namespace System; 6 using namespace System::Windows::Forms; 7 using namespace WeifenLuo::WinFormsUI::Docking; 8 9 namespace ContextFreeNet { 10 System::Void FindReplaceForm::findText_Changed(System::Object^ sender, System::EventArgs^ e) 11 { 12 bool canFind = findText->Text->Length > 0; 13 nextButton->Enabled = canFind; 14 prevButton->Enabled = canFind; 15 replaceButton->Enabled = canFind; 16 replaceAllButton->Enabled = canFind; 17 replaceAllSelectionButton->Enabled = canFind; 18 } 19 20 System::Void FindReplaceForm::find_Click(System::Object^ sender, System::EventArgs^ e) 21 { 22 ScintillaNET::Scintilla^ haystack = getRTB(); 23 if (findText->Text->Length == 0 || haystack == nullptr) { 24 System::Media::SystemSounds::Beep->Play(); 25 return; 26 } 27 28 doFind(haystack, true); 29 haystack->Focus(); 30 } 31 32 System::Void ContextFreeNet::FindReplaceForm::prev_Click(System::Object ^ sender, System::EventArgs ^ e) 33 { 34 ScintillaNET::Scintilla^ haystack = getRTB(); 35 if (findText->Text->Length == 0 || haystack == nullptr) { 36 System::Media::SystemSounds::Beep->Play(); 37 return; 38 } 39 40 doFind(haystack, false); 41 haystack->Focus(); 42 } 43 44 System::Void FindReplaceForm::replace_Click(System::Object^ sender, System::EventArgs^ e) 45 { 46 ScintillaNET::Scintilla^ haystack = getRTB(); 47 if (findText->Text->Length == 0 || haystack == nullptr) { 48 System::Media::SystemSounds::Beep->Play(); 49 return; 50 } 51 52 doReplace(haystack, false, false); 53 haystack->Focus(); 54 } 55 56 System::Void FindReplaceForm::replaceAll_Click(System::Object^ sender, System::EventArgs^ e) 57 { 58 ScintillaNET::Scintilla^ haystack = getRTB(); 59 if (findText->Text->Length == 0 || haystack == nullptr) { 60 System::Media::SystemSounds::Beep->Play(); 61 return; 62 } 63 64 doReplace(haystack, true, false); 65 haystack->Focus(); 66 } 67 68 System::Void FindReplaceForm::replaceAllSelection_Click(System::Object^ sender, System::EventArgs^ e) 69 { 70 ScintillaNET::Scintilla^ haystack = getRTB(); 71 if (findText->Text->Length == 0 || haystack == nullptr) { 72 System::Media::SystemSounds::Beep->Play(); 73 return; 74 } 75 76 doReplace(haystack, true, true); 77 haystack->Focus(); 78 } 79 80 bool FindReplaceForm::doFind(ScintillaNET::Scintilla^ haystack, bool forward) 81 { 82 bool found = false; 83 if (haystack == nullptr) return false; 84 85 bool up = !forward; 86 bool whole = findWhole->Checked; 87 bool start = findStarts->Checked; 88 bool ic = ignoreCaseCheck->Checked; 89 bool wrap = wrapAroundCheck->Checked; 90 auto finds = 91 (whole ? ScintillaNET::SearchFlags::WholeWord : ScintillaNET::SearchFlags::None) | 92 (start ? ScintillaNET::SearchFlags::WordStart : ScintillaNET::SearchFlags::None) | 93 (ic ? ScintillaNET::SearchFlags::None : ScintillaNET::SearchFlags::MatchCase); 94 95 if (up) { 96 haystack->TargetStart = haystack->AnchorPosition; 97 haystack->TargetEnd = 0; 98 } else { 99 haystack->TargetStart = haystack->CurrentPosition; 100 haystack->TargetEnd = haystack->TextLength; 101 } 102 haystack->SearchFlags = finds; 103 104 auto needle = haystack->SearchInTarget(findText->Text); 105 found = needle >= 0; 106 107 if (!found && wrap) { 108 if (up) { 109 haystack->TargetStart = haystack->TextLength; 110 haystack->TargetEnd = 0; 111 } else { 112 haystack->TargetStart = 0; 113 haystack->TargetEnd = haystack->TextLength; 114 } 115 needle = haystack->SearchInTarget(findText->Text); 116 found = needle >= 0; 117 } 118 119 if (found) { 120 haystack->SetSelection(haystack->TargetEnd, haystack->TargetStart); 121 haystack->ScrollCaret(); 122 } else { 123 notFoundSound->Play(); 124 } 125 126 notFound->Visible = !found; 127 128 return found; 129 } 130 131 void FindReplaceForm::doReplace(ScintillaNET::Scintilla^ rtb, bool all, bool selection) 132 { 133 ScintillaNET::Scintilla^ haystack = rtb; 134 135 bool whole = findWhole->Checked; 136 bool start = findStarts->Checked; 137 bool ic = ignoreCaseCheck->Checked; 138 bool wrap = wrapAroundCheck->Checked; 139 auto finds = 140 (whole ? ScintillaNET::SearchFlags::WholeWord : ScintillaNET::SearchFlags::None) | 141 (start ? ScintillaNET::SearchFlags::WordStart : ScintillaNET::SearchFlags::None) | 142 (ic ? ScintillaNET::SearchFlags::None : ScintillaNET::SearchFlags::MatchCase); 143 144 int startPosition = (all && !selection) ? 0 : haystack->CurrentPosition; 145 int endPosition = (all && selection) ? haystack->AnchorPosition : haystack->TextLength; 146 147 if (all && endPosition < startPosition) 148 std::swap(startPosition, endPosition); 149 if (all && endPosition == startPosition) 150 return; 151 152 haystack->SearchFlags = finds; 153 haystack->TargetStart = startPosition; 154 haystack->TargetEnd = endPosition; 155 156 if (all) { 157 bool replaced = false; 158 auto delta = replaceText->Text->Length - findText->Text->Length; 159 for (;;) { 160 auto needle = haystack->SearchInTarget(findText->Text); 161 if (needle < 0) break; 162 163 if (!replaced) 164 haystack->BeginUndoAction(); 165 replaced = true; 166 167 haystack->ReplaceTarget(replaceText->Text); 168 169 if (selection) 170 endPosition += delta; 171 else 172 endPosition = haystack->TextLength; 173 haystack->TargetStart = haystack->TargetEnd; 174 haystack->TargetEnd = endPosition; 175 } 176 notFound->Visible = !replaced; 177 if (replaced) 178 haystack->EndUndoAction(); 179 else 180 notFoundSound->Play(); 181 } else { 182 auto needle = haystack->SearchInTarget(findText->Text); 183 if (needle < 0 && wrap) { 184 haystack->TargetStart = 0; 185 haystack->TargetEnd = haystack->TextLength; 186 needle = haystack->SearchInTarget(findText->Text); 187 } 188 notFound->Visible = needle < 0; 189 if (needle >= 0) { 190 haystack->ReplaceTarget(replaceText->Text); 191 haystack->SetSelection(haystack->TargetEnd, haystack->TargetStart); 192 haystack->ScrollCaret(); 193 } else { 194 notFoundSound->Play(); 195 } 196 } 197 } 198 199 ScintillaNET::Scintilla^ FindReplaceForm::getRTB() 200 { 201 Document^ cfdg = dynamic_cast<Document^>(DockPanel->ActiveDocument); 202 return (cfdg != nullptr) ? cfdg->cfdgText : nullptr; 203 } 204 }