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