Esempio n. 1
0
void QgsLocator::deregisterFilter( QgsLocatorFilter *filter )
{
  cancelRunningQuery();
  mFilters.removeAll( filter );
  QString key = mPrefixedFilters.key( filter );
  if ( !key.isEmpty() )
    mPrefixedFilters.remove( key );
  delete filter;
}
Esempio n. 2
0
void QgsLocator::deregisterFilter( QgsLocatorFilter *filter )
{
  cancelRunningQuery();
  mFilters.removeAll( filter );
  delete filter;
}
Esempio n. 3
0
QgsLocator::~QgsLocator()
{
  cancelRunningQuery();
  qDeleteAll( mFilters );
}
Esempio n. 4
0
void QgsLocator::cancel()
{
  cancelRunningQuery();
}
Esempio n. 5
0
void QgsLocator::fetchResults( const QString &string, const QgsLocatorContext &c, QgsFeedback *feedback )
{
  QgsLocatorContext context( c );
  // ideally this should not be required, as well behaved callers
  // will NOT fire up a new fetchResults call while an existing one is
  // operating/waiting to be canceled...
  cancelRunningQuery();

  // if no feedback object was passed, create one that is owned by this object
  // to ensure that filters ALWAYS receive a valid feedback
  if ( !feedback )
  {
    mOwnedFeedback.reset( new QgsFeedback() );
    feedback = mOwnedFeedback.get();
  }
  else
  {
    mOwnedFeedback.reset( nullptr );
  }
  mFeedback = feedback;

  QList< QgsLocatorFilter * > activeFilters;
  QString searchString = string;
  QString prefix = searchString.left( std::max( searchString.indexOf( ' ' ), 0 ) );
  if ( !prefix.isEmpty() )
  {
    for ( QgsLocatorFilter *filter : qgis::as_const( mFilters ) )
    {
      if ( filter->activePrefix() == prefix && filter->enabled() )
      {
        activeFilters << filter;
      }
    }
    context.usingPrefix = !activeFilters.empty();
  }
  if ( !activeFilters.isEmpty() )
  {
    searchString = searchString.mid( prefix.length() + 1 );
  }
  else
  {
    for ( QgsLocatorFilter *filter : qgis::as_const( mFilters ) )
    {
      if ( filter->useWithoutPrefix() && filter->enabled() )
      {
        activeFilters << filter;
      }
    }
  }

  QList< QgsLocatorFilter *> threadedFilters;
  for ( QgsLocatorFilter *filter : qgis::as_const( activeFilters ) )
  {
    filter->clearPreviousResults();
    std::unique_ptr< QgsLocatorFilter > clone( filter->clone() );
    connect( clone.get(), &QgsLocatorFilter::resultFetched, clone.get(), [this, filter]( QgsLocatorResult result )
    {
      result.filter = filter;
      emit filterSentResult( result );
    } );
    clone->prepare( searchString, context );

    if ( clone->flags() & QgsLocatorFilter::FlagFast )
    {
      // filter is fast enough to fetch results on the main thread
      clone->fetchResults( searchString, context, feedback );
    }
    else
    {
      // run filter in background
      threadedFilters.append( clone.release() );
    }
  }

  mActiveThreads.clear();
  for ( QgsLocatorFilter *filter : qgis::as_const( threadedFilters ) )
  {
    QThread *thread = new QThread();
    mActiveThreads.append( thread );
    filter->moveToThread( thread );
    connect( thread, &QThread::started, filter, [filter, searchString, context, feedback]
    {
      if ( !feedback->isCanceled() )
        filter->fetchResults( searchString, context, feedback );
      filter->emit finished();
    }, Qt::QueuedConnection );
    connect( filter, &QgsLocatorFilter::finished, thread, &QThread::quit );
    connect( filter, &QgsLocatorFilter::finished, filter, &QgsLocatorFilter::deleteLater );
    connect( thread, &QThread::finished, thread, [this, thread]
    {
      mActiveThreads.removeAll( thread );
      if ( mActiveThreads.empty() )
        emit finished();
    } );
    connect( thread, &QThread::finished, thread, &QThread::deleteLater );
    thread->start();
  }

  if ( mActiveThreads.empty() )
    emit finished();
}