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"