23 #include "katesearchbar.moc"
33 #include <ktexteditor/movingcursor.h>
34 #include <ktexteditor/movingrange.h>
36 #include "ui_searchbarincremental.h"
37 #include "ui_searchbarpower.h"
39 #include <kcolorscheme.h>
40 #include <kmessagebox.h>
41 #include <kstandardaction.h>
43 #include <QtGui/QVBoxLayout>
44 #include <QtGui/QComboBox>
45 #include <QtGui/QCheckBox>
46 #include <QtGui/QShortcut>
51 #ifdef FAST_DEBUG_ENABLE
52 # define FAST_DEBUG(x) kDebug() << x
54 # define FAST_DEBUG(x)
57 using namespace KTextEditor;
61 class AddMenuManager {
71 AddMenuManager(
QMenu * parent,
int expectedItemCount)
76 Q_ASSERT(parent != NULL);
81 m_menu->
setIcon(KIcon(
"list-add"));
84 void enableMenu(
bool enabled) {
88 m_menu->setEnabled(enabled);
97 QAction *
const action = m_menu->addAction(before + after +
'\t' + description);
98 m_insertBefore[m_indexWalker] =
QString(realBefore.isEmpty() ? before : realBefore);
99 m_insertAfter[m_indexWalker] =
QString(realAfter.isEmpty() ? after : realAfter);
101 m_actionPointers.insert(action);
104 void addSeparator() {
105 if (m_menu == NULL) {
108 m_menu->addSeparator();
112 if (!m_actionPointers.contains(action)) {
118 const QString & before = m_insertBefore[index];
119 const QString & after = m_insertAfter[index];
120 lineEdit->
insert(before + after);
137 m_incInitCursor(view->cursorPosition()),
139 highlightMatchAttribute (new Attribute()),
140 highlightReplacementAttribute (new Attribute()),
141 m_incHighlightAll(false),
142 m_incFromCursor(true),
143 m_incMatchCase(false),
144 m_powerMatchCase(true),
145 m_powerFromCursor(false),
146 m_powerHighlightAll(false),
148 m_unitTestMode(false)
151 connect(view, SIGNAL(cursorPositionChanged(KTextEditor::View*,KTextEditor::Cursor)),
152 this, SLOT(updateIncInitCursor()));
155 Attribute::Ptr mouseInAttribute(
new Attribute());
156 mouseInAttribute->setFontBold(
true);
157 highlightMatchAttribute->setDynamicAttribute (Attribute::ActivateMouseIn, mouseInAttribute);
159 Attribute::Ptr caretInAttribute(
new Attribute());
160 caretInAttribute->setFontItalic(
true);
161 highlightMatchAttribute->setDynamicAttribute (Attribute::ActivateCaretIn, caretInAttribute);
197 updateSelectionOnly();
198 connect(view, SIGNAL(selectionChanged(KTextEditor::View*)),
199 this, SLOT(updateSelectionOnly()));
231 m_powerUi->replacement->setEditText(replacementPattern);
240 return m_powerUi->replacement->currentText();
249 m_powerUi->searchMode->setCurrentIndex(mode);
256 const bool found = find();
259 QComboBox *combo = m_powerUi != 0 ? m_powerUi->pattern : m_incUi->pattern;
262 addCurrentTextToHistory(combo);
272 QComboBox *combo = m_powerUi != 0 ? m_powerUi->pattern : m_incUi->pattern;
275 addCurrentTextToHistory(combo);
280 KTextEditor::Message::MessageType type, KTextEditor::Message::MessagePosition position,
281 KTextEditor::Message::AutoHideMode autoHideMode,
int durationMs,
bool blink)
285 if (message && visible && !blink)
293 message =
new KTextEditor::Message(text, type);
294 message->setPosition(position);
295 message->setAutoHide(durationMs);
296 message->setAutoHideMode(autoHideMode);
301 void KateSearchBar::showInfoMessage(
const QString& text)
303 typedef KTextEditor::Message KTEM;
304 updateMessage(m_infoMessage,
true, text, KTEM::Positive, KTEM::BottomInView, KTEM::AfterUserInteraction, 3000,
false);
307 void KateSearchBar::highlightMatch(
const Range & range) {
308 KTextEditor::MovingRange*
const highlight = m_view->
doc()->
newMovingRange(range, Kate::TextRange::DoNotExpand);
309 highlight->setView(m_view);
310 highlight->setAttributeOnlyForViews(
true);
312 highlight->setZDepth (-10000.0);
313 highlight->setAttribute(highlightMatchAttribute);
314 m_hlRanges.
append(highlight);
317 void KateSearchBar::highlightReplacement(
const Range & range) {
318 KTextEditor::MovingRange*
const highlight = m_view->
doc()->
newMovingRange(range, Kate::TextRange::DoNotExpand);
319 highlight->setView(m_view);
320 highlight->setAttributeOnlyForViews(
true);
322 highlight->setZDepth (-10000.0);
323 highlight->setAttribute(highlightReplacementAttribute);
324 m_hlRanges.
append(highlight);
327 void KateSearchBar::indicateMatch(MatchResult matchResult) {
329 : m_incUi->pattern->lineEdit();
332 switch (matchResult) {
337 KColorScheme::adjustBackground(background, KColorScheme::PositiveBackground);
341 KColorScheme::adjustBackground(background, KColorScheme::NegativeBackground);
348 KColorScheme::adjustBackground(background, KColorScheme::NeutralBackground);
352 typedef KTextEditor::Message KTEM;
353 const int messageDuration = 2000;
356 KTEM::Information, KTEM::TopInView, KTEM::Immediate, messageDuration,
true);
359 KTEM::Information, KTEM::BottomInView, KTEM::Immediate, messageDuration,
true);
361 updateMessage(m_notFoundMessage, matchResult ==
MatchMismatch,
i18n(
"Not found"),
362 KTEM::Warning, KTEM::BottomInView, KTEM::Immediate, messageDuration,
false);
369 void KateSearchBar::selectRange(
KateView * view,
const KTextEditor::Range & range) {
379 void KateSearchBar::selectRange2(
const KTextEditor::Range & range) {
380 disconnect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)),
this, SLOT(updateSelectionOnly()));
381 selectRange(m_view, range);
382 connect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)),
this, SLOT(updateSelectionOnly()));
387 void KateSearchBar::onIncPatternChanged(
const QString & pattern)
395 m_incUi->next->setDisabled(pattern.
isEmpty());
396 m_incUi->prev->setDisabled(pattern.
isEmpty());
402 const Range inputRange = KTextEditor::Range(m_incInitCursor, m_view->
document()->documentEnd());
406 const bool wrap = !match.isValid() && !pattern.
isEmpty();
410 const KTextEditor::Range inputRange = m_view->
document()->documentRange();
411 match.searchText(inputRange, pattern);
418 const Range selectionRange = pattern.
isEmpty() ? Range(m_incInitCursor, m_incInitCursor) :
419 match.isValid() ? match.range() :
423 disconnect(m_view, SIGNAL(cursorPositionChanged(KTextEditor::View*,KTextEditor::Cursor)),
424 this, SLOT(updateIncInitCursor()));
425 selectRange2(selectionRange);
426 connect(m_view, SIGNAL(cursorPositionChanged(KTextEditor::View*,KTextEditor::Cursor)),
427 this, SLOT(updateIncInitCursor()));
429 indicateMatch(matchResult);
439 m_powerUi->matchCase->setChecked(matchCase);
441 m_incUi->matchCase->setChecked(matchCase);
446 void KateSearchBar::onMatchCaseToggled(
bool ) {
451 const QString pattern = m_incUi->pattern->currentText();
452 onIncPatternChanged(pattern);
462 return isPower() ? m_powerUi->matchCase->isChecked()
463 : m_incUi->matchCase->isChecked();
468 void KateSearchBar::fixForSingleLine(Range & range, SearchDirection searchDirection) {
469 FAST_DEBUG(
"Single-line workaround checking BEFORE" << range);
471 const int line = range.start().line();
472 const int col = range.start().column();
473 const int maxColWithNewline = m_view->
document()->lineLength(line) + 1;
474 if (col == maxColWithNewline) {
476 const int maxLine = m_view->
document()->lines() - 1;
477 if (line < maxLine) {
478 range.setRange(Cursor(line + 1, 0), range.end());
479 FAST_DEBUG(
"Search range fixed to " << range);
482 range = Range::invalid();
486 const int col = range.end().column();
488 FAST_DEBUG(
"Ending after a newline" << range);
489 const int line = range.end().line();
491 const int maxColWithNewline = m_view->
document()->lineLength(line - 1);
492 range.setRange(range.start(), Cursor(line - 1, maxColWithNewline));
493 FAST_DEBUG(
"Search range fixed to " << range);
496 range = Range::invalid();
500 FAST_DEBUG(
"Single-line workaround checking AFTER" << range);
505 void KateSearchBar::onReturnPressed() {
507 const bool shiftDown = (modifiers & Qt::ShiftModifier) != 0;
508 const bool controlDown = (modifiers & Qt::ControlModifier) != 0;
531 bool KateSearchBar::find(SearchDirection searchDirection,
const QString * replacement) {
538 disconnect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)),
this, SLOT(updateSelectionOnly()));
543 const Search::SearchOptions enabledOptions = searchOptions(searchDirection);
548 if (selection.isValid()) {
551 inputRange = selection;
555 inputRange.setRange(selection.start(), m_view->
document()->documentEnd());
557 inputRange.setRange(Cursor(0, 0), selection.end());
568 inputRange.setRange(cursorPos, m_view->
document()->documentEnd());
570 inputRange.setRange(Cursor(cursorPos.line(), cursorPos.column()+1), m_view->
document()->documentEnd());
573 inputRange.setRange(Cursor(0, 0), cursorPos);
579 const bool regexMode = enabledOptions.testFlag(Search::Regex);
583 if (regexMode && !multiLinePattern) {
584 fixForSingleLine(inputRange, searchDirection);
589 Range afterReplace = Range::invalid();
593 const Cursor end(inputRange.end().line(), inputRange.end().column() - 1);
594 inputRange.setRange(inputRange.start(), end);
599 if (match.isValid() && match.range() == selection) {
601 if (replacement != 0) {
603 KTextEditor::MovingRange *smartInputRange = m_view->
doc()->
newMovingRange (inputRange, KTextEditor::MovingRange::ExpandLeft | KTextEditor::MovingRange::ExpandRight);
604 afterReplace = match.replace(*replacement, m_view->
blockSelection());
605 inputRange = *smartInputRange;
606 delete smartInputRange;
612 const Cursor start = (replacement != 0) ? afterReplace.end() : selection.end();
613 inputRange.setRange(start, inputRange.end());
615 const Cursor end = (replacement != 0) ? afterReplace.start() : selection.start();
616 inputRange.setRange(inputRange.start(), end);
621 fixForSingleLine(inputRange, searchDirection);
626 bool askWrap = !match.isValid() && (!selection.isValid() || !
selectionOnly());
628 KateMatch matchAfterWarp(m_view->
doc(), enabledOptions);
632 if (!matchAfterWarp.isValid())
637 if (m_unitTestMode) {
642 : i18n(
"Top of file reached. Continue from bottom?");
643 wrap = (KMessageBox::questionYesNo( 0, question,
i18n(
"Continue search?"), KStandardGuiItem::yes(), KStandardGuiItem::no(),
644 QString(
"DoNotShowAgainContinueSearchDialog")) == KMessageBox::Yes );
649 match = matchAfterWarp;
652 if (match.isValid()) {
653 selectRange2(match.range());
660 indicateMatch(matchResult);
663 if (afterReplace.isValid()) {
664 highlightReplacement(afterReplace);
668 connect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)),
this, SLOT(updateSelectionOnly()));
683 : m_view->
document()->documentRange();
684 const int occurrences =
findAll(inputRange, NULL);
687 showInfoMessage(
i18ncp(
"short translation",
"1 match found",
"%1 matches found", occurrences));
694 void KateSearchBar::onPowerPatternChanged(
const QString & ) {
695 givePatternFeedback();
701 bool KateSearchBar::isPatternValid()
const {
712 void KateSearchBar::givePatternFeedback() {
714 m_powerUi->findNext->setEnabled(isPatternValid());
715 m_powerUi->findPrev->setEnabled(isPatternValid());
716 m_powerUi->replaceNext->setEnabled(isPatternValid());
717 m_powerUi->replaceAll->setEnabled(isPatternValid());
722 void KateSearchBar::addCurrentTextToHistory(
QComboBox * combo) {
724 const int index = combo->
findText(text);
736 void KateSearchBar::backupConfig(
bool ofPower) {
738 m_powerMatchCase = m_powerUi->matchCase->isChecked();
739 m_powerMode = m_powerUi->searchMode->currentIndex();
741 m_incMatchCase = m_incUi->matchCase->isChecked();
747 void KateSearchBar::sendConfig() {
749 long futureFlags = pastFlags;
751 if (m_powerUi != NULL) {
752 const bool OF_POWER =
true;
753 backupConfig(OF_POWER);
756 const long incFlagsOnly = pastFlags
761 futureFlags = incFlagsOnly
773 }
else if (m_incUi != NULL) {
774 const bool OF_INCREMENTAL =
false;
775 backupConfig(OF_INCREMENTAL);
778 const long powerFlagsOnly = pastFlags
780 | KateViewConfig::PowerFromCursor
787 futureFlags = powerFlagsOnly
800 const QString replacement = m_powerUi->replacement->currentText();
807 addCurrentTextToHistory(m_powerUi->pattern);
810 addCurrentTextToHistory(m_powerUi->replacement);
821 disconnect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)),
this, SLOT(updateSelectionOnly()));
823 const Search::SearchOptions enabledOptions = searchOptions(
SearchForward);
825 const bool regexMode = enabledOptions.testFlag(Search::Regex);
828 KTextEditor::MovingRange * workingRange = m_view->
doc()->
newMovingRange(inputRange);
830 int matchCounter = 0;
833 int line = inputRange.start().line();
841 if (!match.isValid()) {
844 bool const originalMatchEmpty = match.isEmpty();
847 if (replacement != NULL) {
848 if (matchCounter == 0) {
853 const Range afterReplace = match.replace(*replacement,
false, ++matchCounter);
857 highlightRanges << afterReplace;
861 highlightRanges << match.range();
866 if (highlightRanges.
last().end() >= workingRange->end())
868 KTextEditor::MovingCursor* workingStart =
870 if (originalMatchEmpty) {
873 workingStart->move(1);
874 }
else if (regexMode && !multiLinePattern && workingStart->atEndOfLine()) {
877 workingStart->move(1);
879 workingRange->setRange(*workingStart, workingRange->end());
881 const bool atEndOfDocument = workingStart->atEndOfDocument();
884 if (!workingRange->toRange().isValid() || atEndOfDocument) {
889 }
while (block && ++line <= inputRange.end().line());
892 if (matchCounter > 0) {
893 if (replacement != NULL) {
898 if (replacement == NULL)
899 foreach (
const Range &r, highlightRanges) {
903 foreach (
const Range &r, highlightRanges) {
904 highlightReplacement(r);
910 connect(m_view, SIGNAL(selectionChanged(KTextEditor::View*)),
this, SLOT(updateSelectionOnly()));
923 const QString replacement = m_powerUi->replacement->currentText();
927 const bool selected = m_view->
selection();
930 : m_view->
document()->documentRange();
934 int replacementsDone=
findAll(inputRange, &replacement);
937 showInfoMessage(
i18ncp(
"short translation",
"1 replacement made",
"%1 replacements made", replacementsDone));
943 addCurrentTextToHistory(m_powerUi->pattern);
946 addCurrentTextToHistory(m_powerUi->replacement);
957 m_powerUi->pattern->setEditText(searchPattern);
959 m_incUi->pattern->setEditText(searchPattern);
965 return (m_powerUi != 0) ? m_powerUi->pattern->currentText()
966 : m_incUi->pattern->currentText();
977 m_powerUi->selectionOnly->setChecked(selectionOnly);
984 return isPower() ? m_powerUi->selectionOnly->isChecked()
990 KTextEditor::Search::SearchOptions KateSearchBar::searchOptions(SearchDirection searchDirection)
const {
991 Search::SearchOptions enabledOptions = KTextEditor::Search::Default;
994 enabledOptions |= Search::CaseInsensitive;
998 enabledOptions |= Search::Backwards;
1001 if (m_powerUi != NULL) {
1002 switch (m_powerUi->searchMode->currentIndex()) {
1004 enabledOptions |= Search::WholeWords;
1008 enabledOptions |= Search::EscapeSequences;
1012 enabledOptions |= Search::Regex;
1022 return enabledOptions;
1041 const int inputLen = pattern.
length();
1043 bool insideClass =
false;
1044 int captureCount = 0;
1046 while (input < inputLen) {
1049 if (pattern[input].unicode() == L
']') {
1050 insideClass =
false;
1056 switch (pattern[input].unicode())
1065 curInfo.openIndex = input;
1066 curInfo.capturing = (input + 1 >= inputLen) || (pattern[input + 1].unicode() !=
'?');
1067 if (curInfo.capturing) {
1070 curInfo.captureNumber = captureCount;
1071 parInfos.
push(curInfo);
1077 if (!parInfos.
empty()) {
1078 ParInfo & top = parInfos.
top();
1079 if (top.capturing && (top.captureNumber <= 9)) {
1080 const int start = top.openIndex + 1;
1081 const int len = input - start;
1082 if (capturePatterns.
size() < top.captureNumber) {
1083 capturePatterns.
resize(top.captureNumber);
1085 capturePatterns[top.captureNumber - 1] = pattern.
mid(start, len);
1106 return capturePatterns;
1111 void KateSearchBar::showExtendedContextMenu(
bool forPattern,
const QPoint& pos) {
1113 QComboBox* comboBox = forPattern ? m_powerUi->pattern : m_powerUi->replacement;
1116 if (contextMenu == NULL) {
1120 bool extendMenu =
false;
1121 bool regexMode =
false;
1122 switch (m_powerUi->searchMode->currentIndex()) {
1135 AddMenuManager addMenuManager(contextMenu, 37);
1137 addMenuManager.enableMenu(extendMenu);
1142 addMenuManager.addEntry(
"^",
"",
i18n(
"Beginning of line"));
1143 addMenuManager.addEntry(
"$",
"",
i18n(
"End of line"));
1144 addMenuManager.addSeparator();
1145 addMenuManager.addEntry(
".",
"",
i18n(
"Any single character (excluding line breaks)"));
1146 addMenuManager.addSeparator();
1147 addMenuManager.addEntry(
"+",
"",
i18n(
"One or more occurrences"));
1148 addMenuManager.addEntry(
"*",
"",
i18n(
"Zero or more occurrences"));
1149 addMenuManager.addEntry(
"?",
"",
i18n(
"Zero or one occurrences"));
1150 addMenuManager.addEntry(
"{a",
",b}",
i18n(
"<a> through <b> occurrences"),
"{",
",}");
1151 addMenuManager.addSeparator();
1152 addMenuManager.addEntry(
"(",
")",
i18n(
"Group, capturing"));
1153 addMenuManager.addEntry(
"|",
"",
i18n(
"Or"));
1154 addMenuManager.addEntry(
"[",
"]",
i18n(
"Set of characters"));
1155 addMenuManager.addEntry(
"[^",
"]",
i18n(
"Negative set of characters"));
1156 addMenuManager.addSeparator();
1159 addMenuManager.addEntry(
"\\0",
"",
i18n(
"Whole match reference"));
1160 addMenuManager.addSeparator();
1162 const QString pattern = m_powerUi->pattern->currentText();
1165 const int captureCount = capturePatterns.
count();
1166 for (
int i = 1; i <= 9; i++) {
1168 const QString & captureDetails = (i <= captureCount)
1169 ? (
QString(
" = (") + capturePatterns[i - 1].left(30)) +
QString(
")")
1171 addMenuManager.addEntry(
"\\" + number,
"",
1172 i18n(
"Reference") +
' ' + number + captureDetails);
1175 addMenuManager.addSeparator();
1179 addMenuManager.addEntry(
"\\n",
"",
i18n(
"Line break"));
1180 addMenuManager.addEntry(
"\\t",
"",
i18n(
"Tab"));
1182 if (forPattern && regexMode) {
1183 addMenuManager.addEntry(
"\\b",
"",
i18n(
"Word boundary"));
1184 addMenuManager.addEntry(
"\\B",
"",
i18n(
"Not word boundary"));
1185 addMenuManager.addEntry(
"\\d",
"",
i18n(
"Digit"));
1186 addMenuManager.addEntry(
"\\D",
"",
i18n(
"Non-digit"));
1187 addMenuManager.addEntry(
"\\s",
"",
i18n(
"Whitespace (excluding line breaks)"));
1188 addMenuManager.addEntry(
"\\S",
"",
i18n(
"Non-whitespace (excluding line breaks)"));
1189 addMenuManager.addEntry(
"\\w",
"",
i18n(
"Word character (alphanumerics plus '_')"));
1190 addMenuManager.addEntry(
"\\W",
"",
i18n(
"Non-word character"));
1193 addMenuManager.addEntry(
"\\0???",
"",
i18n(
"Octal character 000 to 377 (2^8-1)"),
"\\0");
1194 addMenuManager.addEntry(
"\\x????",
"",
i18n(
"Hex character 0000 to FFFF (2^16-1)"),
"\\x");
1195 addMenuManager.addEntry(
"\\\\",
"",
i18n(
"Backslash"));
1197 if (forPattern && regexMode) {
1198 addMenuManager.addSeparator();
1199 addMenuManager.addEntry(
"(?:E",
")",
i18n(
"Group, non-capturing"),
"(?:");
1200 addMenuManager.addEntry(
"(?=E",
")",
i18n(
"Lookahead"),
"(?=");
1201 addMenuManager.addEntry(
"(?!E",
")",
i18n(
"Negative lookahead"),
"(?!");
1205 addMenuManager.addSeparator();
1206 addMenuManager.addEntry(
"\\L",
"",
i18n(
"Begin lowercase conversion"));
1207 addMenuManager.addEntry(
"\\U",
"",
i18n(
"Begin uppercase conversion"));
1208 addMenuManager.addEntry(
"\\E",
"",
i18n(
"End case conversion"));
1209 addMenuManager.addEntry(
"\\l",
"",
i18n(
"Lowercase first character conversion"));
1210 addMenuManager.addEntry(
"\\u",
"",
i18n(
"Uppercase first character conversion"));
1211 addMenuManager.addEntry(
"\\#[#..]",
"",
i18n(
"Replacement counter (for Replace All)"),
"\\#");
1217 if (result != NULL) {
1218 addMenuManager.handle(result, comboBox->
lineEdit());
1224 void KateSearchBar::onPowerModeChanged(
int ) {
1225 if (m_powerUi->searchMode->currentIndex() ==
MODE_REGEX) {
1226 m_powerUi->matchCase->setChecked(
true);
1232 givePatternFeedback();
1238 const bool selected = view->
selection();
1243 Search::SearchOptions enabledOptions(KTextEditor::Search::Default);
1245 enabledOptions |= Search::Backwards;
1254 inputRange.setRange(Cursor(0, 0), selRange.start());
1261 if (match.isValid()) {
1262 selectRange(view, match.range());
1266 inputRange.setRange(Cursor(0, 0), selRange.start());
1272 if (match2.isValid()) {
1273 selectRange(view, match2.range());
1290 const bool selected = m_view->
selection();
1293 if (selection.onSingleLine()) {
1298 selectionOnly =
true;
1303 if (initialPattern.
isNull()) {
1305 const bool fromReplace = (m_powerUi != NULL) && (m_widget->
isVisible());
1307 QLineEdit *
const patternLineEdit = m_powerUi->pattern->lineEdit();
1308 Q_ASSERT(patternLineEdit != NULL);
1310 m_powerUi->pattern->setFocus(Qt::MouseFocusReason);
1315 const bool fromIncremental = (m_incUi != NULL) && (m_widget->
isVisible());
1316 if (fromIncremental) {
1317 initialPattern = m_incUi->pattern->currentText();
1322 const bool create = (m_powerUi == NULL);
1325 if (m_incUi != NULL) {
1327 const bool OF_INCREMENTAL =
false;
1328 backupConfig(OF_INCREMENTAL);
1339 m_powerUi =
new Ui::PowerSearchBar;
1340 m_powerUi->setupUi(m_widget);
1344 m_powerUi->pattern->setDuplicatesEnabled(
false);
1345 m_powerUi->pattern->setInsertPolicy(QComboBox::InsertAtTop);
1348 m_powerUi->replacement->setDuplicatesEnabled(
false);
1349 m_powerUi->replacement->setInsertPolicy(QComboBox::InsertAtTop);
1354 m_powerUi->mutate->setIcon(KIcon(
"arrow-down-double"));
1355 m_powerUi->findNext->setIcon(KIcon(
"go-down-search"));
1356 m_powerUi->findPrev->setIcon(KIcon(
"go-up-search"));
1357 m_powerUi->findAll->setIcon(KIcon(
"edit-find"));
1363 m_powerUi->pattern->completionObject()->setIgnoreCase(
false);
1364 m_powerUi->replacement->completionObject()->setIgnoreCase(
false);
1367 m_powerUi->selectionOnly->setChecked(selectionOnly);
1371 m_powerUi->matchCase->setChecked(m_powerMatchCase);
1372 m_powerUi->searchMode->setCurrentIndex(m_powerMode);
1376 m_powerUi->pattern->setCurrentIndex(-1);
1377 m_powerUi->replacement->setCurrentIndex(-1);
1380 QLineEdit *
const patternLineEdit = m_powerUi->pattern->lineEdit();
1381 Q_ASSERT(patternLineEdit != NULL);
1382 patternLineEdit->
setText(initialPattern);
1386 QLineEdit *
const replacementLineEdit = m_powerUi->replacement->lineEdit();
1387 Q_ASSERT(replacementLineEdit != NULL);
1388 replacementLineEdit->
setText(
"");
1391 onPowerPatternChanged(initialPattern);
1392 givePatternFeedback();
1398 connect(m_powerUi->findNext, SIGNAL(clicked()),
this, SLOT(
findNext()));
1402 connect(m_powerUi->searchMode, SIGNAL(currentIndexChanged(
int)),
this, SLOT(onPowerModeChanged(
int)));
1403 connect(m_powerUi->matchCase, SIGNAL(toggled(
bool)),
this, SLOT(onMatchCaseToggled(
bool)));
1404 connect(m_powerUi->findAll, SIGNAL(clicked()),
this, SLOT(
findAll()));
1407 connect(patternLineEdit, SIGNAL(returnPressed()),
this, SLOT(onReturnPressed()));
1411 m_powerUi->pattern->setContextMenuPolicy(Qt::CustomContextMenu);
1413 SLOT(onPowerPatternContextMenuRequest(
QPoint)));
1414 m_powerUi->replacement->setContextMenuPolicy(Qt::CustomContextMenu);
1416 SLOT(onPowerReplacmentContextMenuRequest(
QPoint)));
1421 m_powerUi->pattern->setFocus(Qt::MouseFocusReason);
1431 const bool selected = m_view->
selection();
1434 if (selection.onSingleLine()) {
1441 if (initialPattern.
isNull()) {
1443 const bool fromIncremental = (m_incUi != NULL) && (m_widget->
isVisible());
1444 if (fromIncremental) {
1445 m_incUi->pattern->lineEdit()->selectAll();
1446 m_incUi->pattern->setFocus(Qt::MouseFocusReason);
1451 const bool fromReplace = (m_powerUi != NULL) && (m_widget->
isVisible());
1453 initialPattern = m_powerUi->pattern->currentText();
1458 if (initialPattern.
isNull()) {
1459 const KTextEditor::Cursor cursorPosition = m_view->
cursorPosition();
1460 initialPattern = m_view->
doc()->
getWord( cursorPosition );
1464 const bool create = (m_incUi == NULL);
1467 if (m_powerUi != NULL) {
1469 const bool OF_POWER =
true;
1470 backupConfig(OF_POWER);
1481 m_incUi =
new Ui::IncrementalSearchBar;
1482 m_incUi->setupUi(m_widget);
1491 m_incUi->mutate->setIcon(KIcon(
"arrow-up-double"));
1492 m_incUi->next->setIcon(KIcon(
"go-down-search"));
1493 m_incUi->prev->setIcon(KIcon(
"go-up-search"));
1496 m_incUi->pattern->setMinimumWidth(12 * m_incUi->pattern->fontMetrics().height());
1501 m_incUi->pattern->setDuplicatesEnabled(
false);
1502 m_incUi->pattern->setInsertPolicy(QComboBox::InsertAtTop);
1505 m_incUi->pattern->setAutoCompletion(
false);
1510 m_incUi->matchCase->setChecked(m_incMatchCase);
1514 m_incUi->pattern->setCurrentIndex(-1);
1519 m_incUi->pattern->setEditText(initialPattern);
1520 connect(m_incUi->pattern, SIGNAL(editTextChanged(
QString)),
this, SLOT(onIncPatternChanged(
QString)));
1521 m_incUi->pattern->lineEdit()->selectAll();
1524 if (initialPattern.
isEmpty()) {
1530 m_incUi->next->setDisabled(initialPattern.
isEmpty());
1531 m_incUi->prev->setDisabled(initialPattern.
isEmpty());
1536 connect(m_incUi->pattern->lineEdit(), SIGNAL(returnPressed()),
this, SLOT(onReturnPressed()));
1539 connect(m_incUi->matchCase, SIGNAL(toggled(
bool)),
this, SLOT(onMatchCaseToggled(
bool)));
1544 m_incUi->pattern->setFocus(Qt::MouseFocusReason);
1550 if (m_infoMessage) {
1551 delete m_infoMessage;
1557 qDeleteAll(m_hlRanges);
1568 highlightMatchAttribute->setBackground(searchColor);
1569 highlightMatchAttribute->dynamicAttribute (Attribute::ActivateMouseIn)->setBackground(searchColor);
1570 highlightMatchAttribute->dynamicAttribute (Attribute::ActivateCaretIn)->setBackground(searchColor);
1573 highlightReplacementAttribute->setBackground(replaceColor);
1579 if (m_incUi != NULL) {
1583 updateSelectionOnly();
1588 void KateSearchBar::updateSelectionOnly() {
1589 if (m_powerUi == NULL) {
1594 const bool selected = m_view->
selection();
1598 selectionOnly = !selection.onSingleLine();
1600 m_powerUi->selectionOnly->setChecked(selectionOnly);
1604 void KateSearchBar::updateIncInitCursor() {
1605 if (m_incUi == NULL) {
1614 void KateSearchBar::onPowerPatternContextMenuRequest(
const QPoint& pos) {
1615 const bool FOR_PATTERN =
true;
1616 showExtendedContextMenu(FOR_PATTERN, pos);
1619 void KateSearchBar::onPowerPatternContextMenuRequest() {
1620 onPowerPatternContextMenuRequest(m_powerUi->pattern->mapFromGlobal(
QCursor::pos()));
1624 void KateSearchBar::onPowerReplacmentContextMenuRequest(
const QPoint& pos) {
1625 const bool FOR_REPLACEMENT =
false;
1626 showExtendedContextMenu(FOR_REPLACEMENT, pos);
1629 void KateSearchBar::onPowerReplacmentContextMenuRequest() {
1630 onPowerReplacmentContextMenuRequest(m_powerUi->replacement->mapFromGlobal(
QCursor::pos()));
1635 return m_powerUi != 0;
1644 m_powerUi->replaceNext->setEnabled (m_view->
doc()->isReadWrite() && isPatternValid());
1645 m_powerUi->replaceAll->setEnabled (m_view->
doc()->isReadWrite() && isPatternValid());
void setReplacementPattern(const QString &replacementPattern)
Set the current replacement pattern.
QScriptValue i18n(QScriptContext *context, QScriptEngine *engine)
i18n("text", arguments [optional])
void setSearchPattern(const QString &searchPattern)
Set the current search pattern.
virtual KTextEditor::MovingRange * newMovingRange(const KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors=KTextEditor::MovingRange::DoNotExpand, KTextEditor::MovingRange::EmptyBehavior emptyBehavior=KTextEditor::MovingRange::AllowEmpty)
Create a new moving range for this document.
void selectWord(const KTextEditor::Cursor &cursor)
Qt::KeyboardModifiers keyboardModifiers()
KateRenderer * renderer()
KTextEditor::Document * document() const
void setSelectionOnly(bool selectionOnly)
const QColor & replaceHighlightColor() const
void setText(const QString &)
QString searchPattern() const
void setIcon(const QIcon &icon)
QMenu * createStandardContextMenu()
KateUndoManager * undoManager()
void enterIncrementalMode()
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
void insertItem(int index, const QString &text, const QVariant &userData)
QScriptValue i18ncp(QScriptContext *context, QScriptEngine *engine)
i18ncp("context", "singular", "plural", number, arguments [optional])
virtual const KTextEditor::Range & selectionRange() const
virtual void showEvent(QShowEvent *event)
int findText(const QString &text, QFlags< Qt::MatchFlag > flags) const
QString number(int n, int base)
void append(const T &value)
void removeBarWidget(KateViewBarWidget *barWidget)
Removes a widget from this viewbar.
uint toUInt(bool *ok) const
bool selectionOnly() const
KateRendererConfig * config() const
Configuration.
virtual bool setSelection(const KTextEditor::Range &selection)
void updateHighlightColors()
void setMatchCase(bool matchCase)
void slotReadWriteChanged()
virtual KTextEditor::Cursor documentEnd() const
QStringListModel * replacementHistoryModel()
KTextEditor::Range rangeOnLine(KTextEditor::Range range, int line) const
virtual bool blockSelection() const
bool isMultiLine() const
States, whether the pattern matches multiple lines, even if it was repaired using repairPattern()...
KateSearchBar(bool initAsPower, KateView *view, KateViewConfig *config)
QString replacementPattern() const
void setMargin(int margin)
virtual bool selection() const
void setData(const QVariant &userData)
void insert(const QString &newText)
static void nextMatchForSelection(KateView *view, SearchDirection searchDirection)
void undoSafePoint()
Prevent latest KateUndoGroup from being merged with the next one.
KTextEditor::Cursor cursorPosition() const
QLineEdit * lineEdit() const
void removeItem(int index)
QString mid(int position, int n) const
QString getWord(const KTextEditor::Cursor &cursor)
int count(const T &value) const
const QColor & searchHighlightColor() const
void setCurrentIndex(int index)
virtual QString selectionText() const
KateDocument * doc()
accessor to katedocument pointer
virtual bool postMessage(KTextEditor::Message *message)
int maxHistorySize() const
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool setCursorPositionInternal(const KTextEditor::Cursor &position, uint tabwidth=1, bool calledExternally=false)
QStringListModel * patternHistoryModel()
void setSearchFlags(long flags)
KTextEditor::Range searchText(const KTextEditor::Range &range, const QString &pattern)
void setSearchMode(SearchMode mode)
typedef KeyboardModifiers