Marble

CloudRouteModel.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2013 Utku Aydın <utkuaydin34@gmail.com>
4//
5
6#include "CloudRouteModel.h"
7
8#include "RouteItem.h"
9
10#include "MarbleDebug.h"
11#include "MarbleDirs.h"
12
13#include <QIcon>
14#include <QUrl>
15#include <QSet>
16#include <QVector>
17#include <QNetworkRequest>
18#include <QNetworkReply>
19#include <QNetworkAccessManager>
20
21namespace Marble {
22
23class Q_DECL_HIDDEN CloudRouteModel::Private {
24
25public:
26 Private();
27
28 QVector<RouteItem> m_items;
29 QString m_cacheDir;
30 QPersistentModelIndex m_downloading;
31 qint64 m_totalSize;
32 qint64 m_downloadedSize;
33
34 QNetworkAccessManager m_network;
35 QMap<QNetworkReply*, int> m_previewQueue;
36 QSet<QString> m_requestedPreviews;
37
38 QHash<int, QByteArray> m_roleNames;
39};
40
41CloudRouteModel::Private::Private() :
42 m_totalSize( -1 ),
43 m_downloadedSize( 0 )
44{
45 m_cacheDir = MarbleDirs::localPath() + QLatin1String("/cloudsync/cache/routes/");
46}
47
48CloudRouteModel::CloudRouteModel( QObject* parent ) :
49 QAbstractListModel( parent ), d( new Private() )
50{
51 connect( &(d->m_network), SIGNAL(finished(QNetworkReply*)),
52 this, SLOT(setPreview(QNetworkReply*)) );
53
54 QHash<int, QByteArray> roles = roleNames();
55 roles[ Name ] = "name";
56 roles[ Timestamp ] = "identifier";
57 roles[ PreviewUrl ] = "previewUrl";
58 roles[ Distance ] = "distance";
59 roles[ Duration ] = "duration";
60 roles[ IsCached ] = "isCached";
61 roles[ IsDownloading ] = "isDownloading";
62 roles[ IsOnCloud ] = "isOnCloud";
63 d->m_roleNames = roles;
64}
65
66CloudRouteModel::~CloudRouteModel()
67{
68 delete d;
69}
70
71QVariant CloudRouteModel::data( const QModelIndex& index, int role ) const
72{
73 if ( index.isValid() && index.row() >= 0 && index.row() < d->m_items.size() ) {
74 switch( role ) {
75 case Qt::DecorationRole: return preview( index );
76 case Timestamp: return d->m_items.at( index.row() ).identifier();
77 case Name: return d->m_items.at( index.row() ).name();
78 case PreviewUrl: return d->m_items.at( index.row() ).previewUrl();
79 case Distance: return d->m_items.at( index.row() ).distance();
80 case Duration: return d->m_items.at( index.row() ).duration();
81 case IsCached: return isCached( index );
82 case IsDownloading: return isDownloading( index );
83 case IsOnCloud: return d->m_items.at( index.row() ).onCloud();
84 }
85 }
86
87 return QVariant();
88}
89
90int CloudRouteModel::rowCount( const QModelIndex &parent ) const
91{
92 return parent.isValid() ? 0 : d->m_items.count();
93}
94
95QHash<int, QByteArray> CloudRouteModel::roleNames() const
96{
97 return d->m_roleNames;
98}
99
100void CloudRouteModel::setItems( const QVector<RouteItem> &items )
101{
102 beginResetModel();
103 d->m_items = items;
104 d->m_previewQueue.clear();
105 d->m_requestedPreviews.clear();
106 endResetModel();
107}
108
109bool CloudRouteModel::isCached( const QModelIndex &index ) const
110{
111 QFileInfo cacheDir(d->m_cacheDir + index.data(Timestamp).toString() + QLatin1String(".kml"));
112 return cacheDir.exists();
113}
114
115QPersistentModelIndex CloudRouteModel::downloadingItem() const
116{
117 return d->m_downloading;
118}
119
120void CloudRouteModel::setDownloadingItem(const QPersistentModelIndex &index )
121{
122 d->m_downloading = index;
123}
124
125bool CloudRouteModel::isDownloading( const QModelIndex &index ) const
126{
127 return d->m_downloading == index;
128}
129
130qint64 CloudRouteModel::totalSize() const
131{
132 return d->m_totalSize;
133}
134
135qint64 CloudRouteModel::downloadedSize() const
136{
137 return d->m_downloadedSize;
138}
139
140QIcon CloudRouteModel::preview( const QModelIndex &index ) const
141{
142 QString timestamp = d->m_items.at( index.row() ).identifier();
143 if( d->m_items.at( index.row() ).preview().isNull() && !d->m_requestedPreviews.contains( timestamp ) ) {
144 QUrl url( d->m_items.at( index.row() ).previewUrl() );
145 QNetworkRequest request( url );
146 QNetworkReply *reply = d->m_network.get( request );
147 d->m_previewQueue.insert( reply, index.row() );
148 d->m_requestedPreviews.insert( timestamp );
149 }
150
151 return d->m_items.at( index.row() ).preview();
152}
153
154void CloudRouteModel::setPreview( QNetworkReply *reply )
155{
156 int position = d->m_previewQueue.take( reply );
157
158 if( position >= d->m_items.count() ) {
159 return;
160 }
161
162 RouteItem &route = d->m_items[ position ];
163 QIcon icon( QPixmap::fromImage( QImage::fromData( reply->readAll() ) ) );
164 route.setPreview( icon );
165 d->m_requestedPreviews.remove( route.identifier() );
166}
167
168void CloudRouteModel::updateProgress( qint64 currentSize, qint64 totalSize )
169{
170 d->m_totalSize = totalSize;
171 d->m_downloadedSize = currentSize;
172 dataChanged( d->m_downloading, d->m_downloading );
173 if( currentSize == totalSize ) {
174 d->m_downloading = QPersistentModelIndex();
175 d->m_totalSize = -1;
176 d->m_downloadedSize = 0;
177 }
178}
179
180}
181
182#include "moc_CloudRouteModel.cpp"
Binds a QML item to a specific geodetic location in screen coordinates.
QImage fromData(QByteArrayView data, const char *format)
QByteArray readAll()
void clear()
QVariant data(int role) const const
bool isValid() const const
int row() const const
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
const QChar at(qsizetype position) const const
DecorationRole
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.