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