File indexing completed on 2024-05-19 07:37:36
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2013 Utku Aydın <utkuaydin34@gmail.com> 0004 // 0005 0006 #include "CloudRouteModel.h" 0007 0008 #include "RouteItem.h" 0009 0010 #include "MarbleDebug.h" 0011 #include "MarbleDirs.h" 0012 0013 #include <QIcon> 0014 #include <QUrl> 0015 #include <QSet> 0016 #include <QVector> 0017 #include <QNetworkRequest> 0018 #include <QNetworkReply> 0019 #include <QNetworkAccessManager> 0020 0021 namespace Marble { 0022 0023 class Q_DECL_HIDDEN CloudRouteModel::Private { 0024 0025 public: 0026 Private(); 0027 0028 QVector<RouteItem> m_items; 0029 QString m_cacheDir; 0030 QPersistentModelIndex m_downloading; 0031 qint64 m_totalSize; 0032 qint64 m_downloadedSize; 0033 0034 QNetworkAccessManager m_network; 0035 QMap<QNetworkReply*, int> m_previewQueue; 0036 QSet<QString> m_requestedPreviews; 0037 0038 QHash<int, QByteArray> m_roleNames; 0039 }; 0040 0041 CloudRouteModel::Private::Private() : 0042 m_totalSize( -1 ), 0043 m_downloadedSize( 0 ) 0044 { 0045 m_cacheDir = MarbleDirs::localPath() + QLatin1String("/cloudsync/cache/routes/"); 0046 } 0047 0048 CloudRouteModel::CloudRouteModel( QObject* parent ) : 0049 QAbstractListModel( parent ), d( new Private() ) 0050 { 0051 connect( &(d->m_network), SIGNAL(finished(QNetworkReply*)), 0052 this, SLOT(setPreview(QNetworkReply*)) ); 0053 0054 QHash<int, QByteArray> roles = roleNames(); 0055 roles[ Name ] = "name"; 0056 roles[ Timestamp ] = "identifier"; 0057 roles[ PreviewUrl ] = "previewUrl"; 0058 roles[ Distance ] = "distance"; 0059 roles[ Duration ] = "duration"; 0060 roles[ IsCached ] = "isCached"; 0061 roles[ IsDownloading ] = "isDownloading"; 0062 roles[ IsOnCloud ] = "isOnCloud"; 0063 d->m_roleNames = roles; 0064 } 0065 0066 CloudRouteModel::~CloudRouteModel() 0067 { 0068 delete d; 0069 } 0070 0071 QVariant CloudRouteModel::data( const QModelIndex& index, int role ) const 0072 { 0073 if ( index.isValid() && index.row() >= 0 && index.row() < d->m_items.size() ) { 0074 switch( role ) { 0075 case Qt::DecorationRole: return preview( index ); 0076 case Timestamp: return d->m_items.at( index.row() ).identifier(); 0077 case Name: return d->m_items.at( index.row() ).name(); 0078 case PreviewUrl: return d->m_items.at( index.row() ).previewUrl(); 0079 case Distance: return d->m_items.at( index.row() ).distance(); 0080 case Duration: return d->m_items.at( index.row() ).duration(); 0081 case IsCached: return isCached( index ); 0082 case IsDownloading: return isDownloading( index ); 0083 case IsOnCloud: return d->m_items.at( index.row() ).onCloud(); 0084 } 0085 } 0086 0087 return QVariant(); 0088 } 0089 0090 int CloudRouteModel::rowCount( const QModelIndex &parent ) const 0091 { 0092 return parent.isValid() ? 0 : d->m_items.count(); 0093 } 0094 0095 QHash<int, QByteArray> CloudRouteModel::roleNames() const 0096 { 0097 return d->m_roleNames; 0098 } 0099 0100 void CloudRouteModel::setItems( const QVector<RouteItem> &items ) 0101 { 0102 beginResetModel(); 0103 d->m_items = items; 0104 d->m_previewQueue.clear(); 0105 d->m_requestedPreviews.clear(); 0106 endResetModel(); 0107 } 0108 0109 bool CloudRouteModel::isCached( const QModelIndex &index ) const 0110 { 0111 QFileInfo cacheDir(d->m_cacheDir + index.data(Timestamp).toString() + QLatin1String(".kml")); 0112 return cacheDir.exists(); 0113 } 0114 0115 QPersistentModelIndex CloudRouteModel::downloadingItem() const 0116 { 0117 return d->m_downloading; 0118 } 0119 0120 void CloudRouteModel::setDownloadingItem(const QPersistentModelIndex &index ) 0121 { 0122 d->m_downloading = index; 0123 } 0124 0125 bool CloudRouteModel::isDownloading( const QModelIndex &index ) const 0126 { 0127 return d->m_downloading == index; 0128 } 0129 0130 qint64 CloudRouteModel::totalSize() const 0131 { 0132 return d->m_totalSize; 0133 } 0134 0135 qint64 CloudRouteModel::downloadedSize() const 0136 { 0137 return d->m_downloadedSize; 0138 } 0139 0140 QIcon CloudRouteModel::preview( const QModelIndex &index ) const 0141 { 0142 QString timestamp = d->m_items.at( index.row() ).identifier(); 0143 if( d->m_items.at( index.row() ).preview().isNull() && !d->m_requestedPreviews.contains( timestamp ) ) { 0144 QUrl url( d->m_items.at( index.row() ).previewUrl() ); 0145 QNetworkRequest request( url ); 0146 QNetworkReply *reply = d->m_network.get( request ); 0147 d->m_previewQueue.insert( reply, index.row() ); 0148 d->m_requestedPreviews.insert( timestamp ); 0149 } 0150 0151 return d->m_items.at( index.row() ).preview(); 0152 } 0153 0154 void CloudRouteModel::setPreview( QNetworkReply *reply ) 0155 { 0156 int position = d->m_previewQueue.take( reply ); 0157 0158 if( position >= d->m_items.count() ) { 0159 return; 0160 } 0161 0162 RouteItem &route = d->m_items[ position ]; 0163 QIcon icon( QPixmap::fromImage( QImage::fromData( reply->readAll() ) ) ); 0164 route.setPreview( icon ); 0165 d->m_requestedPreviews.remove( route.identifier() ); 0166 } 0167 0168 void CloudRouteModel::updateProgress( qint64 currentSize, qint64 totalSize ) 0169 { 0170 d->m_totalSize = totalSize; 0171 d->m_downloadedSize = currentSize; 0172 dataChanged( d->m_downloading, d->m_downloading ); 0173 if( currentSize == totalSize ) { 0174 d->m_downloading = QPersistentModelIndex(); 0175 d->m_totalSize = -1; 0176 d->m_downloadedSize = 0; 0177 } 0178 } 0179 0180 } 0181 0182 #include "moc_CloudRouteModel.cpp"