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 Configuration& config = Persistent<Configuration>( "settings" ); 102 103 LOG(logDEBUG) << "QuickFindMux::setNewPattern"; 104 pattern_->changeSearchPattern( new_pattern, ignore_case ); 105 106 // If we must do an incremental search, we do it now 107 if ( config.isQuickfindIncremental() ) { 108 SearchableWidgetInterface* searchable = getSearchableWidget(); 109 if ( currentDirection_ == Forward ) 110 searchable->incrementallySearchForward(); 111 else 112 searchable->incrementallySearchBackward(); 113 } 114 } 115 116 void QuickFindMux::confirmPattern( 117 const QString& new_pattern, bool ignore_case ) 118 { 119 static Configuration& config = Persistent<Configuration>( "settings" ); 120 121 pattern_->changeSearchPattern( new_pattern, ignore_case ); 122 123 // if non-incremental, we perform the search now 124 if ( ! config.isQuickfindIncremental() ) { 125 searchNext(); 126 } 127 else { 128 SearchableWidgetInterface* searchable = getSearchableWidget(); 129 searchable->incrementalSearchStop(); 130 } 131 } 132 133 void QuickFindMux::cancelSearch() 134 { 135 static Configuration& config = Persistent<Configuration>( "settings" ); 136 137 if ( config.isQuickfindIncremental() ) { 138 SearchableWidgetInterface* searchable = getSearchableWidget(); 139 searchable->incrementalSearchAbort(); 140 } 141 } 142 143 // 144 // Private slots 145 // 146 void QuickFindMux::changeQuickFind( 147 const QString& new_pattern, QFDirection new_direction ) 148 { 149 pattern_->changeSearchPattern( new_pattern ); 150 setDirection( new_direction ); 151 } 152 153 void QuickFindMux::notifyPatternChanged() 154 { 155 emit patternChanged( pattern_->getPattern() ); 156 } 157 158 // 159 // Private member functions 160 // 161 162 // Use the registered 'selector' to determine where to send the search requests. 163 SearchableWidgetInterface* QuickFindMux::getSearchableWidget() const 164 { 165 LOG(logDEBUG) << "QuickFindMux::getSearchableWidget"; 166 167 SearchableWidgetInterface* searchable = NULL; 168 169 if ( selector_ ) 170 searchable = selector_->getActiveSearchable(); 171 else 172 LOG(logERROR) << "QuickFindMux::getActiveSearchable() no registered selector"; 173 174 return searchable; 175 } 176 177 void QuickFindMux::registerSearchable( QObject* searchable ) 178 { 179 LOG(logDEBUG) << "QuickFindMux::registerSearchable"; 180 181 // The searchable can change our qf pattern 182 connect( searchable, 183 SIGNAL( changeQuickFind( const QString&, QuickFindMux::QFDirection ) ), 184 this, SLOT( changeQuickFind( const QString&, QuickFindMux::QFDirection ) ) ); 185 // Send us notifications 186 connect( searchable, SIGNAL( notifyQuickFind( const QFNotification& ) ), 187 this, SIGNAL( notify( const QFNotification& ) ) ); 188 189 // And clear them 190 connect( searchable, SIGNAL( clearQuickFindNotification() ), 191 this, SIGNAL( clearNotification() ) ); 192 // Search can be initiated by the view itself 193 connect( searchable, SIGNAL( searchNext() ), 194 this, SLOT( searchNext() ) ); 195 connect( searchable, SIGNAL( searchPrevious() ), 196 this, SLOT( searchPrevious() ) ); 197 198 registeredSearchables_.push_back( searchable ); 199 } 200 201 void QuickFindMux::unregisterAllSearchables() 202 { 203 for ( auto searchable: registeredSearchables_ ) 204 disconnect( searchable, 0, this, 0 ); 205 206 registeredSearchables_.clear(); 207 } 208