Changeset View
Changeset View
Standalone View
Standalone View
src/search/katesearchbar.cpp
Show First 20 Lines • Show All 91 Lines • ▼ Show 20 Line(s) | 369 | case MatchNeutral: | |||
---|---|---|---|---|---|
370 | KColorScheme::adjustBackground(background, KColorScheme::NeutralBackground); | 370 | KColorScheme::adjustBackground(background, KColorScheme::NeutralBackground); | ||
371 | break; | 371 | break; | ||
372 | } | 372 | } | ||
373 | 373 | | |||
374 | // Update status label | 374 | // Update status label | ||
375 | if (m_incUi != nullptr) { | 375 | if (m_incUi != nullptr) { | ||
376 | QPalette foreground(m_incUi->status->palette()); | 376 | QPalette foreground(m_incUi->status->palette()); | ||
377 | switch (matchResult) { | 377 | switch (matchResult) { | ||
378 | case MatchFound: // FALLTHROUGH | 378 | case MatchFound: | ||
379 | m_incUi->next->setDisabled(false); | ||||
380 | m_incUi->prev->setDisabled(false); | ||||
381 | [[fallthrough]]; | ||||
379 | case MatchNothing: | 382 | case MatchNothing: | ||
380 | KColorScheme::adjustForeground(foreground, KColorScheme::NormalText, QPalette::WindowText, KColorScheme::Window); | 383 | KColorScheme::adjustForeground(foreground, KColorScheme::NormalText, QPalette::WindowText, KColorScheme::Window); | ||
381 | m_incUi->status->clear(); | 384 | m_incUi->status->clear(); | ||
382 | break; | 385 | break; | ||
383 | case MatchWrappedForward: | 386 | case MatchWrappedForward: | ||
384 | case MatchWrappedBackward: | 387 | case MatchWrappedBackward: | ||
385 | KColorScheme::adjustForeground(foreground, KColorScheme::NormalText, QPalette::WindowText, KColorScheme::Window); | 388 | KColorScheme::adjustForeground(foreground, KColorScheme::NormalText, QPalette::WindowText, KColorScheme::Window); | ||
386 | if (matchResult == MatchWrappedBackward) { | 389 | if (matchResult == MatchWrappedBackward) { | ||
Show All 33 Lines | |||||
420 | { | 423 | { | ||
421 | if (!m_incUi) { | 424 | if (!m_incUi) { | ||
422 | return; | 425 | return; | ||
423 | } | 426 | } | ||
424 | 427 | | |||
425 | // clear prior highlightings (deletes info message if present) | 428 | // clear prior highlightings (deletes info message if present) | ||
426 | clearHighlights(); | 429 | clearHighlights(); | ||
427 | 430 | | |||
428 | m_incUi->next->setDisabled(pattern.isEmpty()); | 431 | m_incUi->next->setDisabled(true); | ||
429 | m_incUi->prev->setDisabled(pattern.isEmpty()); | 432 | m_incUi->prev->setDisabled(true); | ||
430 | 433 | | |||
431 | KateMatch match(m_view->doc(), searchOptions()); | 434 | indicateMatch(MatchNothing); | ||
432 | 435 | | |||
433 | if (!pattern.isEmpty()) { | 436 | if (pattern.isEmpty()) { | ||
434 | // Find, first try | 437 | selectRange2(Range(m_incInitCursor, m_incInitCursor)); | ||
435 | const Range inputRange = KTextEditor::Range(m_incInitCursor, m_view->document()->documentEnd()); | 438 | return; | ||
436 | match.searchText(inputRange, pattern); | | |||
437 | } | 439 | } | ||
438 | 440 | | |||
439 | const bool wrap = !match.isValid() && !pattern.isEmpty(); | 441 | m_currentSearchRange = 0; | ||
440 | 442 | | |||
441 | if (wrap) { | 443 | if (!m_incSearchRanges.isEmpty()) { | ||
442 | // Find, second try | 444 | incrementalSearch(); | ||
443 | const KTextEditor::Range inputRange = m_view->document()->documentRange(); | 445 | return; | ||
444 | match.searchText(inputRange, pattern); | 446 | } | ||
447 | | ||||
448 | // Build search range chunks in advance... | ||||
449 | const KTextEditor::Cursor chunkSize(2000, 0); | ||||
450 | const int fuzzyChunk = chunkSize.line() / 3; // To avoid too small chunks, so expand the last by 30% when possible | ||||
451 | // ...starting from current cursor position down to document end... | ||||
452 | KTextEditor::Cursor fromPos = m_incInitCursor; | ||||
453 | KTextEditor::Cursor toPos = KTextEditor::Cursor(m_incInitCursor.line() + chunkSize.line(), 0); | ||||
454 | int lastLine = m_view->document()->documentEnd().line() - fuzzyChunk - 1; | ||||
455 | forever { | ||||
456 | if (toPos.line() > lastLine) { | ||||
457 | toPos = m_view->document()->documentEnd(); | ||||
458 | m_incSearchRanges.append(KTextEditor::Range(fromPos, toPos)); | ||||
459 | break; | ||||
460 | } | ||||
461 | m_incSearchRanges.append(KTextEditor::Range(fromPos, toPos)); | ||||
462 | fromPos = toPos; | ||||
463 | toPos += chunkSize; | ||||
464 | } | ||||
465 | | ||||
466 | // ...continuing from top of document down to current cursor position | ||||
467 | fromPos = KTextEditor::Cursor(0, 0); | ||||
468 | toPos = chunkSize; | ||||
469 | lastLine = m_incInitCursor.line() - fuzzyChunk - 1; | ||||
470 | forever { | ||||
471 | if (toPos.line() > lastLine) { | ||||
472 | // Expand last chunk to end of current line to ensure we have a match when cursor is inside of pattern | ||||
473 | toPos = KTextEditor::Cursor(m_incInitCursor.line(), m_view->document()->lineLength(m_incInitCursor.line())); | ||||
474 | m_incSearchRanges.append(KTextEditor::Range(fromPos, toPos)); | ||||
475 | break; | ||||
476 | } | ||||
477 | m_incSearchRanges.append(KTextEditor::Range(fromPos, toPos)); | ||||
478 | fromPos = toPos; | ||||
479 | toPos += chunkSize; | ||||
445 | } | 480 | } | ||
446 | 481 | | |||
447 | const MatchResult matchResult = match.isValid() ? (wrap ? MatchWrappedForward : MatchFound) : | 482 | incrementalSearch(); | ||
448 | pattern.isEmpty() ? MatchNothing : | 483 | } | ||
449 | MatchMismatch; | | |||
450 | 484 | | |||
451 | const Range selectionRange = pattern.isEmpty() ? Range(m_incInitCursor, m_incInitCursor) : | 485 | void KateSearchBar::incrementalSearch() | ||
452 | match.isValid() ? match.range() : | 486 | { | ||
453 | Range::invalid(); | 487 | if (m_incSearchRanges.size() <= m_currentSearchRange) { | ||
488 | // Cursor was changed or user typed too fast | ||||
489 | return; | ||||
490 | } | ||||
454 | 491 | | |||
492 | const Range range = m_incSearchRanges.at(m_currentSearchRange++); | ||||
493 | | ||||
494 | if (hasRangeMatch(range)) { | ||||
495 | // We are done, we have a winner | ||||
496 | return; | ||||
497 | } | ||||
498 | | ||||
499 | if (m_incSearchRanges.size() == m_currentSearchRange) { | ||||
500 | // We are done, nothing found | ||||
501 | selectRange2(Range::invalid()); | ||||
502 | indicateMatch(MatchMismatch); | ||||
503 | } else { | ||||
504 | QTimer::singleShot(0, this, &KateSearchBar::incrementalSearch); | ||||
505 | } | ||||
506 | } | ||||
507 | | ||||
508 | // TODO parameter not needed, func could merged with incrementalSearch() | ||||
509 | bool KateSearchBar::hasRangeMatch(const KTextEditor::Range &range) | ||||
510 | { | ||||
511 | KateMatch match(m_view->doc(), searchOptions()); | ||||
512 | match.searchText(range, searchPattern()); | ||||
513 | | ||||
514 | if (!match.isValid()) { | ||||
515 | return false; | ||||
516 | } | ||||
517 | | ||||
518 | indicateMatch(MatchFound); | ||||
455 | // don't update m_incInitCursor when we move the cursor | 519 | // don't update m_incInitCursor when we move the cursor | ||
456 | disconnect(m_view, &KTextEditor::View::cursorPositionChanged, this, &KateSearchBar::updateIncInitCursor); | 520 | disconnect(m_view, &KTextEditor::View::cursorPositionChanged, this, &KateSearchBar::updateIncInitCursor); | ||
457 | selectRange2(selectionRange); | 521 | selectRange2(match.range()); | ||
458 | connect(m_view, &KTextEditor::View::cursorPositionChanged, this, &KateSearchBar::updateIncInitCursor); | 522 | connect(m_view, &KTextEditor::View::cursorPositionChanged, this, &KateSearchBar::updateIncInitCursor); | ||
459 | 523 | | |||
460 | indicateMatch(matchResult); | 524 | return true; | ||
461 | } | 525 | } | ||
462 | 526 | | |||
463 | void KateSearchBar::setMatchCase(bool matchCase) | 527 | void KateSearchBar::setMatchCase(bool matchCase) | ||
464 | { | 528 | { | ||
465 | if (this->matchCase() == matchCase) { | 529 | if (this->matchCase() == matchCase) { | ||
466 | return; | 530 | return; | ||
467 | } | 531 | } | ||
468 | 532 | | |||
▲ Show 20 Lines • Show All 182 Lines • ▼ Show 20 Line(s) | 1707 | { | |||
1658 | highlightReplacementAttribute->setForeground(foregroundColor); | 1722 | highlightReplacementAttribute->setForeground(foregroundColor); | ||
1659 | } | 1723 | } | ||
1660 | 1724 | | |||
1661 | void KateSearchBar::showEvent(QShowEvent *event) | 1725 | void KateSearchBar::showEvent(QShowEvent *event) | ||
1662 | { | 1726 | { | ||
1663 | // Update init cursor | 1727 | // Update init cursor | ||
1664 | if (m_incUi != nullptr) { | 1728 | if (m_incUi != nullptr) { | ||
1665 | m_incInitCursor = m_view->cursorPosition(); | 1729 | m_incInitCursor = m_view->cursorPosition(); | ||
1730 | m_incSearchRanges.clear(); | ||||
1666 | } | 1731 | } | ||
1667 | 1732 | | |||
1668 | updateSelectionOnly(); | 1733 | updateSelectionOnly(); | ||
1669 | KateViewBarWidget::showEvent(event); | 1734 | KateViewBarWidget::showEvent(event); | ||
1670 | } | 1735 | } | ||
1671 | 1736 | | |||
1672 | void KateSearchBar::updateSelectionOnly() | 1737 | void KateSearchBar::updateSelectionOnly() | ||
1673 | { | 1738 | { | ||
Show All 12 Lines | |||||
1686 | } | 1751 | } | ||
1687 | 1752 | | |||
1688 | void KateSearchBar::updateIncInitCursor() | 1753 | void KateSearchBar::updateIncInitCursor() | ||
1689 | { | 1754 | { | ||
1690 | if (m_incUi == nullptr) { | 1755 | if (m_incUi == nullptr) { | ||
1691 | return; | 1756 | return; | ||
1692 | } | 1757 | } | ||
1693 | 1758 | | |||
1694 | // Update init cursor | 1759 | // Update init cursor, ensure to update search ranges too | ||
1695 | m_incInitCursor = m_view->cursorPosition(); | 1760 | m_incInitCursor = m_view->cursorPosition(); | ||
1761 | m_incSearchRanges.clear(); | ||||
1696 | } | 1762 | } | ||
1697 | 1763 | | |||
1698 | void KateSearchBar::onPowerPatternContextMenuRequest(const QPoint &pos) | 1764 | void KateSearchBar::onPowerPatternContextMenuRequest(const QPoint &pos) | ||
1699 | { | 1765 | { | ||
1700 | const bool FOR_PATTERN = true; | 1766 | const bool FOR_PATTERN = true; | ||
1701 | showExtendedContextMenu(FOR_PATTERN, pos); | 1767 | showExtendedContextMenu(FOR_PATTERN, pos); | ||
1702 | } | 1768 | } | ||
1703 | 1769 | | |||
Show All 37 Lines |