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
QuickFindMux(std::shared_ptr<QuickFindPattern> pattern)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 //
registerSelector(const QuickFindMuxSelectorInterface * selector)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 if ( selector ) {
52 for ( auto i: selector_->getAllSearchables() )
53 registerSearchable( i );
54 }
55 else {
56 // null selector, all is well, we don't do anything.
57 }
58 }
59
setDirection(QFDirection direction)60 void QuickFindMux::setDirection( QFDirection direction )
61 {
62 LOG(logDEBUG) << "QuickFindMux::setDirection: new direction: " << direction;
63 currentDirection_ = direction;
64 }
65
66 //
67 // Public slots
68 //
searchNext()69 void QuickFindMux::searchNext()
70 {
71 LOG(logDEBUG) << "QuickFindMux::searchNext";
72 if ( currentDirection_ == Forward )
73 searchForward();
74 else
75 searchBackward();
76 }
77
searchPrevious()78 void QuickFindMux::searchPrevious()
79 {
80 LOG(logDEBUG) << "QuickFindMux::searchPrevious";
81 if ( currentDirection_ == Forward )
82 searchBackward();
83 else
84 searchForward();
85 }
86
searchForward()87 void QuickFindMux::searchForward()
88 {
89 LOG(logDEBUG) << "QuickFindMux::searchForward";
90
91 if ( auto searchable = getSearchableWidget() )
92 searchable->searchForward();
93 }
94
searchBackward()95 void QuickFindMux::searchBackward()
96 {
97 LOG(logDEBUG) << "QuickFindMux::searchBackward";
98
99 if ( auto searchable = getSearchableWidget() )
100 searchable->searchBackward();
101 }
102
setNewPattern(const QString & new_pattern,bool ignore_case)103 void QuickFindMux::setNewPattern(
104 const QString& new_pattern, bool ignore_case )
105 {
106 static std::shared_ptr<Configuration> config =
107 Persistent<Configuration>( "settings" );
108
109 LOG(logDEBUG) << "QuickFindMux::setNewPattern";
110
111 // If we must do an incremental search, we do it now
112 if ( config->isQuickfindIncremental() ) {
113 pattern_->changeSearchPattern( new_pattern, ignore_case );
114 if ( auto searchable = getSearchableWidget() ) {
115 if ( currentDirection_ == Forward )
116 searchable->incrementallySearchForward();
117 else
118 searchable->incrementallySearchBackward();
119 }
120 }
121 }
122
confirmPattern(const QString & new_pattern,bool ignore_case)123 void QuickFindMux::confirmPattern(
124 const QString& new_pattern, bool ignore_case )
125 {
126 static std::shared_ptr<Configuration> config =
127 Persistent<Configuration>( "settings" );
128
129 pattern_->changeSearchPattern( new_pattern, ignore_case );
130
131 // if non-incremental, we perform the search now
132 if ( ! config->isQuickfindIncremental() ) {
133 searchNext();
134 }
135 else {
136 if ( auto searchable = getSearchableWidget() )
137 searchable->incrementalSearchStop();
138 }
139 }
140
cancelSearch()141 void QuickFindMux::cancelSearch()
142 {
143 static std::shared_ptr<Configuration> config =
144 Persistent<Configuration>( "settings" );
145
146 if ( config->isQuickfindIncremental() ) {
147 if ( auto searchable = getSearchableWidget() )
148 searchable->incrementalSearchAbort();
149 }
150 }
151
152 //
153 // Private slots
154 //
changeQuickFind(const QString & new_pattern,QFDirection new_direction)155 void QuickFindMux::changeQuickFind(
156 const QString& new_pattern, QFDirection new_direction )
157 {
158 pattern_->changeSearchPattern( new_pattern );
159 setDirection( new_direction );
160 }
161
notifyPatternChanged()162 void QuickFindMux::notifyPatternChanged()
163 {
164 emit patternChanged( pattern_->getPattern() );
165 }
166
167 //
168 // Private member functions
169 //
170
171 // Use the registered 'selector' to determine where to send the search requests.
getSearchableWidget() const172 SearchableWidgetInterface* QuickFindMux::getSearchableWidget() const
173 {
174 LOG(logDEBUG) << "QuickFindMux::getSearchableWidget";
175
176 SearchableWidgetInterface* searchable = nullptr;
177
178 if ( selector_ )
179 searchable = selector_->getActiveSearchable();
180 else
181 LOG(logWARNING) << "QuickFindMux::getActiveSearchable() no registered selector";
182
183 return searchable;
184 }
185
registerSearchable(QObject * searchable)186 void QuickFindMux::registerSearchable( QObject* searchable )
187 {
188 LOG(logDEBUG) << "QuickFindMux::registerSearchable";
189
190 // The searchable can change our qf pattern
191 connect( searchable,
192 SIGNAL( changeQuickFind( const QString&, QuickFindMux::QFDirection ) ),
193 this, SLOT( changeQuickFind( const QString&, QuickFindMux::QFDirection ) ) );
194 // Send us notifications
195 connect( searchable, SIGNAL( notifyQuickFind( const QFNotification& ) ),
196 this, SIGNAL( notify( const QFNotification& ) ) );
197
198 // And clear them
199 connect( searchable, SIGNAL( clearQuickFindNotification() ),
200 this, SIGNAL( clearNotification() ) );
201 // Search can be initiated by the view itself
202 connect( searchable, SIGNAL( searchNext() ),
203 this, SLOT( searchNext() ) );
204 connect( searchable, SIGNAL( searchPrevious() ),
205 this, SLOT( searchPrevious() ) );
206
207 registeredSearchables_.push_back( searchable );
208 }
209
unregisterAllSearchables()210 void QuickFindMux::unregisterAllSearchables()
211 {
212 for ( auto searchable: registeredSearchables_ )
213 disconnect( searchable, 0, this, 0 );
214
215 registeredSearchables_.clear();
216 }
217