File indexing completed on 2024-04-21 03:49:44
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2006-2007 Torsten Rahn <tackat@kde.org> 0004 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org> 0005 // 0006 0007 0008 // Own 0009 #include "MarblePlacemarkModel.h" 0010 #include "MarblePlacemarkModel_P.h" 0011 0012 // Qt 0013 #include <QElapsedTimer> 0014 #include <QImage> 0015 0016 // Marble 0017 #include "MarbleDebug.h" 0018 #include "GeoDataPlacemark.h" 0019 #include "GeoDataExtendedData.h" 0020 #include "GeoDataData.h" 0021 #include "GeoDataGeometry.h" 0022 #include "GeoDataStyle.h" // In geodata/data/ 0023 #include "GeoDataIconStyle.h" 0024 0025 using namespace Marble; 0026 0027 class Q_DECL_HIDDEN MarblePlacemarkModel::Private 0028 { 0029 0030 public: 0031 Private() 0032 : m_size(0), 0033 m_placemarkContainer( nullptr ) 0034 { 0035 } 0036 0037 ~Private() 0038 { 0039 } 0040 0041 int m_size; 0042 QVector<GeoDataPlacemark*> *m_placemarkContainer; 0043 }; 0044 0045 0046 // --------------------------------------------------------------------------- 0047 0048 0049 MarblePlacemarkModel::MarblePlacemarkModel( QObject *parent ) 0050 : QAbstractListModel( parent ), 0051 d( new Private ) 0052 { 0053 QHash<int,QByteArray> roles; 0054 roles[DescriptionRole] = "description"; 0055 roles[Qt::DisplayRole] = "name"; 0056 roles[Qt::DecorationRole] = "icon"; 0057 roles[IconPathRole] = "iconPath"; 0058 roles[PopularityIndexRole] = "zoomLevel"; 0059 roles[VisualCategoryRole] = "visualCategory"; 0060 roles[AreaRole] = "area"; 0061 roles[PopulationRole] = "population"; 0062 roles[CountryCodeRole] = "countryCode"; 0063 roles[StateRole] = "state"; 0064 roles[PopularityRole] = "popularity"; 0065 roles[GeoTypeRole] = "role"; 0066 roles[CoordinateRole] = "coordinate"; 0067 roles[StyleRole] = "style"; 0068 roles[GmtRole] = "gmt"; 0069 roles[DstRole] = "dst"; 0070 roles[GeometryRole] = "geometry"; 0071 roles[ObjectPointerRole] = "objectPointer"; 0072 roles[LongitudeRole] = "longitude"; 0073 roles[LatitudeRole] = "latitude"; 0074 m_roleNames = roles; 0075 } 0076 0077 MarblePlacemarkModel::~MarblePlacemarkModel() 0078 { 0079 delete d; 0080 } 0081 0082 void MarblePlacemarkModel::setPlacemarkContainer( QVector<GeoDataPlacemark*> *container ) 0083 { 0084 d->m_placemarkContainer = container; 0085 } 0086 0087 int MarblePlacemarkModel::rowCount( const QModelIndex &parent ) const 0088 { 0089 if ( !parent.isValid() ) 0090 return d->m_size; 0091 else 0092 return 0; 0093 } 0094 0095 int MarblePlacemarkModel::columnCount( const QModelIndex &parent ) const 0096 { 0097 if ( !parent.isValid() ) 0098 return 1; 0099 else 0100 return 0; 0101 } 0102 0103 QHash<int, QByteArray> MarblePlacemarkModel::roleNames() const 0104 { 0105 return m_roleNames; 0106 } 0107 0108 QVariant MarblePlacemarkModel::data( const QModelIndex &index, int role ) const 0109 { 0110 if ( !index.isValid() ) 0111 return QVariant(); 0112 0113 if ( index.row() >= d->m_placemarkContainer->size() ) 0114 return QVariant(); 0115 0116 if ( role == Qt::DisplayRole ) { 0117 return d->m_placemarkContainer->at( index.row() )->name(); 0118 } else if ( role == Qt::DecorationRole ) { 0119 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->style()->iconStyle().icon() ); 0120 } else if ( role == IconPathRole ) { 0121 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->style()->iconStyle().iconPath() ); 0122 } else if ( role == PopularityIndexRole ) { 0123 return d->m_placemarkContainer->at( index.row() )->zoomLevel(); 0124 } else if ( role == VisualCategoryRole ) { 0125 return d->m_placemarkContainer->at( index.row() )->visualCategory(); 0126 } else if ( role == AreaRole ) { 0127 return d->m_placemarkContainer->at( index.row() )->area(); 0128 } else if ( role == PopulationRole ) { 0129 return d->m_placemarkContainer->at( index.row() )->population(); 0130 } else if ( role == CountryCodeRole ) { 0131 return d->m_placemarkContainer->at( index.row() )->countryCode(); 0132 } else if ( role == StateRole ) { 0133 return d->m_placemarkContainer->at( index.row() )->state(); 0134 } else if ( role == PopularityRole ) { 0135 return d->m_placemarkContainer->at( index.row() )->popularity(); 0136 } else if ( role == DescriptionRole ) { 0137 return d->m_placemarkContainer->at( index.row() )->description(); 0138 } else if ( role == Qt::ToolTipRole ) { 0139 return d->m_placemarkContainer->at( index.row() )->description(); 0140 } else if ( role == GeoTypeRole ) { 0141 return d->m_placemarkContainer->at( index.row() )->role(); 0142 } else if ( role == CoordinateRole ) { 0143 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->coordinate() ); 0144 } else if ( role == StyleRole ) { 0145 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->style().data() ); 0146 } else if ( role == GmtRole ) { 0147 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->extendedData().value(QStringLiteral("gmt")).value() ); 0148 } else if ( role == DstRole ) { 0149 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->extendedData().value(QStringLiteral("dst")).value() ); 0150 } else if ( role == GeometryRole ) { 0151 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->geometry() ); 0152 } else if ( role == ObjectPointerRole ) { 0153 return QVariant::fromValue( dynamic_cast<GeoDataObject*>( d->m_placemarkContainer->at( index.row() ) ) ); 0154 } else if ( role == LongitudeRole ) { 0155 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->coordinate().longitude( GeoDataCoordinates::Degree ) ); 0156 } else if ( role == LatitudeRole ) { 0157 return QVariant::fromValue( d->m_placemarkContainer->at( index.row() )->coordinate().latitude( GeoDataCoordinates::Degree ) ); 0158 } else 0159 return QVariant(); 0160 } 0161 0162 QModelIndexList MarblePlacemarkModel::approxMatch( const QModelIndex & start, int role, 0163 const QVariant & value, int hits, 0164 Qt::MatchFlags flags ) const 0165 { 0166 QList<QModelIndex> results; 0167 0168 int count = 0; 0169 0170 QModelIndex entryIndex; 0171 QString listName; 0172 QString queryString = value.toString().toLower(); 0173 QString simplifiedListName; 0174 0175 int row = start.row(); 0176 const int rowNum = rowCount(); 0177 0178 while ( row < rowNum && count != hits ) { 0179 if ( flags & Qt::MatchStartsWith ) { 0180 entryIndex = index( row, 0 ); 0181 listName = data( entryIndex, role ).toString().toLower(); 0182 simplifiedListName = GeoString::deaccent( listName ); 0183 0184 if ( listName.startsWith( queryString ) 0185 || simplifiedListName.startsWith( queryString ) 0186 ) 0187 { 0188 results << entryIndex; 0189 ++count; 0190 } 0191 } 0192 ++row; 0193 } 0194 0195 return results; 0196 } 0197 0198 void MarblePlacemarkModel::addPlacemarks( int start, 0199 int length ) 0200 { 0201 Q_UNUSED(start); 0202 0203 // performance wise a reset is far better when the provided list 0204 // is significant. That is an issue because we have 0205 // MarbleControlBox::m_sortproxy as a sorting customer. 0206 // I leave the balance search as an exercise to the reader... 0207 0208 QElapsedTimer t; 0209 t.start(); 0210 // beginInsertRows( QModelIndex(), start, start + length ); 0211 d->m_size += length; 0212 // endInsertRows(); 0213 beginResetModel(); 0214 endResetModel(); 0215 emit countChanged(); 0216 mDebug() << "addPlacemarks: Time elapsed:" << t.elapsed() << "ms for" << length << "Placemarks."; 0217 } 0218 0219 void MarblePlacemarkModel::removePlacemarks( const QString &containerName, 0220 int start, 0221 int length ) 0222 { 0223 if ( length > 0 ) { 0224 QElapsedTimer t; 0225 t.start(); 0226 beginRemoveRows( QModelIndex(), start, start + length ); 0227 d->m_size -= length; 0228 endRemoveRows(); 0229 emit layoutChanged(); 0230 emit countChanged(); 0231 mDebug() << "removePlacemarks(" << containerName << "): Time elapsed:" << t.elapsed() << "ms for" << length << "Placemarks."; 0232 } 0233 } 0234 0235 #include "moc_MarblePlacemarkModel.cpp"