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 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 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 // 69 void QuickFindMux::searchNext() 70 { 71 LOG(logDEBUG) << "QuickFindMux::searchNext"; 72 if ( currentDirection_ == Forward ) 73 searchForward(); 74 else 75 searchBackward(); 76 } 77 78 void QuickFindMux::searchPrevious() 79 { 80 LOG(logDEBUG) << "QuickFindMux::searchPrevious"; 81 if ( currentDirection_ == Forward ) 82 searchBackward(); 83 else 84 searchForward(); 85 } 86 87 void QuickFindMux::searchForward() 88 { 89 LOG(logDEBUG) << "QuickFindMux::searchForward"; 90 91 if ( auto searchable = getSearchableWidget() ) 92 searchable->searchForward(); 93 } 94 95 void QuickFindMux::searchBackward() 96 { 97 LOG(logDEBUG) << "QuickFindMux::searchBackward"; 98 99 if ( auto searchable = getSearchableWidget() ) 100 searchable->searchBackward(); 101 } 102 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 pattern_->changeSearchPattern( new_pattern, ignore_case ); 111 112 // If we must do an incremental search, we do it now 113 if ( config->isQuickfindIncremental() ) { 114 if ( auto searchable = getSearchableWidget() ) { 115 if ( currentDirection_ == Forward ) 116 searchable->incrementallySearchForward(); 117 else 118 searchable->incrementallySearchBackward(); 119 } 120 } 121 } 122 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 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 // 155 void QuickFindMux::changeQuickFind( 156 const QString& new_pattern, QFDirection new_direction ) 157 { 158 pattern_->changeSearchPattern( new_pattern ); 159 setDirection( new_direction ); 160 } 161 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. 172 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 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 210 void QuickFindMux::unregisterAllSearchables() 211 { 212 for ( auto searchable: registeredSearchables_ ) 213 disconnect( searchable, 0, this, 0 ); 214 215 registeredSearchables_.clear(); 216 } 217