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 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 // 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 51*a1202e0cSNicolas Bonnefon if ( selector ) { 52b423cd88SNicolas Bonnefon for ( auto i: selector_->getAllSearchables() ) 53b423cd88SNicolas Bonnefon registerSearchable( i ); 54bb02e0acSNicolas Bonnefon } 55*a1202e0cSNicolas Bonnefon else { 56*a1202e0cSNicolas Bonnefon // null selector, all is well, we don't do anything. 57*a1202e0cSNicolas Bonnefon } 58*a1202e0cSNicolas Bonnefon } 59bb02e0acSNicolas Bonnefon 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 // 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 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 87bb02e0acSNicolas Bonnefon void QuickFindMux::searchForward() 88bb02e0acSNicolas Bonnefon { 89bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::searchForward"; 90bb02e0acSNicolas Bonnefon 91*a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() ) 92bb02e0acSNicolas Bonnefon searchable->searchForward(); 93bb02e0acSNicolas Bonnefon } 94bb02e0acSNicolas Bonnefon 95bb02e0acSNicolas Bonnefon void QuickFindMux::searchBackward() 96bb02e0acSNicolas Bonnefon { 97bb02e0acSNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::searchBackward"; 98bb02e0acSNicolas Bonnefon 99*a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() ) 100bb02e0acSNicolas Bonnefon searchable->searchBackward(); 101bb02e0acSNicolas Bonnefon } 102bb02e0acSNicolas Bonnefon 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"; 110b423cd88SNicolas Bonnefon pattern_->changeSearchPattern( new_pattern, ignore_case ); 111bb02e0acSNicolas Bonnefon 112bb02e0acSNicolas Bonnefon // If we must do an incremental search, we do it now 11311582726SNicolas Bonnefon if ( config->isQuickfindIncremental() ) { 114*a1202e0cSNicolas 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 } 121*a1202e0cSNicolas Bonnefon } 122bb02e0acSNicolas Bonnefon 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 { 136*a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() ) 137bb02e0acSNicolas Bonnefon searchable->incrementalSearchStop(); 138bb02e0acSNicolas Bonnefon } 139bb02e0acSNicolas Bonnefon } 140bb02e0acSNicolas Bonnefon 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() ) { 147*a1202e0cSNicolas Bonnefon if ( auto searchable = getSearchableWidget() ) 148bb02e0acSNicolas Bonnefon searchable->incrementalSearchAbort(); 149bb02e0acSNicolas Bonnefon } 150bb02e0acSNicolas Bonnefon } 151bb02e0acSNicolas Bonnefon 152bb02e0acSNicolas Bonnefon // 153bb02e0acSNicolas Bonnefon // Private slots 154bb02e0acSNicolas Bonnefon // 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 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. 172bb02e0acSNicolas Bonnefon SearchableWidgetInterface* QuickFindMux::getSearchableWidget() const 173bb02e0acSNicolas Bonnefon { 174b423cd88SNicolas Bonnefon LOG(logDEBUG) << "QuickFindMux::getSearchableWidget"; 175b423cd88SNicolas Bonnefon 176*a1202e0cSNicolas Bonnefon SearchableWidgetInterface* searchable = nullptr; 177bb02e0acSNicolas Bonnefon 178bb02e0acSNicolas Bonnefon if ( selector_ ) 179bb02e0acSNicolas Bonnefon searchable = selector_->getActiveSearchable(); 180bb02e0acSNicolas Bonnefon else 181*a1202e0cSNicolas Bonnefon LOG(logWARNING) << "QuickFindMux::getActiveSearchable() no registered selector"; 182bb02e0acSNicolas Bonnefon 183bb02e0acSNicolas Bonnefon return searchable; 184bb02e0acSNicolas Bonnefon } 185b423cd88SNicolas Bonnefon 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 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