File indexing completed on 2024-05-05 03:49:20
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2015 Gábor Péterffy <peterffy95@gmail.com> 0004 // 0005 0006 #include "SearchBackend.h" 0007 0008 #include "SearchRunnerManager.h" 0009 #include "MarbleModel.h" 0010 #include "Coordinate.h" 0011 0012 #include <QCompleter> 0013 0014 using namespace Marble; 0015 0016 0017 SearchBackend::SearchBackend(QObject *parent) : 0018 QObject(parent), 0019 m_searchManager( nullptr ), 0020 m_marbleQuickItem( nullptr ), 0021 m_placemarkModel( nullptr ), 0022 m_completer( nullptr ), 0023 m_completionModel( new MarblePlacemarkModel ), 0024 m_completionContainer( new QVector<GeoDataPlacemark*>() ), 0025 m_selectedPlacemark( ) 0026 { 0027 m_model.setSortRole( MarblePlacemarkModel::PopularityIndexRole ); 0028 m_model.sort(0); 0029 m_model.setDynamicSortFilter(true); 0030 m_completionModel->setPlacemarkContainer(m_completionContainer); 0031 } 0032 0033 void SearchBackend::search(const QString &place) 0034 { 0035 if (m_marbleQuickItem) 0036 { 0037 m_searchManager->searchPlacemarks(place); 0038 } 0039 } 0040 0041 void SearchBackend::setCompletionPrefix(const QString &prefix) 0042 { 0043 if( m_completer != nullptr && m_completer->completionPrefix() != prefix ) { 0044 if (!m_lastSuccessfulCompletion.isEmpty() 0045 && prefix.startsWith(m_lastSuccessfulCompletion) 0046 && prefix.size() > m_lastSuccessfulCompletion.size()) { 0047 return; 0048 } 0049 0050 m_completionModel->removePlacemarks(QStringLiteral("Completion model"), 0, m_completionModel->rowCount()); 0051 m_completionContainer->clear(); 0052 QString const lastPrefix = m_completer->completionPrefix(); 0053 m_completer->setCompletionPrefix(prefix); 0054 if( prefix.isEmpty() ) { 0055 emit completionModelChanged(m_completionModel); 0056 return; 0057 } 0058 QVector<GeoDataPlacemark*> *container = new QVector<GeoDataPlacemark*>(); 0059 QAbstractProxyModel *model = qobject_cast<QAbstractProxyModel*>(m_completer->completionModel()); 0060 for( int i = 0; i<m_completer->completionModel()->rowCount(); ++i ) { 0061 QModelIndex index = model->mapToSource(model->index(i,0)); 0062 QVariant data = m_marbleQuickItem->model()->placemarkModel()->data(index, MarblePlacemarkModel::ObjectPointerRole); 0063 GeoDataPlacemark *placemark = placemarkFromQVariant(data); 0064 if( placemark != nullptr ) { 0065 container->append(placemark); 0066 } 0067 } 0068 if (container->isEmpty() && prefix.startsWith(lastPrefix) ) { 0069 m_lastSuccessfulCompletion = lastPrefix; 0070 } else if (!container->isEmpty()) { 0071 m_lastSuccessfulCompletion.clear(); 0072 } 0073 m_completionModel->setPlacemarkContainer(container); 0074 m_completionModel->addPlacemarks(0, container->size()); 0075 delete m_completionContainer; 0076 m_completionContainer = container; 0077 emit completionModelChanged(m_completionModel); 0078 } 0079 } 0080 0081 QObject * SearchBackend::marbleQuickItem() 0082 { 0083 return m_marbleQuickItem; 0084 } 0085 0086 MarblePlacemarkModel *SearchBackend::completionModel() 0087 { 0088 return m_completionModel; 0089 } 0090 0091 const QObject * SearchBackend::marbleQuickItem() const 0092 { 0093 return m_marbleQuickItem; 0094 } 0095 0096 Placemark *SearchBackend::selectedPlacemark() 0097 { 0098 return &m_selectedPlacemark; 0099 } 0100 0101 void SearchBackend::setSelectedPlacemark(int placemarkIndex) 0102 { 0103 QVariant data = m_placemarkModel->data(m_placemarkModel->index(placemarkIndex), MarblePlacemarkModel::ObjectPointerRole); 0104 GeoDataPlacemark *placemark = placemarkFromQVariant(data); 0105 if( placemark == nullptr ) { 0106 return; 0107 } 0108 0109 m_selectedPlacemark.setGeoDataPlacemark(*placemark); 0110 m_marbleQuickItem->centerOn(*placemark, true); 0111 emit selectedPlacemarkChanged(&m_selectedPlacemark); 0112 } 0113 0114 void SearchBackend::setMarbleQuickItem(QObject *marbleQuickItem) 0115 { 0116 MarbleQuickItem * item = qobject_cast<MarbleQuickItem*>(marbleQuickItem); 0117 if (m_marbleQuickItem == item) 0118 { 0119 return; 0120 } 0121 0122 if (item) 0123 { 0124 delete m_searchManager; 0125 delete m_completer; 0126 m_marbleQuickItem = item; 0127 m_searchManager = new SearchRunnerManager(m_marbleQuickItem->model(), this); 0128 0129 connect(m_searchManager, SIGNAL(searchResultChanged(QAbstractItemModel*)), 0130 this, SLOT(updateSearchResult(QAbstractItemModel*))); 0131 connect(m_searchManager, SIGNAL(searchFinished(QString)), 0132 this, SIGNAL(searchFinished(QString))); 0133 0134 m_completer = new QCompleter(); 0135 m_completer->setModel(m_marbleQuickItem->model()->placemarkModel()); 0136 m_completer->setCompletionRole(Qt::DisplayRole); 0137 m_completer->setCaseSensitivity(Qt::CaseInsensitive); 0138 0139 emit marbleQuickItemChanged(marbleQuickItem); 0140 } 0141 } 0142 0143 void SearchBackend::updateSearchResult(QAbstractItemModel *result) 0144 { 0145 m_placemarkModel = qobject_cast<MarblePlacemarkModel*>(result); 0146 emit searchResultChanged(m_placemarkModel); 0147 } 0148 0149 GeoDataPlacemark *SearchBackend::placemarkFromQVariant(const QVariant &data) 0150 { 0151 if( !data.isValid() ) { 0152 return nullptr; 0153 } 0154 GeoDataObject *object = qvariant_cast<GeoDataObject*>( data ); 0155 if( object == nullptr ) { 0156 return nullptr; 0157 } 0158 GeoDataPlacemark *placemark = dynamic_cast<GeoDataPlacemark*>( object ); 0159 if( placemark == nullptr ) { 0160 return nullptr; 0161 } 0162 return placemark; 0163 } 0164 0165 #include "moc_SearchBackend.cpp"