diff --git a/src/IncrementalSearchBar.cpp b/src/IncrementalSearchBar.cpp index 79a28773c..627b03af2 100644 --- a/src/IncrementalSearchBar.cpp +++ b/src/IncrementalSearchBar.cpp @@ -42,6 +42,10 @@ IncrementalSearchBar::IncrementalSearchBar(QWidget* aParent) , _caseSensitive(0) , _regExpression(0) , _highlightMatches(0) + , _reverseSearch(0) + , _findNextButton(0) + , _findPreviousButton(0) + , _searchFromButton(0) { QHBoxLayout* barLayout = new QHBoxLayout(this); @@ -74,21 +78,24 @@ IncrementalSearchBar::IncrementalSearchBar(QWidget* aParent) connect(_searchEdit , SIGNAL(clearButtonClicked()) , this , SLOT(clearLineEdit())); connect(_searchEdit , SIGNAL(textChanged(QString)) , _searchTimer , SLOT(start())); - QToolButton* findNext = new QToolButton(this); - findNext->setObjectName(QLatin1String("find-next-button")); - findNext->setText(i18nc("@action:button Go to the next phrase", "Next")); - findNext->setIcon(KIcon("go-down-search")); - findNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - findNext->setToolTip(i18nc("@info:tooltip", "Find the next match for the current search phrase")); - connect(findNext , SIGNAL(clicked()) , this , SIGNAL(findNextClicked())); + _findNextButton = new QToolButton(this); + _findNextButton->setObjectName(QLatin1String("find-next-button")); + _findNextButton->setText(i18nc("@action:button Go to the next phrase", "Next")); + _findNextButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + _findNextButton->setToolTip(i18nc("@info:tooltip", "Find the next match for the current search phrase")); + connect(_findNextButton , SIGNAL(clicked()) , this , SIGNAL(findNextClicked())); - QToolButton* findPrev = new QToolButton(this); - findPrev->setObjectName(QLatin1String("find-previous-button")); - findPrev->setText(i18nc("@action:button Go to the previous phrase", "Previous")); - findPrev->setIcon(KIcon("go-up-search")); - findPrev->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - findPrev->setToolTip(i18nc("@info:tooltip", "Find the previous match for the current search phrase")); - connect(findPrev , SIGNAL(clicked()) , this , SIGNAL(findPreviousClicked())); + _findPreviousButton = new QToolButton(this); + _findPreviousButton->setObjectName(QLatin1String("find-previous-button")); + _findPreviousButton->setText(i18nc("@action:button Go to the previous phrase", "Previous")); + _findPreviousButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + _findPreviousButton->setToolTip(i18nc("@info:tooltip", "Find the previous match for the current search phrase")); + connect(_findPreviousButton , SIGNAL(clicked()) , this , SIGNAL(findPreviousClicked())); + + + _searchFromButton = new QToolButton(this); + _searchFromButton->setObjectName(QLatin1String("search-from-button")); + connect(_searchFromButton , SIGNAL(clicked()) , this , SIGNAL(searchFromClicked())); QToolButton* optionsButton = new QToolButton(this); optionsButton->setObjectName(QLatin1String("find-options-button")); @@ -102,8 +109,9 @@ IncrementalSearchBar::IncrementalSearchBar(QWidget* aParent) barLayout->addWidget(closeButton); barLayout->addWidget(findLabel); barLayout->addWidget(_searchEdit); - barLayout->addWidget(findNext); - barLayout->addWidget(findPrev); + barLayout->addWidget(_findNextButton); + barLayout->addWidget(_findPreviousButton); + barLayout->addWidget(_searchFromButton); barLayout->addWidget(optionsButton); // Fill the options menu @@ -128,16 +136,43 @@ IncrementalSearchBar::IncrementalSearchBar(QWidget* aParent) connect(_highlightMatches, SIGNAL(toggled(bool)), this, SIGNAL(highlightMatchesToggled(bool))); + _reverseSearch = optionsMenu->addAction(i18n("Search backwards")); + _reverseSearch->setCheckable(true); + _reverseSearch->setToolTip(i18n("Sets whether search should start from the bottom")); + _reverseSearch->setChecked(true); + connect(_reverseSearch, SIGNAL(toggled(bool)), + this, SLOT(updateButtonsAccordingToReverseSearchSetting())); + updateButtonsAccordingToReverseSearchSetting(); + barLayout->addStretch(); barLayout->setContentsMargins(4, 4, 4, 4); setLayout(barLayout); } + void IncrementalSearchBar::notifySearchChanged() { emit searchChanged(searchText()); } + +void IncrementalSearchBar::updateButtonsAccordingToReverseSearchSetting() +{ + Q_ASSERT(_reverseSearch); + if (_reverseSearch->isChecked()) { + _searchFromButton->setText(i18nc("@action:button Search from bottom", "From bottom")); + _searchFromButton->setToolTip(i18n("Search for the current search phrase from the bottom")); + _findNextButton->setIcon(KIcon("go-up-search")); + _findPreviousButton->setIcon(KIcon("go-down-search")); + } else { + _searchFromButton->setText(i18nc("@action:button Search from top", "From top")); + _searchFromButton->setToolTip(i18n("Search for the current search phrase from the top")); + _findNextButton->setIcon(KIcon("go-down-search")); + _findPreviousButton->setIcon(KIcon("go-up-search")); + } + +} + QString IncrementalSearchBar::searchText() { return _searchEdit->text(); @@ -161,12 +196,17 @@ bool IncrementalSearchBar::eventFilter(QObject* watched , QEvent* aEvent) } if (keyEvent->key() == Qt::Key_Return && !keyEvent->modifiers()) { - emit searchReturnPressed(_searchEdit->text()); + _findNextButton->click(); return true; } if ((keyEvent->key() == Qt::Key_Return) && (keyEvent->modifiers() == Qt::ShiftModifier)) { - emit searchShiftPlusReturnPressed(); + _findPreviousButton->click(); + return true; + } + + if ((keyEvent->key() == Qt::Key_Return) && (keyEvent->modifiers() == Qt::ControlModifier)) { + _searchFromButton->click(); return true; } } @@ -180,9 +220,7 @@ void IncrementalSearchBar::setVisible(bool visible) QWidget::setVisible(visible); if (visible) { - //TODO - Check if this is the correct reason value to use here - _searchEdit->setFocus(Qt::ActiveWindowFocusReason); - _searchEdit->selectAll(); + focusLineEdit(); } } @@ -212,13 +250,20 @@ void IncrementalSearchBar::clearLineEdit() _searchEdit->setStyleSheet(QString()); } +void IncrementalSearchBar::focusLineEdit() +{ + _searchEdit->setFocus(Qt::ActiveWindowFocusReason); + _searchEdit->selectAll(); +} + const QBitArray IncrementalSearchBar::optionsChecked() { - QBitArray options(3, 0); + QBitArray options(4, 0); if (_caseSensitive->isChecked()) options.setBit(MatchCase); if (_regExpression->isChecked()) options.setBit(RegExp); if (_highlightMatches->isChecked()) options.setBit(HighlightMatches); + if (_reverseSearch->isChecked()) options.setBit(ReverseSearch); return options; } diff --git a/src/IncrementalSearchBar.h b/src/IncrementalSearchBar.h index d0661a5ae..44be26c07 100644 --- a/src/IncrementalSearchBar.h +++ b/src/IncrementalSearchBar.h @@ -28,6 +28,7 @@ class QAction; class QLabel; class QTimer; class KLineEdit; +class QToolButton; namespace Konsole { @@ -66,7 +67,9 @@ public: /** Searches are case-sensitive or not */ MatchCase = 1, /** Searches use regular expressions */ - RegExp = 2 + RegExp = 2, + /** Search from the bottom and up **/ + ReverseSearch = 3 }; /** @@ -95,6 +98,8 @@ public: void setSearchText(const QString& text); + void focusLineEdit(); + // reimplemented virtual void setVisible(bool visible); signals: @@ -104,6 +109,8 @@ signals: void findNextClicked(); /** Emitted when the user clicks the button to find the previous match */ void findPreviousClicked(); + /** The search from beginning/end button */ + void searchFromClicked(); /** * Emitted when the user toggles the checkbox to indicate whether * matches for the search text should be highlighted @@ -134,12 +141,17 @@ public slots: private slots: void notifySearchChanged(); + void updateButtonsAccordingToReverseSearchSetting(); private: KLineEdit* _searchEdit; QAction* _caseSensitive; QAction* _regExpression; QAction* _highlightMatches; + QAction* _reverseSearch; + QToolButton* _findNextButton; + QToolButton* _findPreviousButton; + QToolButton* _searchFromButton; QTimer* _searchTimer; }; diff --git a/src/ScreenWindow.cpp b/src/ScreenWindow.cpp index 92804302c..e2bf5c145 100644 --- a/src/ScreenWindow.cpp +++ b/src/ScreenWindow.cpp @@ -32,10 +32,12 @@ ScreenWindow::ScreenWindow(QObject* parent) , _bufferNeedsUpdate(true) , _windowLines(1) , _currentLine(0) + , _currentResultLine(-1) , _trackOutput(true) , _scrollCount(0) { } + ScreenWindow::~ScreenWindow() { delete[] _windowBuffer; @@ -211,6 +213,21 @@ int ScreenWindow::currentLine() const return qBound(0, _currentLine, lineCount() - windowLines()); } +int ScreenWindow::currentResultLine() const +{ + return _currentResultLine; +} + +void ScreenWindow::setCurrentResultLine(int line) +{ + if (_currentResultLine == line) { + return; + } + + _currentResultLine = line; + emit currentResultLineChanged(); +} + void ScreenWindow::scrollBy(RelativeScrollMode mode, int amount, bool fullPage) { if (mode == ScrollLines) { diff --git a/src/ScreenWindow.h b/src/ScreenWindow.h index 89fe7bed7..22b32ea76 100644 --- a/src/ScreenWindow.h +++ b/src/ScreenWindow.h @@ -113,6 +113,13 @@ public: */ QRect scrollRegion() const; + + /** + * What line the next search will start from + */ + void setCurrentResultLine(int line); + int currentResultLine() const; + /** * Sets the start of the selection to the given @p line and @p column within * the window. @@ -241,6 +248,8 @@ signals: */ void outputChanged(); + void currentResultLineChanged(); + /** * Emitted when the screen window is scrolled to a different position. * @@ -262,6 +271,7 @@ private: int _windowLines; int _currentLine; // see scrollTo() , currentLine() + int _currentResultLine; bool _trackOutput; // see setTrackOutput() , trackOutput() int _scrollCount; // count of lines which the window has been scrolled by since // the last call to resetScrollCount() diff --git a/src/SessionController.cpp b/src/SessionController.cpp index 88fc50c6a..d7745bcfb 100644 --- a/src/SessionController.cpp +++ b/src/SessionController.cpp @@ -112,6 +112,8 @@ SessionController::SessionController(Session* session , TerminalDisplay* view, Q , _findNextAction(0) , _findPreviousAction(0) , _urlFilterUpdateRequired(false) + , _searchStartLine(0) + , _prevSearchResultLine(0) , _searchBar(0) , _codecAction(0) , _switchProfileMenu(0) @@ -526,6 +528,7 @@ void SessionController::setSearchBar(IncrementalSearchBar* searchBar) _searchBar = searchBar; if (_searchBar) { connect(_searchBar, SIGNAL(closeClicked()), this, SLOT(searchClosed())); + connect(_searchBar, SIGNAL(searchFromClicked()), this, SLOT(searchFrom())); connect(_searchBar, SIGNAL(findNextClicked()), this, SLOT(findNextInHistory())); connect(_searchBar, SIGNAL(findPreviousClicked()), this, SLOT(findPreviousInHistory())); connect(_searchBar, SIGNAL(highlightMatchesToggled(bool)) , this , SLOT(highlightMatches(bool))); @@ -1084,6 +1087,17 @@ void SessionController::searchClosed() searchHistory(false); } +void SessionController::setSearchStartToWindowCurrentLine() +{ + setSearchStartTo(-1); +} + +void SessionController::setSearchStartTo(int line) +{ + _searchStartLine = line; + _prevSearchResultLine = line; +} + void SessionController::listenForScreenWindowUpdates() { if (_listenForScreenWindowUpdates) @@ -1093,6 +1107,8 @@ void SessionController::listenForScreenWindowUpdates() SLOT(updateSearchFilter())); connect(_view->screenWindow(), SIGNAL(scrolled(int)), this, SLOT(updateSearchFilter())); + connect(_view->screenWindow(), SIGNAL(currentResultLineChanged()), _view, + SLOT(update())); _listenForScreenWindowUpdates = true; } @@ -1106,9 +1122,12 @@ void SessionController::updateSearchFilter() void SessionController::searchBarEvent() { + QString selectedText = _view->screenWindow()->selectedText(true, true); + if (!selectedText.isEmpty()) + _searchBar->setSearchText(selectedText); + if (_searchBar->isVisible()) { - // refresh focus - _searchBar->setVisible(true); + _searchBar->focusLineEdit(); } else { searchHistory(true); _isSearchBarEnabled = true; @@ -1119,10 +1138,13 @@ void SessionController::enableSearchBar(bool showSearchBar) { if (!_searchBar) return; + + if (showSearchBar && !_searchBar->isVisible()) { + setSearchStartToWindowCurrentLine(); + } + _searchBar->setVisible(showSearchBar); if (showSearchBar) { - _searchBar->clearLineEdit(); - _searchBar->setSearchText(_searchText); connect(_searchBar, SIGNAL(searchChanged(QString)), this, SLOT(searchTextChanged(QString))); connect(_searchBar, SIGNAL(searchReturnPressed(QString)), this, @@ -1136,9 +1158,32 @@ void SessionController::enableSearchBar(bool showSearchBar) SLOT(findPreviousInHistory())); disconnect(_searchBar, SIGNAL(searchShiftPlusReturnPressed()), this, SLOT(findNextInHistory())); + if (_view && _view->screenWindow()) { + _view->screenWindow()->setCurrentResultLine(-1); + } } } + +bool SessionController::reverseSearchChecked() const +{ + Q_ASSERT(_searchBar); + + QBitArray options = _searchBar->optionsChecked(); + return options.at(IncrementalSearchBar::ReverseSearch); +} + +QRegExp SessionController::regexpFromSearchBarOptions() +{ + QBitArray options = _searchBar->optionsChecked(); + + Qt::CaseSensitivity caseHandling = options.at(IncrementalSearchBar::MatchCase) ? Qt::CaseSensitive : Qt::CaseInsensitive; + QRegExp::PatternSyntax syntax = options.at(IncrementalSearchBar::RegExp) ? QRegExp::RegExp : QRegExp::FixedString; + + QRegExp regExp(_searchBar->searchText(), caseHandling , syntax); + return regExp; +} + // searchHistory() may be called either as a result of clicking a menu item or // as a result of changing the search bar widget void SessionController::searchHistory(bool showSearchBar) @@ -1152,13 +1197,9 @@ void SessionController::searchHistory(bool showSearchBar) listenForScreenWindowUpdates(); _searchFilter = new RegExpFilter(); + _searchFilter->setRegExp(regexpFromSearchBarOptions()); _view->filterChain()->addFilter(_searchFilter); - - // invoke search for matches for the current search text - const QString& currentSearchText = _searchBar->searchText(); - if (!currentSearchText.isEmpty()) { - searchTextChanged(currentSearchText); - } + _view->processFilters(); setFindNextPrevEnabled(true); } else { @@ -1170,6 +1211,7 @@ void SessionController::searchHistory(bool showSearchBar) } } } + void SessionController::setFindNextPrevEnabled(bool enabled) { _findNextAction->setEnabled(enabled); @@ -1184,15 +1226,19 @@ void SessionController::searchTextChanged(const QString& text) _searchText = text; - if (text.isEmpty()) + if (text.isEmpty()) { _view->screenWindow()->clearSelection(); + _view->screenWindow()->scrollTo(_searchStartLine); + } // update search. this is called even when the text is // empty to clear the view's filters - beginSearch(text , SearchHistoryTask::BackwardsSearch); + beginSearch(text , reverseSearchChecked() ? SearchHistoryTask::BackwardsSearch : SearchHistoryTask::ForwardsSearch); } void SessionController::searchCompleted(bool success) { + _prevSearchResultLine = _view->screenWindow()->currentResultLine(); + if (_searchBar) _searchBar->setFoundMatch(success); } @@ -1202,15 +1248,19 @@ void SessionController::beginSearch(const QString& text , int direction) Q_ASSERT(_searchBar); Q_ASSERT(_searchFilter); - QBitArray options = _searchBar->optionsChecked(); - - Qt::CaseSensitivity caseHandling = options.at(IncrementalSearchBar::MatchCase) ? Qt::CaseSensitive : Qt::CaseInsensitive; - QRegExp::PatternSyntax syntax = options.at(IncrementalSearchBar::RegExp) ? QRegExp::RegExp : QRegExp::FixedString; - - QRegExp regExp(text , caseHandling , syntax); + QRegExp regExp = regexpFromSearchBarOptions(); _searchFilter->setRegExp(regExp); + if (_searchStartLine == -1) { + if (direction == SearchHistoryTask::ForwardsSearch) { + setSearchStartTo(_view->screenWindow()->currentLine()); + } else { + setSearchStartTo(_view->screenWindow()->currentLine() + _view->screenWindow()->windowLines()); + } + } + if (!regExp.isEmpty()) { + _view->screenWindow()->setCurrentResultLine(-1); SearchHistoryTask* task = new SearchHistoryTask(this); connect(task, SIGNAL(completed(bool)), this, SLOT(searchCompleted(bool))); @@ -1218,6 +1268,7 @@ void SessionController::beginSearch(const QString& text , int direction) task->setRegExp(regExp); task->setSearchDirection((SearchHistoryTask::SearchDirection)direction); task->setAutoDelete(true); + task->setStartLine(_searchStartLine); task->addScreenWindow(_session , _view->screenWindow()); task->execute(); } else if (text.isEmpty()) { @@ -1237,19 +1288,38 @@ void SessionController::highlightMatches(bool highlight) _view->update(); } + +void SessionController::searchFrom() +{ + Q_ASSERT(_searchBar); + Q_ASSERT(_searchFilter); + + if (reverseSearchChecked()) { + setSearchStartTo(_view->screenWindow()->lineCount()); + } else { + setSearchStartTo(0); + } + + + beginSearch(_searchBar->searchText(), reverseSearchChecked() ? SearchHistoryTask::BackwardsSearch : SearchHistoryTask::ForwardsSearch); +} void SessionController::findNextInHistory() { Q_ASSERT(_searchBar); Q_ASSERT(_searchFilter); - beginSearch(_searchBar->searchText(), SearchHistoryTask::ForwardsSearch); + setSearchStartTo(_prevSearchResultLine); + + beginSearch(_searchBar->searchText(), reverseSearchChecked() ? SearchHistoryTask::BackwardsSearch : SearchHistoryTask::ForwardsSearch); } void SessionController::findPreviousInHistory() { Q_ASSERT(_searchBar); Q_ASSERT(_searchFilter); - beginSearch(_searchBar->searchText(), SearchHistoryTask::BackwardsSearch); + setSearchStartTo(_prevSearchResultLine); + + beginSearch(_searchBar->searchText(), reverseSearchChecked() ? SearchHistoryTask::ForwardsSearch : SearchHistoryTask::BackwardsSearch); } void SessionController::changeSearchMatch() { @@ -1258,7 +1328,7 @@ void SessionController::changeSearchMatch() // reset Selection for new case match _view->screenWindow()->clearSelection(); - beginSearch(_searchBar->searchText(), SearchHistoryTask::BackwardsSearch); + beginSearch(_searchBar->searchText(), reverseSearchChecked() ? SearchHistoryTask::BackwardsSearch : SearchHistoryTask::ForwardsSearch); } void SessionController::showHistoryOptions() { @@ -1734,18 +1804,20 @@ void SearchHistoryTask::executeOnScreenWindow(SessionPtr session , ScreenWindowP Emulation* emulation = session->emulation(); - int selectionColumn = 0; - int selectionLine = 0; - - window->getSelectionEnd(selectionColumn , selectionLine); - if (!_regExp.isEmpty()) { int pos = -1; const bool forwards = (_direction == ForwardsSearch); - int startLine = selectionLine + window->currentLine() + (forwards ? 1 : -1); - // Temporary fix for #205495 - if (startLine < 0) startLine = 0; const int lastLine = window->lineCount() - 1; + + int startLine; + if (forwards && (_startLine == lastLine)) { + startLine = 0; + } else if (!forwards && (_startLine == 0)) { + startLine = lastLine; + } else { + startLine = _startLine + (forwards ? 1 : -1); + } + QString string; //text stream to read history into string for pattern or regular expression searching @@ -1852,22 +1924,35 @@ void SearchHistoryTask::highlightResult(ScreenWindowPtr window , int findPos) //kDebug() << "Found result at line " << findPos; //update display to show area of history containing selection - window->scrollTo(findPos); - window->setSelectionStart(0 , findPos - window->currentLine() , false); - window->setSelectionEnd(window->columnCount() , findPos - window->currentLine()); + if ((findPos < window->currentLine()) || + (findPos >= (window->currentLine() + window->windowLines()))) { + int centeredScrollPos = findPos - window->windowLines() / 2; + if (centeredScrollPos < 0) { + centeredScrollPos = 0; + } + + window->scrollTo(centeredScrollPos); + } + window->setTrackOutput(false); window->notifyOutputChanged(); + window->setCurrentResultLine(findPos); } SearchHistoryTask::SearchHistoryTask(QObject* parent) : SessionTask(parent) , _direction(BackwardsSearch) + , _startLine(0) { } void SearchHistoryTask::setSearchDirection(SearchDirection direction) { _direction = direction; } +void SearchHistoryTask::setStartLine(int line) +{ + _startLine = line; +} SearchHistoryTask::SearchDirection SearchHistoryTask::searchDirection() const { return _direction; diff --git a/src/SessionController.h b/src/SessionController.h index 036e05349..b061e70de 100644 --- a/src/SessionController.h +++ b/src/SessionController.h @@ -126,6 +126,13 @@ public: */ bool isValid() const; + /** Set the start line from which the next search will be done **/ + void setSearchStartTo(int line); + + /** set start line to the first or last line (depending on the reverse search + * setting) in the terminal display **/ + void setSearchStartToWindowCurrentLine(); + /** * Sets the widget used for searches through the session's output. * @@ -228,6 +235,7 @@ private slots: void enableSearchBar(bool showSearchBar); void searchHistory(bool showSearchBar); void searchBarEvent(); + void searchFrom(); void findNextInHistory(); void findPreviousInHistory(); void changeSearchMatch(); @@ -286,6 +294,8 @@ private: // direction - value from SearchHistoryTask::SearchDirection enum to specify // the search direction void beginSearch(const QString& text , int direction); + QRegExp regexpFromSearchBarOptions(); + bool reverseSearchChecked() const; void setupCommonActions(); void setupExtraActions(); void removeSearchFilter(); // remove and delete the current search filter if set @@ -318,6 +328,8 @@ private: bool _urlFilterUpdateRequired; + int _searchStartLine; + int _prevSearchResultLine; QPointer _searchBar; KCodecAction* _codecAction; @@ -496,6 +508,9 @@ public: /** Returns the current search direction. See setSearchDirection(). */ SearchDirection searchDirection() const; + /** The line from which the search will be done **/ + void setStartLine(int startLine); + /** * Performs a search through the session's history, starting at the position * of the current selection, in the direction specified by setSearchDirection(). @@ -517,6 +532,7 @@ private: QMap< SessionPtr , ScreenWindowPtr > _windows; QRegExp _regExp; SearchDirection _direction; + int _startLine; //static QPointer _thread; }; diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp index acfddc176..9ec92aa34 100644 --- a/src/TerminalDisplay.cpp +++ b/src/TerminalDisplay.cpp @@ -116,6 +116,7 @@ void TerminalDisplay::setScreenWindow(ScreenWindow* window) if (_screenWindow) { connect(_screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateLineProperties())); connect(_screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateImage())); + connect(_screenWindow , SIGNAL(currentResultLineChanged()) , this , SLOT(updateImage())); _screenWindow->setWindowLines(_lines); } } @@ -358,6 +359,8 @@ TerminalDisplay::TerminalDisplay(QWidget* parent) _scrollBar->setCursor(Qt::ArrowCursor); connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); + connect(_scrollBar, SIGNAL(sliderMoved(int)), + this, SLOT(viewScrolledByUser())); // setup timers for blinking text _blinkTextTimer = new QTimer(this); @@ -1169,6 +1172,7 @@ void TerminalDisplay::paintEvent(QPaintEvent* pe) true /* use opacity setting */); drawContents(paint, rect); } + drawCurrentResultRect(paint); drawInputMethodPreeditString(paint, preeditRect()); paintFilters(paint); } @@ -1310,7 +1314,9 @@ void TerminalDisplay::paintFilters(QPainter& painter) // drawn on top of them } else if (spot->type() == Filter::HotSpot::Marker) { //TODO - Do not use a hardcoded color for this - painter.fillRect(r, QBrush(QColor(255, 0, 0, 120))); + const bool isCurrentResultLine = (_screenWindow->currentResultLine() == (spot->startLine() + _screenWindow->currentLine())); + QColor color = isCurrentResultLine ? QColor(255, 255, 0, 120) : QColor(255, 0, 0, 120); + painter.fillRect(r, color); } } } @@ -1473,6 +1479,17 @@ void TerminalDisplay::drawContents(QPainter& paint, const QRect& rect) } } +void TerminalDisplay::drawCurrentResultRect(QPainter& painter) +{ + if(_screenWindow->currentResultLine() == -1) { + return; + } + + QRect r(0, (_screenWindow->currentResultLine() - _screenWindow->currentLine())*_fontHeight, + contentsRect().width(), _fontHeight); + painter.fillRect(r, QColor(0, 0, 255, 80)); +} + QRect TerminalDisplay::imageToWidget(const QRect& imageArea) const { QRect result; @@ -2458,6 +2475,7 @@ void TerminalDisplay::wheelEvent(QWheelEvent* ev) const bool canScroll = _scrollBar->maximum() > 0; if (canScroll) { _scrollBar->event(ev); + _sessionController->setSearchStartToWindowCurrentLine(); } else { // assume that each Up / Down key event will cause the terminal application // to scroll by one line. @@ -2494,6 +2512,11 @@ void TerminalDisplay::tripleClickTimeout() _possibleTripleClick = false; } +void TerminalDisplay::viewScrolledByUser() +{ + _sessionController->setSearchStartToWindowCurrentLine(); +} + void TerminalDisplay::mouseTripleClickEvent(QMouseEvent* ev) { if (!_screenWindow) return; @@ -2832,6 +2855,7 @@ void TerminalDisplay::scrollScreenWindow(enum ScreenWindow::RelativeScrollMode m _screenWindow->setTrackOutput(_screenWindow->atEndOfOutput()); updateLineProperties(); updateImage(); + viewScrolledByUser(); } void TerminalDisplay::keyPressEvent(QKeyEvent* event) diff --git a/src/TerminalDisplay.h b/src/TerminalDisplay.h index 100ffccc3..ad60cf985 100644 --- a/src/TerminalDisplay.h +++ b/src/TerminalDisplay.h @@ -668,6 +668,7 @@ private slots: void unmaskBell(); void swapFGBGColors(); void tripleClickTimeout(); // resets possibleTripleClick + void viewScrolledByUser(); /** * Called from the drag-and-drop popup. Causes the dropped URLs to be pasted as text. @@ -684,6 +685,8 @@ private: // drawTextFragment() or drawPrinterFriendlyTextFragment() // to draw the fragments void drawContents(QPainter& painter, const QRect& rect); + // draw a transparent rectangle over the line of the current match + void drawCurrentResultRect(QPainter& painter); // draws a section of text, all the text in this section // has a common color and style void drawTextFragment(QPainter& painter, const QRect& rect,