File indexing completed on 2025-01-05 03:58:35
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2006-09-19 0007 * Description : Track file loading and managing 0008 * 0009 * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2010-2014 by Michael G. Hansen <mike at mghansen dot de> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "trackmanager.h" 0017 0018 // Qt includes 0019 0020 #include <QtConcurrentMap> 0021 #include <QFuture> 0022 #include <QFutureWatcher> 0023 0024 // local includes 0025 0026 #include "trackreader.h" 0027 0028 namespace Digikam 0029 { 0030 0031 // TrackManager::TrackPoint --------------------------------------------------- 0032 0033 bool TrackManager::TrackPoint::EarlierThan(const TrackPoint& a, const TrackPoint& b) 0034 { 0035 return (a.dateTime < b.dateTime); 0036 } 0037 0038 // TrackManager --------------------------------------------------------------- 0039 0040 class Q_DECL_HIDDEN TrackManager::Private 0041 { 0042 public: 0043 0044 explicit Private() 0045 : trackLoadFutureWatcher(nullptr), 0046 trackLoadFuture (), 0047 trackList (), 0048 loadErrorFiles (), 0049 nextTrackId (1), 0050 nextTrackColor (0), 0051 visibility (true) 0052 { 0053 } 0054 0055 QFutureWatcher<TrackReader::TrackReadResult>* trackLoadFutureWatcher; 0056 QFuture<TrackReader::TrackReadResult> trackLoadFuture; 0057 TrackManager::Track::List trackPendingList; 0058 TrackManager::Track::List trackList; 0059 QList<QPair<QUrl, QString> > loadErrorFiles; 0060 0061 Id nextTrackId; 0062 int nextTrackColor; 0063 bool visibility; 0064 }; 0065 0066 TrackManager::TrackManager(QObject* const parent) 0067 : QObject(parent), 0068 d (new Private) 0069 { 0070 } 0071 0072 TrackManager::~TrackManager() 0073 { 0074 } 0075 0076 bool TrackManager::getVisibility() const 0077 { 0078 return d->visibility; 0079 } 0080 0081 void TrackManager::setVisibility(const bool value) 0082 { 0083 if (d->visibility == value) 0084 { 0085 return; 0086 } 0087 0088 d->visibility = value; 0089 0090 Q_EMIT signalVisibilityChanged(value); 0091 } 0092 0093 void TrackManager::clear() 0094 { 0095 /// @TODO send a signal 0096 0097 d->trackList.clear(); 0098 d->nextTrackColor = 0; 0099 } 0100 0101 const TrackManager::Track& TrackManager::getTrack(const int index) const 0102 { 0103 return d->trackList.at(index); 0104 } 0105 0106 void TrackManager::loadTrackFiles(const QList<QUrl>& urls) 0107 { 0108 d->trackLoadFutureWatcher = new QFutureWatcher<TrackReader::TrackReadResult>(this); 0109 0110 connect(d->trackLoadFutureWatcher, SIGNAL(resultsReadyAt(int,int)), 0111 this, SLOT(slotTrackFilesReadyAt(int,int))); 0112 0113 connect(d->trackLoadFutureWatcher, SIGNAL(finished()), 0114 this, SLOT(slotTrackFilesFinished())); 0115 0116 d->trackLoadFuture = QtConcurrent::mapped(urls, TrackReader::loadTrackFile); 0117 d->trackLoadFutureWatcher->setFuture(d->trackLoadFuture); 0118 0119 // results are reported to slotTrackFilesReadyAt 0120 } 0121 0122 void TrackManager::slotTrackFilesReadyAt(int beginIndex, int endIndex) 0123 { 0124 /* 0125 const int nFilesBefore = d->trackList.count(); 0126 */ 0127 // note that endIndex is exclusive! 0128 0129 for (int i = beginIndex ; i < endIndex ; ++i) 0130 { 0131 const TrackReader::TrackReadResult nextFile = d->trackLoadFuture.resultAt(i); 0132 0133 if (nextFile.isValid) 0134 { 0135 Track nextTrack = nextFile.track; 0136 nextTrack.id = getNextFreeTrackId(); 0137 nextTrack.color = getNextFreeTrackColor(); 0138 d->trackPendingList << nextTrack; 0139 } 0140 else 0141 { 0142 d->loadErrorFiles << QPair<QUrl, QString>(nextFile.track.url, nextFile.loadError); 0143 } 0144 } 0145 } 0146 0147 void TrackManager::slotTrackFilesFinished() 0148 { 0149 d->trackLoadFutureWatcher->deleteLater(); 0150 0151 d->trackList << d->trackPendingList; 0152 QList<TrackChanges> trackChanges; 0153 0154 Q_FOREACH (const Track& track, d->trackPendingList) 0155 { 0156 trackChanges << TrackChanges(track.id, ChangeAdd); 0157 } 0158 0159 d->trackPendingList.clear(); 0160 0161 Q_EMIT signalAllTrackFilesReady(); 0162 Q_EMIT signalTracksChanged(trackChanges); 0163 } 0164 0165 TrackManager::Track::List TrackManager::getTrackList() const 0166 { 0167 return d->trackList; 0168 } 0169 0170 int TrackManager::trackCount() const 0171 { 0172 return d->trackList.count(); 0173 } 0174 0175 QList<QPair<QUrl, QString> > TrackManager::readLoadErrors() 0176 { 0177 const QList<QPair<QUrl, QString> > result = d->loadErrorFiles; 0178 d->loadErrorFiles.clear(); 0179 0180 return result; 0181 } 0182 0183 quint64 TrackManager::getNextFreeTrackId() 0184 { 0185 const quint64 nextId = d->nextTrackId; 0186 ++(d->nextTrackId); 0187 0188 return nextId; 0189 } 0190 0191 TrackManager::Track TrackManager::getTrackById(const quint64 trackId) const 0192 { 0193 Q_FOREACH (const Track& track, d->trackList) 0194 { 0195 if (track.id == trackId) 0196 { // cppcheck-suppress useStlAlgorithm 0197 return track; 0198 } 0199 } 0200 0201 return TrackManager::Track(); 0202 } 0203 0204 QColor TrackManager::getNextFreeTrackColor() 0205 { 0206 QList<QColor> colorList; 0207 colorList << Qt::red << Qt::blue << Qt::green << Qt::magenta; 0208 0209 const QColor nextColor = colorList.at(d->nextTrackColor); 0210 ++(d->nextTrackColor); 0211 0212 if (d->nextTrackColor >= colorList.count()) 0213 { 0214 d->nextTrackColor = 0; 0215 } 0216 0217 return nextColor; 0218 } 0219 0220 } // namespace Digikam 0221 0222 #include "moc_trackmanager.cpp"