1bb02e0acSNicolas Bonnefon /*
2b423cd88SNicolas Bonnefon * Copyright (C) 2013, 2014 Nicolas Bonnefon and other contributors
3bb02e0acSNicolas Bonnefon *
4bb02e0acSNicolas Bonnefon * This file is part of glogg.
5bb02e0acSNicolas Bonnefon *
6bb02e0acSNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify
7bb02e0acSNicolas Bonnefon * it under the terms of the GNU General Public License as published by
8bb02e0acSNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or
9bb02e0acSNicolas Bonnefon * (at your option) any later version.
10bb02e0acSNicolas Bonnefon *
11bb02e0acSNicolas Bonnefon * glogg is distributed in the hope that it will be useful,
12bb02e0acSNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of
13bb02e0acSNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14bb02e0acSNicolas Bonnefon * GNU General Public License for more details.
15bb02e0acSNicolas Bonnefon *
16bb02e0acSNicolas Bonnefon * You should have received a copy of the GNU General Public License
17bb02e0acSNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>.
18bb02e0acSNicolas Bonnefon */
19bb02e0acSNicolas Bonnefon
20bb02e0acSNicolas Bonnefon #include "log.h"
21bb02e0acSNicolas Bonnefon
22bb02e0acSNicolas Bonnefon #include "persistentinfo.h"
23bb02e0acSNicolas Bonnefon #include "configuration.h"
24bb02e0acSNicolas Bonnefon #include "quickfindmux.h"
25bb02e0acSNicolas Bonnefon
26b423cd88SNicolas Bonnefon #include "qfnotifications.h"
27b423cd88SNicolas Bonnefon
QuickFindMux(std::shared_ptr<QuickFindPattern> pattern)28b423cd88SNicolas Bonnefon QuickFindMux::QuickFindMux( std::shared_ptr<QuickFindPattern> pattern ) :
29d2b38ed8SNicolas Bonnefon QObject(), pattern_( pattern ), registeredSearchables_()
30bb02e0acSNicolas Bonnefon {
31b423cd88SNicolas Bonnefon selector_ = nullptr;
32bb02e0acSNicolas Bonnefon
33bb02e0acSNicolas Bonnefon // Forward the pattern's signal to our listeners
34b423cd88SNicolas Bonnefon connect( pattern_.get(), SIGNAL( patternUpdated() ),
35bb02e0acSNicolas Bonnefon this, SLOT( notifyPatternChanged() ) );
36bb02e0acSNicolas Bonnefon }
37bb02e0acSNicolas Bonnefon
38bb02e0acSNicolas Bonnefon //
39bb02e0acSNicolas Bonnefon // Public member functions
40bb02e0acSNicolas Bonnefon //
registerSelector(const QuickFindMuxSelectorInterface * selector)41b423cd88SNicolas Bonnefon void QuickFindMux::registerSelector(
42b423cd88SNicolas Bonnefon const QuickFindMuxSelectorInterface* selector )
43bb02e0acSNicolas Bonnefon {
44b423cd88SNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::registerSelector";
45bb02e0acSNicolas Bonnefon
46b423cd88SNicolas Bonnefon // The selector object we will use when forwarding search requests
47b423cd88SNicolas Bonnefon selector_ = selector;
48b423cd88SNicolas Bonnefon
49b423cd88SNicolas Bonnefon unregisterAllSearchables();
50b423cd88SNicolas Bonnefon
51a1202e0cSNicolas Bonnefon if ( selector ) {
52b423cd88SNicolas Bonnefon for ( auto i: selector_->getAllSearchables() )
53b423cd88SNicolas Bonnefon registerSearchable( i );
54bb02e0acSNicolas Bonnefon }
55a1202e0cSNicolas Bonnefon else {
56a1202e0cSNicolas Bonnefon // null selector, all is well, we don't do anything.
57a1202e0cSNicolas Bonnefon }
58a1202e0cSNicolas Bonnefon }
59bb02e0acSNicolas Bonnefon
setDirection(QFDirection direction)60bb02e0acSNicolas Bonnefon void QuickFindMux::setDirection( QFDirection direction )
61bb02e0acSNicolas Bonnefon {
62bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::setDirection: new direction: " << direction;
63bb02e0acSNicolas Bonnefon currentDirection_ = direction;
64bb02e0acSNicolas Bonnefon }
65bb02e0acSNicolas Bonnefon
66bb02e0acSNicolas Bonnefon //
67bb02e0acSNicolas Bonnefon // Public slots
68bb02e0acSNicolas Bonnefon //
searchNext()69bb02e0acSNicolas Bonnefon void QuickFindMux::searchNext()
70bb02e0acSNicolas Bonnefon {
71bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::searchNext";
72bb02e0acSNicolas Bonnefon if ( currentDirection_ == Forward )
73bb02e0acSNicolas Bonnefon searchForward();
74bb02e0acSNicolas Bonnefon else
75bb02e0acSNicolas Bonnefon searchBackward();
76bb02e0acSNicolas Bonnefon }
77bb02e0acSNicolas Bonnefon
searchPrevious()78bb02e0acSNicolas Bonnefon void QuickFindMux::searchPrevious()
79bb02e0acSNicolas Bonnefon {
80bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::searchPrevious";
81bb02e0acSNicolas Bonnefon if ( currentDirection_ == Forward )
82bb02e0acSNicolas Bonnefon searchBackward();
83bb02e0acSNicolas Bonnefon else
84bb02e0acSNicolas Bonnefon searchForward();
85bb02e0acSNicolas Bonnefon }
86bb02e0acSNicolas Bonnefon
searchForward()87bb02e0acSNicolas Bonnefon void QuickFindMux::searchForward()
88bb02e0acSNicolas Bonnefon {
89bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::searchForward";
90bb02e0acSNicolas Bonnefon
91a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() )
92bb02e0acSNicolas Bonnefon searchable->searchForward();
93bb02e0acSNicolas Bonnefon }
94bb02e0acSNicolas Bonnefon
searchBackward()95bb02e0acSNicolas Bonnefon void QuickFindMux::searchBackward()
96bb02e0acSNicolas Bonnefon {
97bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::searchBackward";
98bb02e0acSNicolas Bonnefon
99a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() )
100bb02e0acSNicolas Bonnefon searchable->searchBackward();
101bb02e0acSNicolas Bonnefon }
102bb02e0acSNicolas Bonnefon
setNewPattern(const QString & new_pattern,bool ignore_case)103bb02e0acSNicolas Bonnefon void QuickFindMux::setNewPattern(
104bb02e0acSNicolas Bonnefon const QString& new_pattern, bool ignore_case )
105bb02e0acSNicolas Bonnefon {
10611582726SNicolas Bonnefon static std::shared_ptr<Configuration> config =
10711582726SNicolas Bonnefon Persistent<Configuration>( "settings" );
108bb02e0acSNicolas Bonnefon
109bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::setNewPattern";
110bb02e0acSNicolas Bonnefon
111bb02e0acSNicolas Bonnefon // If we must do an incremental search, we do it now
11211582726SNicolas Bonnefon if ( config->isQuickfindIncremental() ) {
113*b932ea6fSNicolas Bonnefon pattern_->changeSearchPattern( new_pattern, ignore_case );
114a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() ) {
115bb02e0acSNicolas Bonnefon if ( currentDirection_ == Forward )
116bb02e0acSNicolas Bonnefon searchable->incrementallySearchForward();
117bb02e0acSNicolas Bonnefon else
118bb02e0acSNicolas Bonnefon searchable->incrementallySearchBackward();
119bb02e0acSNicolas Bonnefon }
120bb02e0acSNicolas Bonnefon }
121a1202e0cSNicolas Bonnefon }
122bb02e0acSNicolas Bonnefon
confirmPattern(const QString & new_pattern,bool ignore_case)123bb02e0acSNicolas Bonnefon void QuickFindMux::confirmPattern(
124bb02e0acSNicolas Bonnefon const QString& new_pattern, bool ignore_case )
125bb02e0acSNicolas Bonnefon {
12611582726SNicolas Bonnefon static std::shared_ptr<Configuration> config =
12711582726SNicolas Bonnefon Persistent<Configuration>( "settings" );
128bb02e0acSNicolas Bonnefon
129b423cd88SNicolas Bonnefon pattern_->changeSearchPattern( new_pattern, ignore_case );
130bb02e0acSNicolas Bonnefon
131bb02e0acSNicolas Bonnefon // if non-incremental, we perform the search now
13211582726SNicolas Bonnefon if ( ! config->isQuickfindIncremental() ) {
133bb02e0acSNicolas Bonnefon searchNext();
134bb02e0acSNicolas Bonnefon }
135bb02e0acSNicolas Bonnefon else {
136a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() )
137bb02e0acSNicolas Bonnefon searchable->incrementalSearchStop();
138bb02e0acSNicolas Bonnefon }
139bb02e0acSNicolas Bonnefon }
140bb02e0acSNicolas Bonnefon
cancelSearch()141bb02e0acSNicolas Bonnefon void QuickFindMux::cancelSearch()
142bb02e0acSNicolas Bonnefon {
14311582726SNicolas Bonnefon static std::shared_ptr<Configuration> config =
14411582726SNicolas Bonnefon Persistent<Configuration>( "settings" );
145bb02e0acSNicolas Bonnefon
14611582726SNicolas Bonnefon if ( config->isQuickfindIncremental() ) {
147a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() )
148bb02e0acSNicolas Bonnefon searchable->incrementalSearchAbort();
149bb02e0acSNicolas Bonnefon }
150bb02e0acSNicolas Bonnefon }
151bb02e0acSNicolas Bonnefon
152bb02e0acSNicolas Bonnefon //
153bb02e0acSNicolas Bonnefon // Private slots
154bb02e0acSNicolas Bonnefon //
changeQuickFind(const QString & new_pattern,QFDirection new_direction)155bb02e0acSNicolas Bonnefon void QuickFindMux::changeQuickFind(
156bb02e0acSNicolas Bonnefon const QString& new_pattern, QFDirection new_direction )
157bb02e0acSNicolas Bonnefon {
158b423cd88SNicolas Bonnefon pattern_->changeSearchPattern( new_pattern );
159bb02e0acSNicolas Bonnefon setDirection( new_direction );
160bb02e0acSNicolas Bonnefon }
161bb02e0acSNicolas Bonnefon
notifyPatternChanged()162bb02e0acSNicolas Bonnefon void QuickFindMux::notifyPatternChanged()
163bb02e0acSNicolas Bonnefon {
164b423cd88SNicolas Bonnefon emit patternChanged( pattern_->getPattern() );
165bb02e0acSNicolas Bonnefon }
166bb02e0acSNicolas Bonnefon
167bb02e0acSNicolas Bonnefon //
168bb02e0acSNicolas Bonnefon // Private member functions
169bb02e0acSNicolas Bonnefon //
170bb02e0acSNicolas Bonnefon
171bb02e0acSNicolas Bonnefon // Use the registered 'selector' to determine where to send the search requests.
getSearchableWidget() const172bb02e0acSNicolas Bonnefon SearchableWidgetInterface* QuickFindMux::getSearchableWidget() const
173bb02e0acSNicolas Bonnefon {
174b423cd88SNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::getSearchableWidget";
175b423cd88SNicolas Bonnefon
176a1202e0cSNicolas Bonnefon SearchableWidgetInterface* searchable = nullptr;
177bb02e0acSNicolas Bonnefon
178bb02e0acSNicolas Bonnefon if ( selector_ )
179bb02e0acSNicolas Bonnefon searchable = selector_->getActiveSearchable();
180bb02e0acSNicolas Bonnefon else
181a1202e0cSNicolas Bonnefon LOG(logWARNING) << "QuickFindMux::getActiveSearchable() no registered selector";
182bb02e0acSNicolas Bonnefon
183bb02e0acSNicolas Bonnefon return searchable;
184bb02e0acSNicolas Bonnefon }
185b423cd88SNicolas Bonnefon
registerSearchable(QObject * searchable)186b423cd88SNicolas Bonnefon void QuickFindMux::registerSearchable( QObject* searchable )
187b423cd88SNicolas Bonnefon {
188b423cd88SNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::registerSearchable";
189b423cd88SNicolas Bonnefon
190b423cd88SNicolas Bonnefon // The searchable can change our qf pattern
191b423cd88SNicolas Bonnefon connect( searchable,
192b423cd88SNicolas Bonnefon SIGNAL( changeQuickFind( const QString&, QuickFindMux::QFDirection ) ),
193b423cd88SNicolas Bonnefon this, SLOT( changeQuickFind( const QString&, QuickFindMux::QFDirection ) ) );
194b423cd88SNicolas Bonnefon // Send us notifications
195b423cd88SNicolas Bonnefon connect( searchable, SIGNAL( notifyQuickFind( const QFNotification& ) ),
196b423cd88SNicolas Bonnefon this, SIGNAL( notify( const QFNotification& ) ) );
197b423cd88SNicolas Bonnefon
198b423cd88SNicolas Bonnefon // And clear them
199b423cd88SNicolas Bonnefon connect( searchable, SIGNAL( clearQuickFindNotification() ),
200b423cd88SNicolas Bonnefon this, SIGNAL( clearNotification() ) );
201b423cd88SNicolas Bonnefon // Search can be initiated by the view itself
202b423cd88SNicolas Bonnefon connect( searchable, SIGNAL( searchNext() ),
203b423cd88SNicolas Bonnefon this, SLOT( searchNext() ) );
204b423cd88SNicolas Bonnefon connect( searchable, SIGNAL( searchPrevious() ),
205b423cd88SNicolas Bonnefon this, SLOT( searchPrevious() ) );
206d2b38ed8SNicolas Bonnefon
207d2b38ed8SNicolas Bonnefon registeredSearchables_.push_back( searchable );
208b423cd88SNicolas Bonnefon }
209b423cd88SNicolas Bonnefon
unregisterAllSearchables()210b423cd88SNicolas Bonnefon void QuickFindMux::unregisterAllSearchables()
211b423cd88SNicolas Bonnefon {
212d2b38ed8SNicolas Bonnefon for ( auto searchable: registeredSearchables_ )
213d2b38ed8SNicolas Bonnefon disconnect( searchable, 0, this, 0 );
214d2b38ed8SNicolas Bonnefon
215d2b38ed8SNicolas Bonnefon registeredSearchables_.clear();
216b423cd88SNicolas Bonnefon }
217