1*bb02e0acSNicolas Bonnefon /* 2*bb02e0acSNicolas Bonnefon * Copyright (C) 2010, 2013 Nicolas Bonnefon and other contributors 3*bb02e0acSNicolas Bonnefon * 4*bb02e0acSNicolas Bonnefon * This file is part of glogg. 5*bb02e0acSNicolas Bonnefon * 6*bb02e0acSNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify 7*bb02e0acSNicolas Bonnefon * it under the terms of the GNU General Public License as published by 8*bb02e0acSNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or 9*bb02e0acSNicolas Bonnefon * (at your option) any later version. 10*bb02e0acSNicolas Bonnefon * 11*bb02e0acSNicolas Bonnefon * glogg is distributed in the hope that it will be useful, 12*bb02e0acSNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*bb02e0acSNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*bb02e0acSNicolas Bonnefon * GNU General Public License for more details. 15*bb02e0acSNicolas Bonnefon * 16*bb02e0acSNicolas Bonnefon * You should have received a copy of the GNU General Public License 17*bb02e0acSNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>. 18*bb02e0acSNicolas Bonnefon */ 19*bb02e0acSNicolas Bonnefon 20*bb02e0acSNicolas Bonnefon #include "log.h" 21*bb02e0acSNicolas Bonnefon 22*bb02e0acSNicolas Bonnefon #include <QToolButton> 23*bb02e0acSNicolas Bonnefon #include <QLabel> 24*bb02e0acSNicolas Bonnefon #include <QCheckBox> 25*bb02e0acSNicolas Bonnefon #include <QLineEdit> 26*bb02e0acSNicolas Bonnefon #include <QHBoxLayout> 27*bb02e0acSNicolas Bonnefon 28*bb02e0acSNicolas Bonnefon #include "configuration.h" 29*bb02e0acSNicolas Bonnefon #include "qfnotifications.h" 30*bb02e0acSNicolas Bonnefon 31*bb02e0acSNicolas Bonnefon #include "quickfindwidget.h" 32*bb02e0acSNicolas Bonnefon 33*bb02e0acSNicolas Bonnefon const int QuickFindWidget::NOTIFICATION_TIMEOUT = 5000; 34*bb02e0acSNicolas Bonnefon 35*bb02e0acSNicolas Bonnefon const QString QFNotification::REACHED_EOF = "Reached end of file, no occurence found."; 36*bb02e0acSNicolas Bonnefon const QString QFNotification::REACHED_BOF = "Reached beginning of file, no occurence found."; 37*bb02e0acSNicolas Bonnefon 38*bb02e0acSNicolas Bonnefon QuickFindWidget::QuickFindWidget( QWidget* parent ) : QWidget( parent ) 39*bb02e0acSNicolas Bonnefon { 40*bb02e0acSNicolas Bonnefon // ui_.setupUi( this ); 41*bb02e0acSNicolas Bonnefon // setFocusProxy(ui_.findEdit); 42*bb02e0acSNicolas Bonnefon // setProperty("topBorder", true); 43*bb02e0acSNicolas Bonnefon QHBoxLayout *layout = new QHBoxLayout( this ); 44*bb02e0acSNicolas Bonnefon 45*bb02e0acSNicolas Bonnefon layout->setMargin( 0 ); 46*bb02e0acSNicolas Bonnefon layout->setSpacing( 6 ); 47*bb02e0acSNicolas Bonnefon 48*bb02e0acSNicolas Bonnefon closeButton_ = setupToolButton( 49*bb02e0acSNicolas Bonnefon QLatin1String(""), QLatin1String( ":/images/darkclosebutton.png" ) ); 50*bb02e0acSNicolas Bonnefon layout->addWidget( closeButton_ ); 51*bb02e0acSNicolas Bonnefon 52*bb02e0acSNicolas Bonnefon editQuickFind_ = new QLineEdit( this ); 53*bb02e0acSNicolas Bonnefon // FIXME: set MinimumSize might be to constraining 54*bb02e0acSNicolas Bonnefon editQuickFind_->setMinimumSize( QSize( 150, 0 ) ); 55*bb02e0acSNicolas Bonnefon layout->addWidget( editQuickFind_ ); 56*bb02e0acSNicolas Bonnefon 57*bb02e0acSNicolas Bonnefon ignoreCaseCheck_ = new QCheckBox( "Ignore &case" ); 58*bb02e0acSNicolas Bonnefon layout->addWidget( ignoreCaseCheck_ ); 59*bb02e0acSNicolas Bonnefon 60*bb02e0acSNicolas Bonnefon previousButton_ = setupToolButton( QLatin1String("Previous"), 61*bb02e0acSNicolas Bonnefon QLatin1String( ":/images/arrowup.png" ) ); 62*bb02e0acSNicolas Bonnefon layout->addWidget( previousButton_ ); 63*bb02e0acSNicolas Bonnefon 64*bb02e0acSNicolas Bonnefon nextButton_ = setupToolButton( QLatin1String("Next"), 65*bb02e0acSNicolas Bonnefon QLatin1String( ":/images/arrowdown.png" ) ); 66*bb02e0acSNicolas Bonnefon layout->addWidget( nextButton_ ); 67*bb02e0acSNicolas Bonnefon 68*bb02e0acSNicolas Bonnefon notificationText_ = new QLabel( "" ); 69*bb02e0acSNicolas Bonnefon // FIXME: set MinimumSize might be too constraining 70*bb02e0acSNicolas Bonnefon int width = QFNotification::maxWidth( notificationText_ ); 71*bb02e0acSNicolas Bonnefon notificationText_->setMinimumSize( width, 0 ); 72*bb02e0acSNicolas Bonnefon layout->addWidget( notificationText_ ); 73*bb02e0acSNicolas Bonnefon 74*bb02e0acSNicolas Bonnefon setMinimumWidth( minimumSizeHint().width() ); 75*bb02e0acSNicolas Bonnefon 76*bb02e0acSNicolas Bonnefon // Behaviour 77*bb02e0acSNicolas Bonnefon connect( closeButton_, SIGNAL( clicked() ), SLOT( closeHandler() ) ); 78*bb02e0acSNicolas Bonnefon connect( editQuickFind_, SIGNAL( textEdited( QString ) ), 79*bb02e0acSNicolas Bonnefon this, SLOT( textChanged() ) ); 80*bb02e0acSNicolas Bonnefon connect( ignoreCaseCheck_, SIGNAL( stateChanged( int ) ), 81*bb02e0acSNicolas Bonnefon this, SLOT( textChanged() ) ); 82*bb02e0acSNicolas Bonnefon /* 83*bb02e0acSNicolas Bonnefon connect( editQuickFind_. SIGNAL( textChanged( QString ) ), this, 84*bb02e0acSNicolas Bonnefon SLOT( updateButtons() ) ); 85*bb02e0acSNicolas Bonnefon */ 86*bb02e0acSNicolas Bonnefon connect( editQuickFind_, SIGNAL( returnPressed() ), 87*bb02e0acSNicolas Bonnefon this, SLOT( returnHandler() ) ); 88*bb02e0acSNicolas Bonnefon connect( previousButton_, SIGNAL( clicked() ), 89*bb02e0acSNicolas Bonnefon this, SLOT( doSearchBackward() ) ); 90*bb02e0acSNicolas Bonnefon connect( nextButton_, SIGNAL( clicked() ), 91*bb02e0acSNicolas Bonnefon this, SLOT( doSearchForward() ) ); 92*bb02e0acSNicolas Bonnefon 93*bb02e0acSNicolas Bonnefon // Notification timer: 94*bb02e0acSNicolas Bonnefon notificationTimer_ = new QTimer( this ); 95*bb02e0acSNicolas Bonnefon notificationTimer_->setSingleShot( true ); 96*bb02e0acSNicolas Bonnefon connect( notificationTimer_, SIGNAL( timeout() ), 97*bb02e0acSNicolas Bonnefon this, SLOT( notificationTimeout() ) ); 98*bb02e0acSNicolas Bonnefon } 99*bb02e0acSNicolas Bonnefon 100*bb02e0acSNicolas Bonnefon void QuickFindWidget::userActivate() 101*bb02e0acSNicolas Bonnefon { 102*bb02e0acSNicolas Bonnefon userRequested_ = true; 103*bb02e0acSNicolas Bonnefon QWidget::show(); 104*bb02e0acSNicolas Bonnefon editQuickFind_->setFocus( Qt::ShortcutFocusReason ); 105*bb02e0acSNicolas Bonnefon } 106*bb02e0acSNicolas Bonnefon 107*bb02e0acSNicolas Bonnefon // 108*bb02e0acSNicolas Bonnefon // SLOTS 109*bb02e0acSNicolas Bonnefon // 110*bb02e0acSNicolas Bonnefon 111*bb02e0acSNicolas Bonnefon void QuickFindWidget::changeDisplayedPattern( const QString& newPattern ) 112*bb02e0acSNicolas Bonnefon { 113*bb02e0acSNicolas Bonnefon editQuickFind_->setText( newPattern ); 114*bb02e0acSNicolas Bonnefon } 115*bb02e0acSNicolas Bonnefon 116*bb02e0acSNicolas Bonnefon void QuickFindWidget::notify( const QFNotification& message ) 117*bb02e0acSNicolas Bonnefon { 118*bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindWidget::notify()"; 119*bb02e0acSNicolas Bonnefon 120*bb02e0acSNicolas Bonnefon notificationText_->setText( message.message() ); 121*bb02e0acSNicolas Bonnefon QWidget::show(); 122*bb02e0acSNicolas Bonnefon notificationTimer_->start( NOTIFICATION_TIMEOUT ); 123*bb02e0acSNicolas Bonnefon } 124*bb02e0acSNicolas Bonnefon 125*bb02e0acSNicolas Bonnefon void QuickFindWidget::clearNotification() 126*bb02e0acSNicolas Bonnefon { 127*bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindWidget::clearNotification()"; 128*bb02e0acSNicolas Bonnefon 129*bb02e0acSNicolas Bonnefon notificationText_->setText( "" ); 130*bb02e0acSNicolas Bonnefon } 131*bb02e0acSNicolas Bonnefon 132*bb02e0acSNicolas Bonnefon // User clicks forward arrow 133*bb02e0acSNicolas Bonnefon void QuickFindWidget::doSearchForward() 134*bb02e0acSNicolas Bonnefon { 135*bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindWidget::doSearchForward()"; 136*bb02e0acSNicolas Bonnefon 137*bb02e0acSNicolas Bonnefon // The user has clicked on a button, so we assume she wants 138*bb02e0acSNicolas Bonnefon // the widget to stay visible. 139*bb02e0acSNicolas Bonnefon userRequested_ = true; 140*bb02e0acSNicolas Bonnefon 141*bb02e0acSNicolas Bonnefon emit patternConfirmed( editQuickFind_->text(), isIgnoreCase() ); 142*bb02e0acSNicolas Bonnefon emit searchForward(); 143*bb02e0acSNicolas Bonnefon } 144*bb02e0acSNicolas Bonnefon 145*bb02e0acSNicolas Bonnefon // User clicks backward arrow 146*bb02e0acSNicolas Bonnefon void QuickFindWidget::doSearchBackward() 147*bb02e0acSNicolas Bonnefon { 148*bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindWidget::doSearchBackward()"; 149*bb02e0acSNicolas Bonnefon 150*bb02e0acSNicolas Bonnefon // The user has clicked on a button, so we assume she wants 151*bb02e0acSNicolas Bonnefon // the widget to stay visible. 152*bb02e0acSNicolas Bonnefon userRequested_ = true; 153*bb02e0acSNicolas Bonnefon 154*bb02e0acSNicolas Bonnefon emit patternConfirmed( editQuickFind_->text(), isIgnoreCase() ); 155*bb02e0acSNicolas Bonnefon emit searchBackward(); 156*bb02e0acSNicolas Bonnefon } 157*bb02e0acSNicolas Bonnefon 158*bb02e0acSNicolas Bonnefon // Close and search when the user presses Return 159*bb02e0acSNicolas Bonnefon void QuickFindWidget::returnHandler() 160*bb02e0acSNicolas Bonnefon { 161*bb02e0acSNicolas Bonnefon emit patternConfirmed( editQuickFind_->text(), isIgnoreCase() ); 162*bb02e0acSNicolas Bonnefon // Close the widget 163*bb02e0acSNicolas Bonnefon userRequested_ = false; 164*bb02e0acSNicolas Bonnefon this->hide(); 165*bb02e0acSNicolas Bonnefon emit close(); 166*bb02e0acSNicolas Bonnefon } 167*bb02e0acSNicolas Bonnefon 168*bb02e0acSNicolas Bonnefon // Close and reset flag when the user clicks 'close' 169*bb02e0acSNicolas Bonnefon void QuickFindWidget::closeHandler() 170*bb02e0acSNicolas Bonnefon { 171*bb02e0acSNicolas Bonnefon userRequested_ = false; 172*bb02e0acSNicolas Bonnefon this->hide(); 173*bb02e0acSNicolas Bonnefon emit close(); 174*bb02e0acSNicolas Bonnefon emit cancelSearch(); 175*bb02e0acSNicolas Bonnefon } 176*bb02e0acSNicolas Bonnefon 177*bb02e0acSNicolas Bonnefon void QuickFindWidget::notificationTimeout() 178*bb02e0acSNicolas Bonnefon { 179*bb02e0acSNicolas Bonnefon // We close the widget if the user hasn't explicitely requested it. 180*bb02e0acSNicolas Bonnefon if ( userRequested_ == false ) 181*bb02e0acSNicolas Bonnefon this->hide(); 182*bb02e0acSNicolas Bonnefon } 183*bb02e0acSNicolas Bonnefon 184*bb02e0acSNicolas Bonnefon void QuickFindWidget::textChanged() 185*bb02e0acSNicolas Bonnefon { 186*bb02e0acSNicolas Bonnefon emit patternUpdated( editQuickFind_->text(), isIgnoreCase() ); 187*bb02e0acSNicolas Bonnefon } 188*bb02e0acSNicolas Bonnefon 189*bb02e0acSNicolas Bonnefon // 190*bb02e0acSNicolas Bonnefon // Private functions 191*bb02e0acSNicolas Bonnefon // 192*bb02e0acSNicolas Bonnefon QToolButton* QuickFindWidget::setupToolButton( 193*bb02e0acSNicolas Bonnefon const QString &text, const QString &icon) 194*bb02e0acSNicolas Bonnefon { 195*bb02e0acSNicolas Bonnefon QToolButton *toolButton = new QToolButton(this); 196*bb02e0acSNicolas Bonnefon 197*bb02e0acSNicolas Bonnefon toolButton->setText(text); 198*bb02e0acSNicolas Bonnefon toolButton->setAutoRaise(true); 199*bb02e0acSNicolas Bonnefon toolButton->setIcon(QIcon(icon)); 200*bb02e0acSNicolas Bonnefon toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 201*bb02e0acSNicolas Bonnefon 202*bb02e0acSNicolas Bonnefon return toolButton; 203*bb02e0acSNicolas Bonnefon } 204*bb02e0acSNicolas Bonnefon 205*bb02e0acSNicolas Bonnefon bool QuickFindWidget::isIgnoreCase() const 206*bb02e0acSNicolas Bonnefon { 207*bb02e0acSNicolas Bonnefon return ( ignoreCaseCheck_->checkState() == Qt::Checked ); 208*bb02e0acSNicolas Bonnefon } 209