/* Copyright 2006-2008 by Robert Knight This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Own #include "IncrementalSearchBar.h" // Qt #include #include #include #include #include #include #include // KDE #include #include #include #include using namespace Konsole; IncrementalSearchBar::IncrementalSearchBar(Features features , QWidget* parent) : QWidget(parent) , _foundMatch(false) , _matchCaseBox(0) , _matchRegExpBox(0) , _highlightBox(0) , _searchEdit(0) , _continueLabel(0) { QHBoxLayout* layout = new QHBoxLayout(this); QToolButton* close = new QToolButton(this); close->setObjectName( QLatin1String("close-button" )); close->setToolTip( i18n("Close the search bar") ); close->setAutoRaise(true); close->setIcon(KIcon("dialog-close")); connect( close , SIGNAL(clicked()) , this , SIGNAL(closeClicked()) ); QLabel* findLabel = new QLabel(i18n("Find:"),this); _searchEdit = new KLineEdit(this); _searchEdit->setClearButtonShown(true); _searchEdit->installEventFilter(this); _searchEdit->setObjectName( QLatin1String("search-edit" )); _searchEdit->setToolTip( i18n("Enter the text to search for here") ); // text box may be a minimum of 6 characters wide and a maximum of 10 characters wide // (since the maxWidth metric is used here, more characters probably will fit in than 6 // and 10) QFontMetrics metrics(_searchEdit->font()); int maxWidth = metrics.maxWidth(); _searchEdit->setMinimumWidth(maxWidth*6); _searchEdit->setMaximumWidth(maxWidth*10); _searchTimer = new QTimer(this); _searchTimer->setInterval(250); _searchTimer->setSingleShot(true); connect( _searchTimer , SIGNAL(timeout()) , this , SLOT(notifySearchChanged()) ); connect( _searchEdit , SIGNAL(clearButtonClicked()) , this , SLOT(clearLineEdit()) ); connect( _searchEdit , SIGNAL(textChanged(const 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->setAutoRaise(true); findNext->setIcon( KIcon("go-down-search") ); findNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); findNext->setToolTip( i18n("Find the next match for the current search phrase") ); connect( findNext , 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->setAutoRaise(true); findPrev->setIcon( KIcon("go-up-search") ); findPrev->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); findPrev->setToolTip( i18n("Find the previous match for the current search phrase") ); connect( findPrev , SIGNAL(clicked()) , this , SIGNAL(findPreviousClicked()) ); if ( features & HighlightMatches ) { _highlightBox = new QCheckBox( i18n("Highlight all") , this ); _highlightBox->setObjectName( QLatin1String("highlight-matches-box" )); _highlightBox->setToolTip( i18n("Sets whether matching text should be highlighted") ); _highlightBox->setChecked(true); connect( _highlightBox , SIGNAL(toggled(bool)) , this , SIGNAL(highlightMatchesToggled(bool)) ); } if ( features & MatchCase ) { _matchCaseBox = new QCheckBox( i18n("Match case") , this ); _matchCaseBox->setObjectName( QLatin1String("match-case-box" )); _matchCaseBox->setToolTip( i18n("Sets whether the search is case sensitive") ); connect( _matchCaseBox , SIGNAL(toggled(bool)) , this , SIGNAL(matchCaseToggled(bool)) ); } if ( features & RegExp ) { _matchRegExpBox = new QCheckBox( i18n("Match regular expression") , this ); _matchRegExpBox->setObjectName( QLatin1String("match-regexp-box" )); _matchRegExpBox->setToolTip( i18n("Sets whether the search phrase is interpreted as normal text or" " as a regular expression") ); connect( _matchRegExpBox , SIGNAL(toggled(bool)) , this , SIGNAL(matchRegExpToggled(bool)) ); } QProgressBar* _progress = new QProgressBar(this); _progress->setMinimum(0); _progress->setMaximum(0); _progress->setVisible(false); QLabel* _continueLabel = new QLabel(this); _continueLabel->setVisible(false); layout->addWidget(close); layout->addWidget(findLabel); layout->addWidget(_searchEdit); layout->addWidget(findNext); layout->addWidget(findPrev); // optional features if ( features & HighlightMatches ) layout->addWidget(_highlightBox); if ( features & MatchCase ) layout->addWidget(_matchCaseBox); if ( features & RegExp ) layout->addWidget(_matchRegExpBox); layout->addWidget(_progress); layout->addWidget(_continueLabel); layout->addStretch(); layout->setContentsMargins(4, 4, 4, 4); setLayout(layout); } void IncrementalSearchBar::notifySearchChanged() { emit searchChanged( searchText() ); } QString IncrementalSearchBar::searchText() { return _searchEdit->text(); } bool IncrementalSearchBar::highlightMatches() { if ( !_highlightBox ) { return true; } else { return _highlightBox->isChecked(); } } bool IncrementalSearchBar::matchCase() { if ( !_matchCaseBox ) { return false; } else { return _matchCaseBox->isChecked(); } } bool IncrementalSearchBar::matchRegExp() { if ( !_matchRegExpBox ) { return false; } else { return _matchRegExpBox->isChecked(); } } bool IncrementalSearchBar::eventFilter(QObject* watched , QEvent* event) { if ( watched == _searchEdit ) { if ( event->type() == QEvent::KeyPress ) { QKeyEvent* keyEvent = static_cast(event); if ( keyEvent->key() == Qt::Key_Escape ) { emit closeClicked(); return true; } } } return QWidget::eventFilter(watched,event); } 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(); } } void IncrementalSearchBar::setFoundMatch( bool match ) { if ( !match && !_searchEdit->text().isEmpty() ) { KStatefulBrush backgroundBrush(KColorScheme::View,KColorScheme::NegativeBackground); QString styleSheet = QString("QLineEdit{ background-color:%1 }") .arg(backgroundBrush.brush(_searchEdit).color().name()); _searchEdit->setStyleSheet( styleSheet ); } else { _searchEdit->setStyleSheet( QString() ); } } void IncrementalSearchBar::setContinueFlag( Continue flag ) { if ( flag == ContinueFromTop ) { _continueLabel->setText( i18n("Search reached bottom, continued from top.") ); _continueLabel->show(); } else if ( flag == ContinueFromBottom ) { _continueLabel->setText( i18n("Search reached top, continued from bottom.") ); _continueLabel->show(); } else if ( flag == ClearContinue ) { _continueLabel->hide(); } } void IncrementalSearchBar::clearLineEdit() { _searchEdit->setStyleSheet( QString() ); } #include "IncrementalSearchBar.moc"