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"