xref: /glogg/src/quickfindmux.cpp (revision 11582726a85c08832d009bfe179074b8d1152d21)
1 /*
2  * Copyright (C) 2013, 2014 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 "persistentinfo.h"
23 #include "configuration.h"
24 #include "quickfindmux.h"
25 
26 #include "qfnotifications.h"
27 
28 QuickFindMux::QuickFindMux( std::shared_ptr<QuickFindPattern> pattern ) :
29     QObject(), pattern_( pattern ), registeredSearchables_()
30 {
31     selector_ = nullptr;
32 
33     // Forward the pattern's signal to our listeners
34     connect( pattern_.get(), SIGNAL( patternUpdated() ),
35              this, SLOT( notifyPatternChanged() ) );
36 }
37 
38 //
39 // Public member functions
40 //
41 void QuickFindMux::registerSelector(
42         const QuickFindMuxSelectorInterface* selector )
43 {
44     LOG(logDEBUG) << "QuickFindMux::registerSelector";
45 
46     // The selector object we will use when forwarding search requests
47     selector_ = selector;
48 
49     unregisterAllSearchables();
50 
51     for ( auto i: selector_->getAllSearchables() )
52         registerSearchable( i );
53 }
54 
55 void QuickFindMux::setDirection( QFDirection direction )
56 {
57     LOG(logDEBUG) << "QuickFindMux::setDirection: new direction: " << direction;
58     currentDirection_ = direction;
59 }
60 
61 //
62 // Public slots
63 //
64 void QuickFindMux::searchNext()
65 {
66     LOG(logDEBUG) << "QuickFindMux::searchNext";
67     if ( currentDirection_ == Forward )
68         searchForward();
69     else
70         searchBackward();
71 }
72 
73 void QuickFindMux::searchPrevious()
74 {
75     LOG(logDEBUG) << "QuickFindMux::searchPrevious";
76     if ( currentDirection_ == Forward )
77         searchBackward();
78     else
79         searchForward();
80 }
81 
82 void QuickFindMux::searchForward()
83 {
84     LOG(logDEBUG) << "QuickFindMux::searchForward";
85     SearchableWidgetInterface* searchable = getSearchableWidget();
86 
87     searchable->searchForward();
88 }
89 
90 void QuickFindMux::searchBackward()
91 {
92     LOG(logDEBUG) << "QuickFindMux::searchBackward";
93     SearchableWidgetInterface* searchable = getSearchableWidget();
94 
95     searchable->searchBackward();
96 }
97 
98 void QuickFindMux::setNewPattern(
99         const QString& new_pattern, bool ignore_case )
100 {
101     static std::shared_ptr<Configuration> config =
102         Persistent<Configuration>( "settings" );
103 
104     LOG(logDEBUG) << "QuickFindMux::setNewPattern";
105     pattern_->changeSearchPattern( new_pattern, ignore_case );
106 
107     // If we must do an incremental search, we do it now
108     if ( config->isQuickfindIncremental() ) {
109         SearchableWidgetInterface* searchable = getSearchableWidget();
110         if ( currentDirection_ == Forward )
111             searchable->incrementallySearchForward();
112         else
113             searchable->incrementallySearchBackward();
114     }
115 }
116 
117 void QuickFindMux::confirmPattern(
118         const QString& new_pattern, bool ignore_case )
119 {
120     static std::shared_ptr<Configuration> config =
121         Persistent<Configuration>( "settings" );
122 
123     pattern_->changeSearchPattern( new_pattern, ignore_case );
124 
125     // if non-incremental, we perform the search now
126     if ( ! config->isQuickfindIncremental() ) {
127         searchNext();
128     }
129     else {
130         SearchableWidgetInterface* searchable = getSearchableWidget();
131         searchable->incrementalSearchStop();
132     }
133 }
134 
135 void QuickFindMux::cancelSearch()
136 {
137     static std::shared_ptr<Configuration> config =
138         Persistent<Configuration>( "settings" );
139 
140     if ( config->isQuickfindIncremental() ) {
141         SearchableWidgetInterface* searchable = getSearchableWidget();
142         searchable->incrementalSearchAbort();
143     }
144 }
145 
146 //
147 // Private slots
148 //
149 void QuickFindMux::changeQuickFind(
150         const QString& new_pattern, QFDirection new_direction )
151 {
152     pattern_->changeSearchPattern( new_pattern );
153     setDirection( new_direction );
154 }
155 
156 void QuickFindMux::notifyPatternChanged()
157 {
158     emit patternChanged( pattern_->getPattern() );
159 }
160 
161 //
162 // Private member functions
163 //
164 
165 // Use the registered 'selector' to determine where to send the search requests.
166 SearchableWidgetInterface* QuickFindMux::getSearchableWidget() const
167 {
168     LOG(logDEBUG) << "QuickFindMux::getSearchableWidget";
169 
170     SearchableWidgetInterface* searchable = NULL;
171 
172     if ( selector_ )
173         searchable = selector_->getActiveSearchable();
174     else
175         LOG(logERROR) << "QuickFindMux::getActiveSearchable() no registered selector";
176 
177     return searchable;
178 }
179 
180 void QuickFindMux::registerSearchable( QObject* searchable )
181 {
182     LOG(logDEBUG) << "QuickFindMux::registerSearchable";
183 
184     // The searchable can change our qf pattern
185     connect( searchable,
186              SIGNAL( changeQuickFind( const QString&, QuickFindMux::QFDirection ) ),
187              this, SLOT( changeQuickFind( const QString&, QuickFindMux::QFDirection ) ) );
188     // Send us notifications
189     connect( searchable, SIGNAL( notifyQuickFind( const QFNotification& ) ),
190              this, SIGNAL( notify( const QFNotification& ) ) );
191 
192     // And clear them
193     connect( searchable, SIGNAL( clearQuickFindNotification() ),
194              this, SIGNAL( clearNotification() ) );
195     // Search can be initiated by the view itself
196     connect( searchable, SIGNAL( searchNext() ),
197              this, SLOT( searchNext() ) );
198     connect( searchable, SIGNAL( searchPrevious() ),
199              this, SLOT( searchPrevious() ) );
200 
201     registeredSearchables_.push_back( searchable );
202 }
203 
204 void QuickFindMux::unregisterAllSearchables()
205 {
206     for ( auto searchable: registeredSearchables_ )
207         disconnect( searchable, 0, this, 0 );
208 
209     registeredSearchables_.clear();
210 }
211