Marble

CloudRouteModel.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2013 Utku Aydın <[email protected]>
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 
21 namespace Marble {
22 
23 class Q_DECL_HIDDEN CloudRouteModel::Private {
24 
25 public:
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 
41 CloudRouteModel::Private::Private() :
42  m_totalSize( -1 ),
43  m_downloadedSize( 0 )
44 {
45  m_cacheDir = MarbleDirs::localPath() + QLatin1String("/cloudsync/cache/routes/");
46 }
47 
48 CloudRouteModel::CloudRouteModel( QObject* parent ) :
49  QAbstractListModel( parent ), d( new Private() )
50 {
51  connect( &(d->m_network), SIGNAL(finished(QNetworkReply*)),
52  this, SLOT(setPreview(QNetworkReply*)) );
53 
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 
66 CloudRouteModel::~CloudRouteModel()
67 {
68  delete d;
69 }
70 
71 QVariant 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 
90 int CloudRouteModel::rowCount( const QModelIndex &parent ) const
91 {
92  return parent.isValid() ? 0 : d->m_items.count();
93 }
94 
95 QHash<int, QByteArray> CloudRouteModel::roleNames() const
96 {
97  return d->m_roleNames;
98 }
99 
100 void 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 
109 bool 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 
115 QPersistentModelIndex CloudRouteModel::downloadingItem() const
116 {
117  return d->m_downloading;
118 }
119 
120 void CloudRouteModel::setDownloadingItem(const QPersistentModelIndex &index )
121 {
122  d->m_downloading = index;
123 }
124 
125 bool CloudRouteModel::isDownloading( const QModelIndex &index ) const
126 {
127  return d->m_downloading == index;
128 }
129 
130 qint64 CloudRouteModel::totalSize() const
131 {
132  return d->m_totalSize;
133 }
134 
135 qint64 CloudRouteModel::downloadedSize() const
136 {
137  return d->m_downloadedSize;
138 }
139 
140 QIcon 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 
154 void 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 
168 void 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"
DecorationRole
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QVariant data(int role) const const
virtual QHash< int, QByteArray > roleNames() const const
Duration
void clear()
Binds a QML item to a specific geodetic location in screen coordinates.
bool isValid() const const
int row() const const
const QChar at(int position) const const
QByteArray readAll()
QImage fromData(const uchar *data, int size, const char *format)
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Oct 4 2023 04:09:41 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.