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