Merge lp:~schwann/gallery-app/gallery-datastructure-load into lp:gallery-app

Proposed by Günter Schwann
Status: Merged
Approved by: Günter Schwann
Approved revision: 768
Merged at revision: 766
Proposed branch: lp:~schwann/gallery-app/gallery-datastructure-load
Merge into: lp:gallery-app
Diff against target: 938 lines (+349/-114)
20 files modified
src/database/media-table.cpp (+25/-39)
src/database/media-table.h (+7/-2)
src/gallery-application.cpp (+3/-1)
src/gallery-manager.cpp (+25/-28)
src/gallery-manager.h (+1/-0)
src/media-object-factory.cpp (+81/-3)
src/media-object-factory.h (+15/-2)
src/media/media-collection.cpp (+32/-1)
src/media/media-collection.h (+5/-1)
src/media/media-monitor.cpp (+77/-6)
src/media/media-monitor.h (+15/-5)
src/photo/photo-caches.cpp (+1/-1)
src/qml/qml-media-collection-model.cpp (+1/-1)
tests/autopilot/gallery_app/emulators/gallery_utils.py (+1/-6)
tests/autopilot/gallery_app/tests/test_events_view.py (+7/-4)
tests/autopilot/gallery_app/tests/test_photo_viewer.py (+8/-6)
tests/autopilot/gallery_app/tests/test_photos_view.py (+7/-4)
tests/unittests/mediaobjectfactory/tst_mediaobjectfactory.cpp (+29/-0)
tests/unittests/stubs/gallery-manager_stub.cpp (+5/-0)
tests/unittests/stubs/media-table_stub.cpp (+4/-4)
To merge this branch: bzr merge lp:~schwann/gallery-app/gallery-datastructure-load
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Thomas Moenicke (community) Approve
Review via email: mp+172348@code.launchpad.net

Commit message

Load the media object from the DB without checkin for the files (and separate queries)
Do a datastructure / file syetem consitency check in a background thread

Description of the change

Load the whole media collection in go from the DB.
Do a consistency check afterwards in the background.
Gallery now reacts properly when files are deleted on the file system.
Usually the "Loading..." Screen is now shown anymore.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Thomas Moenicke (thomas-moenicke) wrote :

looks like in addMedia the Video* pointer is not really needed

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Günter Schwann (schwann) wrote :

Top approving again - now that jenkins seems to work ok again

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/database/media-table.cpp'
--- src/database/media-table.cpp 2013-06-28 12:33:19 +0000
+++ src/database/media-table.cpp 2013-07-02 13:33:30 +0000
@@ -34,45 +34,6 @@
34}34}
3535
36/*!36/*!
37 * \brief MediaTable::verifyFiles
38 * Runs though the table, removes references to files
39 * that have been deleted from disk.
40 */
41void MediaTable::verifyFiles()
42{
43 QSqlQuery query(*m_db->getDB());
44 QList<qint64> to_delete;
45 query.prepare("SELECT id, filename FROM MediaTable");
46 if (!query.exec())
47 m_db->logSqlError(query);
48
49 // Stat each file. Make a list of files that no longer exist.
50 while (query.next()) {
51 // stat'ing and sync'ing file info over even several hundred photos is an
52 // expensive operation since it involves lots of I/O, so spin the event
53 // loop so that the UI remains responsive
54 QApplication::processEvents();
55
56 qint64 id = query.value(0).toLongLong();
57 QFile file(query.value(1).toString());
58
59 if (!file.exists())
60 to_delete.append(id);
61 }
62
63 // Delete any references to non-existent files.
64 m_db->getDB()->transaction();
65 foreach (qint64 id, to_delete) {
66 // spin the event loop so that the UI remains responsive
67 QApplication::processEvents();
68
69 remove(id);
70 }
71
72 m_db->getDB()->commit();
73}
74
75/*!
76 * \brief MediaTable::getIdForMedia Returns the row ID for the given photo.37 * \brief MediaTable::getIdForMedia Returns the row ID for the given photo.
77 * \param filename38 * \param filename
78 * \return Returns the row ID for the given photo. If none exists, -1 will be returned.39 * \return Returns the row ID for the given photo. If none exists, -1 will be returned.
@@ -263,6 +224,31 @@
263}224}
264225
265/*!226/*!
227 * \brief MediaTable::emitAllRows goes through the whole DB and emits a row() signal
228 * for every single row with all the Database
229 */
230void MediaTable::emitAllRows()
231{
232 QSqlQuery query(*m_db->getDB());
233 query.prepare("SELECT * FROM MediaTable");
234 if (!query.exec())
235 m_db->logSqlError(query);
236
237 while (query.next()) {
238 qint64 id = query.value(0).toInt();
239 QString filename = query.value(1).toString();
240 QSize size(query.value(2).toInt(), query.value(3).toInt());
241 QDateTime timestamp;
242 timestamp.setMSecsSinceEpoch(query.value(4).toLongLong());
243 QDateTime exposuretime;
244 exposuretime.setMSecsSinceEpoch(query.value(5).toLongLong());
245 Orientation orientation = static_cast<Orientation>(query.value(6).toInt());
246 qint64 filesize = query.value(7).toInt();
247 emit row(id, filename, size, timestamp, exposuretime, orientation, filesize);
248 }
249}
250
251/*!
266 * \brief MediaTable::getRow Gets a row that already exists252 * \brief MediaTable::getRow Gets a row that already exists
267 * \param mediaId253 * \param mediaId
268 * \param size254 * \param size
269255
=== modified file 'src/database/media-table.h'
--- src/database/media-table.h 2013-06-28 12:33:19 +0000
+++ src/database/media-table.h 2013-07-02 13:33:30 +0000
@@ -37,8 +37,6 @@
37public:37public:
38 explicit MediaTable(Database* db, QObject *parent = 0);38 explicit MediaTable(Database* db, QObject *parent = 0);
3939
40 void verifyFiles();
41
42 qint64 getIdForMedia(const QString& filename);40 qint64 getIdForMedia(const QString& filename);
4341
44 qint64 createIdForMedia(const QString& filename, const QDateTime& timestamp,42 qint64 createIdForMedia(const QString& filename, const QDateTime& timestamp,
@@ -63,6 +61,13 @@
6361
64 QDateTime getExposureTime(qint64 mediaId);62 QDateTime getExposureTime(qint64 mediaId);
6563
64 void emitAllRows();
65
66signals:
67 void row(qint64 mediaId, const QString& filename, const QSize& size,
68 const QDateTime& timestamp, const QDateTime& exposureTime,
69 Orientation originalOrientation, qint64 filesize);
70
66private:71private:
67 Database* m_db;72 Database* m_db;
68};73};
6974
=== modified file 'src/gallery-application.cpp'
--- src/gallery-application.cpp 2013-06-28 11:53:54 +0000
+++ src/gallery-application.cpp 2013-07-02 13:33:30 +0000
@@ -206,7 +206,10 @@
206 filterType = MediaSource::Photo;206 filterType = MediaSource::Photo;
207 m_galleryManager->enableContentLoadFilter(filterType);207 m_galleryManager->enableContentLoadFilter(filterType);
208 }208 }
209 QApplication::processEvents();
210
209 m_galleryManager->postInit();211 m_galleryManager->postInit();
212 QApplication::processEvents();
210 if (m_cmdLineParser->startupTimer())213 if (m_cmdLineParser->startupTimer())
211 qDebug() << "GalleryManager initialized" << m_timer->elapsed() << "ms";214 qDebug() << "GalleryManager initialized" << m_timer->elapsed() << "ms";
212215
@@ -230,4 +233,3 @@
230233
231 m_timer->restart();234 m_timer->restart();
232}235}
233
234236
=== modified file 'src/gallery-manager.cpp'
--- src/gallery-manager.cpp 2013-07-01 07:40:13 +0000
+++ src/gallery-manager.cpp 2013-07-02 13:33:30 +0000
@@ -193,13 +193,12 @@
193 m_database = new Database(m_resource->databaseDirectory(),193 m_database = new Database(m_resource->databaseDirectory(),
194 m_resource->getRcUrl("sql").path());194 m_resource->getRcUrl("sql").path());
195 m_mediaFactory->setMediaTable(m_database->getMediaTable());195 m_mediaFactory->setMediaTable(m_database->getMediaTable());
196 m_database->getMediaTable()->verifyFiles();
197 m_defaultTemplate = new AlbumDefaultTemplate();196 m_defaultTemplate = new AlbumDefaultTemplate();
198 m_mediaCollection = new MediaCollection();197 m_mediaCollection = new MediaCollection();
199198
200 initPreviewManager();199 initPreviewManager();
200 fillMediaCollection();
201 startFileMonitoring();201 startFileMonitoring();
202 fillMediaCollection();
203202
204 collectionsInitialised = true;203 collectionsInitialised = true;
205204
@@ -229,7 +228,7 @@
229EventCollection *GalleryManager::eventCollection()228EventCollection *GalleryManager::eventCollection()
230{229{
231 if (!m_eventCollection)230 if (!m_eventCollection)
232 m_eventCollection = new EventCollection;231 m_eventCollection = new EventCollection();
233232
234 return m_eventCollection;233 return m_eventCollection;
235}234}
@@ -303,23 +302,10 @@
303{302{
304 Q_ASSERT(m_mediaCollection);303 Q_ASSERT(m_mediaCollection);
305304
306 QSet<DataObject*> photos;305 QSet<DataObject*> medias;
307 foreach (const QString &dirName, m_resource->mediaDirectories()) {306 medias = m_mediaFactory->mediasFromDB();
308 QDir mediaDir(dirName);307 m_mediaCollection->addMany(medias);
309 mediaDir.setFilter(QDir::Files);308 m_mediaFactory->clear();
310 mediaDir.setSorting(QDir::Name);
311
312 const QStringList filenames = mediaDir.entryList();
313 foreach (const QString& filename, filenames) {
314 QFileInfo file(mediaDir, filename);
315 DataObject *media = m_mediaFactory->create(file);
316 if (media) {
317 photos.insert(media);
318 }
319 }
320 }
321
322 m_mediaCollection->addMany(photos);
323}309}
324310
325/*!311/*!
@@ -334,7 +320,11 @@
334 m_monitor = new MediaMonitor();320 m_monitor = new MediaMonitor();
335 QObject::connect(m_monitor, SIGNAL(mediaItemAdded(QString)),321 QObject::connect(m_monitor, SIGNAL(mediaItemAdded(QString)),
336 this, SLOT(onMediaItemAdded(QString)));322 this, SLOT(onMediaItemAdded(QString)));
323 QObject::connect(m_monitor, SIGNAL(mediaItemRemoved(qint64)),
324 this, SLOT(onMediaItemRemoved(qint64)));
325
337 m_monitor->startMonitoring(m_resource->mediaDirectories());326 m_monitor->startMonitoring(m_resource->mediaDirectories());
327 m_monitor->checkConsitency(m_mediaCollection);
338}328}
339329
340/*!330/*!
@@ -343,12 +333,19 @@
343 */333 */
344void GalleryManager::onMediaItemAdded(QString file)334void GalleryManager::onMediaItemAdded(QString file)
345{335{
346 QFileInfo fi(file);336 if (! m_mediaCollection->containsFile(file)) {
347 MediaSource* media = m_mediaCollection->mediaFromFileinfo(fi);337 QFileInfo fi(file);
348 if (media == 0) {338 MediaSource *media = m_mediaFactory->create(fi);
349 media = m_mediaFactory->create(fi);339 if (media)
350 }340 m_mediaCollection->add(media);
351 if (media) {341 }
352 m_mediaCollection->add(media);342}
353 }343
344/*!
345 * \brief GalleryManager::onMediaItemRemoved
346 * \param mediaId
347 */
348void GalleryManager::onMediaItemRemoved(qint64 mediaId)
349{
350 m_mediaCollection->destroy(mediaId);
354}351}
355352
=== modified file 'src/gallery-manager.h'
--- src/gallery-manager.h 2013-06-28 20:38:44 +0000
+++ src/gallery-manager.h 2013-07-02 13:33:30 +0000
@@ -84,6 +84,7 @@
8484
85private slots:85private slots:
86 void onMediaItemAdded(QString file);86 void onMediaItemAdded(QString file);
87 void onMediaItemRemoved(qint64 mediaId);
8788
88private:89private:
89 GalleryManager(const GalleryManager&);90 GalleryManager(const GalleryManager&);
9091
=== modified file 'src/media-object-factory.cpp'
--- src/media-object-factory.cpp 2013-06-28 12:33:19 +0000
+++ src/media-object-factory.cpp 2013-07-02 13:33:30 +0000
@@ -59,6 +59,43 @@
59}59}
6060
61/*!61/*!
62 * \brief MediaObjectFactory::photosFromDB creates a set with all photos and video
63 * stored in the DB.
64 * Someone else needs to take the responsibility to delete all the objects in the set.
65 * You should call clear() afterwards, to remove temporary data.
66 * \return All medias stored in the DB
67 */
68QSet<DataObject *> MediaObjectFactory::mediasFromDB()
69{
70 Q_ASSERT(m_mediaTable);
71
72 m_mediasFromDB.clear();
73
74 connect(m_mediaTable,
75 SIGNAL(row(qint64,QString,QSize,QDateTime,QDateTime,Orientation,qint64)),
76 this,
77 SLOT(addMedia(qint64,QString,QSize,QDateTime,QDateTime,Orientation,qint64)));
78
79 m_mediaTable->emitAllRows();
80
81 disconnect(m_mediaTable,
82 SIGNAL(row(qint64,QString,QSize,QDateTime,QDateTime,Orientation,qint64)),
83 this,
84 SLOT(addMedia(qint64,QString,QSize,QDateTime,QDateTime,Orientation,qint64)));
85
86 return m_mediasFromDB;
87}
88
89/*!
90 * \brief MediaObjectFactory::clear
91 */
92void MediaObjectFactory::clear()
93{
94 clearMetadata();
95 m_mediasFromDB.clear();
96}
97
98/*!
62 * \brief MediaObjectFactory::create loads the data for a photo or video file.99 * \brief MediaObjectFactory::create loads the data for a photo or video file.
63 * Creates / updates the database as well.100 * Creates / updates the database as well.
64 * \param file the file to load101 * \param file the file to load
@@ -89,13 +126,11 @@
89126
90 MediaSource *media = 0;127 MediaSource *media = 0;
91 Photo *photo = 0;128 Photo *photo = 0;
92 Video *video = 0;
93 if (mediaType == MediaSource::Photo) {129 if (mediaType == MediaSource::Photo) {
94 photo = new Photo(file);130 photo = new Photo(file);
95 media = photo;131 media = photo;
96 } else {132 } else {
97 video = new Video(file);133 media = new Video(file);
98 media = video;
99 }134 }
100135
101 if (id == INVALID_ID) {136 if (id == INVALID_ID) {
@@ -129,6 +164,49 @@
129}164}
130165
131/*!166/*!
167 * \brief MediaObjectFactory::addMedia creates a media object, and adds it to the
168 * internal set. This is used for mediasFromDB().
169 * \param mediaId
170 * \param filename
171 * \param size
172 * \param timestamp
173 * \param exposureTime
174 * \param originalOrientation
175 * \param filesize
176 * \return
177 */
178void MediaObjectFactory::addMedia(qint64 mediaId, const QString &filename,
179 const QSize &size, const QDateTime &timestamp,
180 const QDateTime &exposureTime,
181 Orientation originalOrientation, qint64 filesize)
182{
183 Q_UNUSED(filesize);
184
185 QFileInfo file(filename);
186 MediaSource::MediaType mediaType = MediaSource::Photo;
187 if (Video::isCameraVideo(file))
188 mediaType = MediaSource::Video;
189
190 MediaSource *media = 0;
191 Photo *photo = 0;
192 if (mediaType == MediaSource::Photo) {
193 photo = new Photo(file);
194 media = photo;
195 } else {
196 media = new Video(file);
197 }
198
199 media->setSize(size);
200 media->setFileTimestamp(timestamp);
201 media->setExposureDateTime(exposureTime);
202 if (mediaType == MediaSource::Photo)
203 photo->setOriginalOrientation(originalOrientation);
204 media->setId(mediaId);
205
206 m_mediasFromDB.insert(media);
207}
208
209/*!
132 * \brief MediaObjectFactory::clearMetadata resets all memeber variables210 * \brief MediaObjectFactory::clearMetadata resets all memeber variables
133 * regarding metadata211 * regarding metadata
134 */212 */
135213
=== modified file 'src/media-object-factory.h'
--- src/media-object-factory.h 2013-06-26 08:59:08 +0000
+++ src/media-object-factory.h 2013-07-02 13:33:30 +0000
@@ -25,6 +25,7 @@
2525
26#include <QDateTime>26#include <QDateTime>
27#include <QFileInfo>27#include <QFileInfo>
28#include <QObject>
28#include <QSize>29#include <QSize>
2930
30class MediaTable;31class MediaTable;
@@ -32,17 +33,27 @@
32/*!33/*!
33 * \brief The MediaObjectFactory creates phot and video objects34 * \brief The MediaObjectFactory creates phot and video objects
34 */35 */
35class MediaObjectFactory36class MediaObjectFactory : public QObject
36{37{
38 Q_OBJECT
39
37public:40public:
38 explicit MediaObjectFactory();41 explicit MediaObjectFactory();
3942
40 void setMediaTable(MediaTable *mediaTable);43 void setMediaTable(MediaTable *mediaTable);
41 void enableContentLoadFilter(MediaSource::MediaType filterType);44 void enableContentLoadFilter(MediaSource::MediaType filterType);
4245
46 QSet<DataObject*> mediasFromDB();
47 void clear();
48
43 MediaSource *create(const QFileInfo& file);49 MediaSource *create(const QFileInfo& file);
4450
45private:51private slots:
52 void addMedia(qint64 mediaId, const QString& filename, const QSize& size,
53 const QDateTime& timestamp, const QDateTime& exposureTime,
54 Orientation originalOrientation, qint64 filesize);
55
56private:
46 void clearMetadata();57 void clearMetadata();
47 bool readPhotoMetadata(const QFileInfo &file);58 bool readPhotoMetadata(const QFileInfo &file);
48 bool readVideoMetadata(const QFileInfo &file);59 bool readVideoMetadata(const QFileInfo &file);
@@ -56,6 +67,8 @@
5667
57 MediaSource::MediaType m_filterType;68 MediaSource::MediaType m_filterType;
5869
70 QSet<DataObject*> m_mediasFromDB;
71
59 friend class tst_MediaObjectFactory;72 friend class tst_MediaObjectFactory;
60};73};
6174
6275
=== modified file 'src/media/media-collection.cpp'
--- src/media/media-collection.cpp 2013-06-10 07:37:09 +0000
+++ src/media/media-collection.cpp 2013-07-02 13:33:30 +0000
@@ -137,12 +137,22 @@
137 * \param file_to_load137 * \param file_to_load
138 * \return138 * \return
139 */139 */
140MediaSource *MediaCollection::mediaFromFileinfo(const QFileInfo& file)140const MediaSource *MediaCollection::mediaFromFileinfo(const QFileInfo& file) const
141{141{
142 return m_fileMediaMap.value(file.absoluteFilePath(), 0);142 return m_fileMediaMap.value(file.absoluteFilePath(), 0);
143}143}
144144
145/*!145/*!
146 * \brief MediaCollection::containsFile
147 * \param filename
148 * \return
149 */
150bool MediaCollection::containsFile(const QString &filename) const
151{
152 return m_fileMediaMap.contains(filename);
153}
154
155/*!
146 * \reimp156 * \reimp
147 */157 */
148void MediaCollection::addMany(const QSet<DataObject *> &objects)158void MediaCollection::addMany(const QSet<DataObject *> &objects)
@@ -154,3 +164,24 @@
154164
155 DataCollection::addMany(objects);165 DataCollection::addMany(objects);
156}166}
167
168/*!
169 * \brief MediaCollection::destroy
170 * \param media
171 */
172void MediaCollection::destroy(MediaSource *media)
173{
174 SourceCollection::destroy(media, true, true);
175}
176
177/*!
178 * \brief MediaCollection::remove
179 * \param id
180 */
181void MediaCollection::destroy(qint64 id)
182{
183 if (m_idMap.contains(id)) {
184 MediaSource *media = qobject_cast<MediaSource*>(m_idMap[id]);
185 SourceCollection::destroy(media, true, true);
186 }
187}
157188
=== modified file 'src/media/media-collection.h'
--- src/media/media-collection.h 2013-06-10 06:32:08 +0000
+++ src/media/media-collection.h 2013-07-02 13:33:30 +0000
@@ -44,10 +44,14 @@
44 static bool exposureDateTimeDescendingComparator(DataObject* a, DataObject* b);44 static bool exposureDateTimeDescendingComparator(DataObject* a, DataObject* b);
4545
46 MediaSource* mediaForId(qint64 id);46 MediaSource* mediaForId(qint64 id);
47 MediaSource* mediaFromFileinfo(const QFileInfo &file);47 const MediaSource* mediaFromFileinfo(const QFileInfo &file) const;
48 bool containsFile(const QString& filename) const;
4849
49 virtual void addMany(const QSet<DataObject*>& objects);50 virtual void addMany(const QSet<DataObject*>& objects);
5051
52 void destroy(MediaSource *media);
53 void destroy(qint64 id);
54
51protected slots:55protected slots:
52 virtual void notifyContentsChanged(const QSet<DataObject*>* added,56 virtual void notifyContentsChanged(const QSet<DataObject*>* added,
53 const QSet<DataObject*>* removed);57 const QSet<DataObject*>* removed);
5458
=== modified file 'src/media/media-monitor.cpp'
--- src/media/media-monitor.cpp 2013-06-28 11:53:54 +0000
+++ src/media/media-monitor.cpp 2013-07-02 13:33:30 +0000
@@ -18,14 +18,17 @@
18 */18 */
1919
20#include "media-monitor.h"20#include "media-monitor.h"
21#include "media-collection.h"
22#include "media-source.h"
2123
22#include <QDir>24#include <QDir>
25#include <QElapsedTimer>
26#include <QFileInfo>
23#include <QSet>27#include <QSet>
24#include <QString>28#include <QString>
2529
26/*!30/*!
27 * \brief MediaMonitor::MediaMonitor31 * \brief MediaMonitor::MediaMonitor
28 * \param targetDirectory
29 */32 */
30MediaMonitor::MediaMonitor(QObject *parent)33MediaMonitor::MediaMonitor(QObject *parent)
31 : QObject(parent),34 : QObject(parent),
@@ -38,6 +41,8 @@
3841
39 QObject::connect(m_worker, SIGNAL(mediaItemAdded(QString)),42 QObject::connect(m_worker, SIGNAL(mediaItemAdded(QString)),
40 this, SIGNAL(mediaItemAdded(QString)), Qt::QueuedConnection);43 this, SIGNAL(mediaItemAdded(QString)), Qt::QueuedConnection);
44 QObject::connect(m_worker, SIGNAL(mediaItemRemoved(qint64)),
45 this, SIGNAL(mediaItemRemoved(qint64)), Qt::QueuedConnection);
4146
42 m_workerThread.start(QThread::LowPriority);47 m_workerThread.start(QThread::LowPriority);
43}48}
@@ -52,7 +57,8 @@
52}57}
5358
54/*!59/*!
55 * \brief MediaMonitor::startMonitoring60 * \brief MediaMonitor::startMonitoring starts monitoring the given directories
61 * new and delted files
56 * \param targetDirectories62 * \param targetDirectories
57 */63 */
58void MediaMonitor::startMonitoring(const QStringList &targetDirectories)64void MediaMonitor::startMonitoring(const QStringList &targetDirectories)
@@ -61,10 +67,20 @@
61 Q_ARG(QStringList, targetDirectories));67 Q_ARG(QStringList, targetDirectories));
62}68}
6369
70/*!
71 * \brief MediaMonitor::checkConsitency checks the given datastructure, if it is
72 * in sync with the file system (files got added, deleted meanwhile)
73 * \param mediaCollection
74 */
75void MediaMonitor::checkConsitency(const MediaCollection *mediaCollection)
76{
77 m_worker->setMediaCollection(mediaCollection);
78 QMetaObject::invokeMethod(m_worker, "checkConsitency", Qt::QueuedConnection);
79}
80
6481
65/*!82/*!
66 * \brief MediaMonitor::MediaMonitor83 * \brief MediaMonitor::MediaMonitor
67 * \param targetDirectory
68 */84 */
69MediaMonitorWorker::MediaMonitorWorker(QObject *parent)85MediaMonitorWorker::MediaMonitorWorker(QObject *parent)
70 : QObject(parent),86 : QObject(parent),
@@ -89,6 +105,15 @@
89}105}
90106
91/*!107/*!
108 * \brief MediaMonitorWorker::setMediaCollection
109 * \param mediaCollection
110 */
111void MediaMonitorWorker::setMediaCollection(const MediaCollection *mediaCollection)
112{
113 m_mediaCollection = mediaCollection;
114}
115
116/*!
92 * \brief MediaMonitor::startMonitoring117 * \brief MediaMonitor::startMonitoring
93 * \param targetDirectories118 * \param targetDirectories
94 */119 */
@@ -105,6 +130,16 @@
105}130}
106131
107/*!132/*!
133 * \brief MediaMonitorWorker::checkConsitency
134 * \param mediaCollection
135 */
136void MediaMonitorWorker::checkConsitency()
137{
138 checkForRemovedMedias();
139 checkForNewMedias();
140}
141
142/*!
108 * \brief MediaMonitor::onDirectoryEvent143 * \brief MediaMonitor::onDirectoryEvent
109 * \param eventSource144 * \param eventSource
110 */145 */
@@ -120,9 +155,17 @@
120{155{
121 QStringList new_manifest = getManifest(m_targetDirectories);156 QStringList new_manifest = getManifest(m_targetDirectories);
122157
123 QStringList difference = subtractManifest(new_manifest, m_manifest);158 QStringList added = subtractManifest(new_manifest, m_manifest);
124 for (int i = 0; i < difference.size(); i++)159 for (int i = 0; i < added.size(); i++)
125 emit mediaItemAdded(difference.at(i));160 emit mediaItemAdded(added.at(i));
161
162 QStringList removed = subtractManifest(m_manifest, new_manifest);
163 for (int i = 0; i < removed.size(); i++) {
164 QFileInfo file(removed.at(i));
165 const MediaSource *media = m_mediaCollection->mediaFromFileinfo(file);
166 if (media)
167 emit mediaItemRemoved(media->id());
168 }
126169
127 m_manifest = new_manifest;170 m_manifest = new_manifest;
128}171}
@@ -158,3 +201,31 @@
158 result.subtract(QSet<QString>::fromList(m2));201 result.subtract(QSet<QString>::fromList(m2));
159 return QStringList(result.toList());202 return QStringList(result.toList());
160}203}
204
205/*!
206 * \brief MediaMonitorWorker::checkForNewMedias checks for files in the filesystem
207 * that are not in the datastructure
208 * \param mediaCollection
209 */
210void MediaMonitorWorker::checkForNewMedias()
211{
212 foreach (const QString& file, m_manifest) {
213 if (!m_mediaCollection->containsFile(file))
214 emit mediaItemAdded(file);
215 }
216}
217
218/*!
219 * \brief MediaMonitorWorker::checkForRemovedMedias checks if there are files in
220 * the datastructure, but not in the file system
221 */
222void MediaMonitorWorker::checkForRemovedMedias()
223{
224 const QList<DataObject*> medias = m_mediaCollection->getAll();
225 foreach (const DataObject* obj, medias) {
226 const MediaSource *media = qobject_cast<const MediaSource*>(obj);
227 Q_ASSERT(media);
228 if (!m_manifest.contains(media->file().absoluteFilePath()))
229 emit mediaItemRemoved(media->id());
230 }
231}
161232
=== modified file 'src/media/media-monitor.h'
--- src/media/media-monitor.h 2013-06-28 11:53:54 +0000
+++ src/media/media-monitor.h 2013-07-02 13:33:30 +0000
@@ -26,11 +26,13 @@
26#include <QThread>26#include <QThread>
27#include <QTimer>27#include <QTimer>
2828
29class MediaCollection;
29class MediaMonitorWorker;30class MediaMonitorWorker;
3031
31/*!32/*!
32 * \brief The MediaMonitor class monitor directories for added files33 * \brief The MediaMonitor class monitor directories for added files. And does a
33 * All it's time consuming tasks are automaticly run in a separate thread34 * check if the files in the datastructure and on thef ile system are in sync.
35 * All this is done in an extra thread.
34 */36 */
35class MediaMonitor : public QObject37class MediaMonitor : public QObject
36{38{
@@ -41,9 +43,11 @@
41 virtual ~MediaMonitor();43 virtual ~MediaMonitor();
4244
43 void startMonitoring(const QStringList& targetDirectories);45 void startMonitoring(const QStringList& targetDirectories);
46 void checkConsitency(const MediaCollection *mediaCollection);
4447
45signals:48signals:
46 void mediaItemAdded(QString newItem);49 void mediaItemAdded(QString newItem);
50 void mediaItemRemoved(qint64 mediaId);
4751
48private:52private:
49 MediaMonitorWorker* m_worker;53 MediaMonitorWorker* m_worker;
@@ -63,25 +67,31 @@
63 MediaMonitorWorker(QObject *parent=0);67 MediaMonitorWorker(QObject *parent=0);
64 virtual ~MediaMonitorWorker();68 virtual ~MediaMonitorWorker();
6569
70 void setMediaCollection(const MediaCollection *mediaCollection);
71
66public slots:72public slots:
67 void startMonitoring(const QStringList& targetDirectories);73 void startMonitoring(const QStringList& targetDirectories);
74 void checkConsitency();
6875
69signals:76signals:
70 void mediaItemAdded(QString newItem);77 void mediaItemAdded(QString newItem);
78 void mediaItemRemoved(qint64 mediaId);
7179
72private slots:80private slots:
73 void onDirectoryEvent(const QString& eventSource);81 void onDirectoryEvent(const QString& eventSource);
74 void onFileActivityCeased();82 void onFileActivityCeased();
7583
76private:84private:
77 static QStringList getManifest(const QStringList& dirs);85 QStringList getManifest(const QStringList& dirs);
78 static QStringList subtractManifest(const QStringList& m1,86 QStringList subtractManifest(const QStringList& m1, const QStringList& m2);
79 const QStringList& m2);87 void checkForNewMedias();
88 void checkForRemovedMedias();
8089
81 QStringList m_targetDirectories;90 QStringList m_targetDirectories;
82 QFileSystemWatcher m_watcher;91 QFileSystemWatcher m_watcher;
83 QStringList m_manifest;92 QStringList m_manifest;
84 QTimer m_fileActivityTimer;93 QTimer m_fileActivityTimer;
94 const MediaCollection *m_mediaCollection;
85};95};
8696
87#endif // GALLERY_MEDIA_MONITOR_H_97#endif // GALLERY_MEDIA_MONITOR_H_
8898
=== modified file 'src/photo/photo-caches.cpp'
--- src/photo/photo-caches.cpp 2013-06-10 07:59:26 +0000
+++ src/photo/photo-caches.cpp 2013-07-02 13:33:30 +0000
@@ -102,7 +102,7 @@
102102
103 m_file.dir().mkdir(ORIGINAL_DIR);103 m_file.dir().mkdir(ORIGINAL_DIR);
104104
105 return rename(m_file, m_originalFile);105 return copy(m_file, m_originalFile);
106}106}
107107
108/*!108/*!
109109
=== modified file 'src/qml/qml-media-collection-model.cpp'
--- src/qml/qml-media-collection-model.cpp 2013-06-11 19:44:28 +0000
+++ src/qml/qml-media-collection-model.cpp 2013-07-02 13:33:30 +0000
@@ -93,7 +93,7 @@
93 MediaSource* media = VariantToObject<MediaSource*>(vmedia);93 MediaSource* media = VariantToObject<MediaSource*>(vmedia);
9494
95 if (media != NULL)95 if (media != NULL)
96 GalleryManager::instance()->mediaCollection()->destroy(media, true, true);96 GalleryManager::instance()->mediaCollection()->destroy(media);
97}97}
9898
99/*!99/*!
100100
=== modified file 'tests/autopilot/gallery_app/emulators/gallery_utils.py'
--- tests/autopilot/gallery_app/emulators/gallery_utils.py 2013-06-21 16:00:49 +0000
+++ tests/autopilot/gallery_app/emulators/gallery_utils.py 2013-07-02 13:33:30 +0000
@@ -119,12 +119,7 @@
119 def get_first_image_in_event_view(self):119 def get_first_image_in_event_view(self):
120 """Returns the first photo of the gallery."""120 """Returns the first photo of the gallery."""
121 event = self.get_first_event()121 event = self.get_first_event()
122 list_view = event.get_children_by_type("QQuickListView")[0]122 return event.select_many("OrganicItemInteraction")[1]
123 item = list_view.get_children_by_type("QQuickItem")[0]
124 first_delegate = item.get_children_by_type("QQuickItem",
125 objectName="eventPhoto")[0]
126 first_photo = first_delegate.get_children_by_type("UbuntuShape")[0]
127 return first_photo
128123
129 def get_all_albums(self):124 def get_all_albums(self):
130 """Returns all albums in the albums view"""125 """Returns all albums in the albums view"""
131126
=== modified file 'tests/autopilot/gallery_app/tests/test_events_view.py'
--- tests/autopilot/gallery_app/tests/test_events_view.py 2013-06-26 09:02:33 +0000
+++ tests/autopilot/gallery_app/tests/test_events_view.py 2013-07-02 13:33:30 +0000
@@ -47,6 +47,11 @@
47 first_photo = self.events_view.get_first_image_in_event_view()47 first_photo = self.events_view.get_first_image_in_event_view()
48 self.click_item(first_photo)48 self.click_item(first_photo)
4949
50 def get_delete_dialog(self):
51 delete_dialog = self.gallery_utils.get_delete_dialog()
52 self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
53 return delete_dialog
54
50 def click_delete_action(self):55 def click_delete_action(self):
51 trash_button = self.events_view.get_toolbar_delete_button()56 trash_button = self.events_view.get_toolbar_delete_button()
52 self.click_item(trash_button)57 self.click_item(trash_button)
@@ -69,8 +74,7 @@
69 self.click_first_photo()74 self.click_first_photo()
70 self.click_delete_action()75 self.click_delete_action()
7176
72 delete_dialog = self.events_view.get_delete_dialog()77 delete_dialog = self.get_delete_dialog()
73 self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
7478
75 cancel_item = self.events_view.get_delete_dialog_cancel_button()79 cancel_item = self.events_view.get_delete_dialog_cancel_button()
76 self.click_item(cancel_item)80 self.click_item(cancel_item)
@@ -83,8 +87,7 @@
8387
84 self.click_delete_action()88 self.click_delete_action()
8589
86 delete_dialog = self.events_view.get_delete_dialog()90 delete_dialog = self.get_delete_dialog()
87 self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
8891
89 delete_item = self.events_view.get_delete_dialog_delete_button()92 delete_item = self.events_view.get_delete_dialog_delete_button()
90 self.click_item(delete_item)93 self.click_item(delete_item)
9194
=== modified file 'tests/autopilot/gallery_app/tests/test_photo_viewer.py'
--- tests/autopilot/gallery_app/tests/test_photo_viewer.py 2013-06-26 09:02:33 +0000
+++ tests/autopilot/gallery_app/tests/test_photo_viewer.py 2013-07-02 13:33:30 +0000
@@ -52,6 +52,11 @@
52 def setUp(self):52 def setUp(self):
53 super(TestPhotoViewer, self).setUp()53 super(TestPhotoViewer, self).setUp()
5454
55 def get_delete_dialog(self):
56 delete_dialog = self.photo_viewer.get_delete_dialog()
57 self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
58 return delete_dialog
59
55 def test_nav_bar_back_button(self):60 def test_nav_bar_back_button(self):
56 """Clicking the back button must close the photo."""61 """Clicking the back button must close the photo."""
57 photo_viewer = self.photo_viewer.get_main_photo_viewer()62 photo_viewer = self.photo_viewer.get_main_photo_viewer()
@@ -68,8 +73,7 @@
68 self.pointing_device.move_to_object(trash_button)73 self.pointing_device.move_to_object(trash_button)
69 self.pointing_device.click()74 self.pointing_device.click()
7075
71 delete_dialog = self.photo_viewer.get_delete_dialog()76 delete_dialog = self.get_delete_dialog()
72 self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
7377
74 cancel_item = self.photo_viewer.get_delete_popover_cancel_item()78 cancel_item = self.photo_viewer.get_delete_popover_cancel_item()
75 self.click_item(cancel_item)79 self.click_item(cancel_item)
@@ -82,8 +86,7 @@
82 self.pointing_device.move_to_object(trash_button)86 self.pointing_device.move_to_object(trash_button)
83 self.pointing_device.click()87 self.pointing_device.click()
8488
85 delete_dialog = self.photo_viewer.get_delete_dialog()89 delete_dialog = self.get_delete_dialog()
86 self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
8790
88 delete_item = self.photo_viewer.get_delete_popover_delete_item()91 delete_item = self.photo_viewer.get_delete_popover_delete_item()
89 self.click_item(delete_item)92 self.click_item(delete_item)
@@ -94,8 +97,7 @@
94 self.reveal_toolbar()97 self.reveal_toolbar()
95 self.pointing_device.click_object(trash_button)98 self.pointing_device.click_object(trash_button)
9699
97 delete_dialog = self.photo_viewer.get_delete_dialog()100 delete_dialog = self.get_delete_dialog()
98 self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
99101
100 delete_item = self.photo_viewer.get_delete_popover_delete_item()102 delete_item = self.photo_viewer.get_delete_popover_delete_item()
101 self.click_item(delete_item)103 self.click_item(delete_item)
102104
=== modified file 'tests/autopilot/gallery_app/tests/test_photos_view.py'
--- tests/autopilot/gallery_app/tests/test_photos_view.py 2013-06-26 08:59:08 +0000
+++ tests/autopilot/gallery_app/tests/test_photos_view.py 2013-07-02 13:33:30 +0000
@@ -60,6 +60,11 @@
60 trash_button = self.photos_view.get_toolbar_delete_button()60 trash_button = self.photos_view.get_toolbar_delete_button()
61 self.click_item(trash_button)61 self.click_item(trash_button)
6262
63 def get_delete_dialog(self):
64 delete_dialog = self.gallery_utils.get_delete_dialog()
65 self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
66 return delete_dialog
67
63 def test_open_photo(self):68 def test_open_photo(self):
64 self.click_first_photo()69 self.click_first_photo()
65 photo_viewer = self.photos_view.get_main_photo_viewer()70 photo_viewer = self.photos_view.get_main_photo_viewer()
@@ -83,8 +88,7 @@
83 self.click_first_photo()88 self.click_first_photo()
84 self.click_delete_action()89 self.click_delete_action()
8590
86 delete_dialog = self.photos_view.get_delete_dialog()91 delete_dialog = self.get_delete_dialog()
87 self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
8892
89 cancel_item = self.photos_view.get_delete_dialog_cancel_button()93 cancel_item = self.photos_view.get_delete_dialog_cancel_button()
90 self.click_item(cancel_item)94 self.click_item(cancel_item)
@@ -97,8 +101,7 @@
97101
98 self.click_delete_action()102 self.click_delete_action()
99103
100 delete_dialog = self.photos_view.get_delete_dialog()104 delete_dialog = self.get_delete_dialog()
101 self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
102105
103 delete_item = self.photos_view.get_delete_dialog_delete_button()106 delete_item = self.photos_view.get_delete_dialog_delete_button()
104 self.click_item(delete_item)107 self.click_item(delete_item)
105108
=== modified file 'tests/unittests/mediaobjectfactory/tst_mediaobjectfactory.cpp'
--- tests/unittests/mediaobjectfactory/tst_mediaobjectfactory.cpp 2013-06-28 12:33:19 +0000
+++ tests/unittests/mediaobjectfactory/tst_mediaobjectfactory.cpp 2013-07-02 13:33:30 +0000
@@ -41,6 +41,7 @@
41 void readPhotoMetadata();41 void readPhotoMetadata();
42 void readVideoMetadata();42 void readVideoMetadata();
43 void enableContentLoadFilter();43 void enableContentLoadFilter();
44 void addMedia();
4445
45private:46private:
46 MediaTable *m_mediaTable;47 MediaTable *m_mediaTable;
@@ -143,6 +144,34 @@
143 QVERIFY(media == 0);144 QVERIFY(media == 0);
144}145}
145146
147void tst_MediaObjectFactory::addMedia()
148{
149 qint64 id = 123;
150 QString filename("/some/photo.jpg");
151 QSize size(320, 200);
152 QDateTime timestamp(QDate(2013, 02, 03), QTime(12, 12, 12));
153 QDateTime exposureTime(QDate(2013, 03, 04), QTime(1, 2, 3));
154 Orientation originalOrientation(BOTTOM_RIGHT_ORIGIN);
155 qint64 filesize = 2048;
156
157 m_factory->addMedia(id, filename, size, timestamp,
158 exposureTime, originalOrientation,
159 filesize);
160
161 QCOMPARE(m_factory->m_mediasFromDB.size(), 1);
162 QSet<DataObject*>::iterator it;
163 it = m_factory->m_mediasFromDB.begin();
164 DataObject *obj = *it;
165 Photo *photo = qobject_cast<Photo*>(obj);
166 QVERIFY(photo != 0);
167 QCOMPARE(photo->id(), id);
168 QCOMPARE(photo->path().toLocalFile(), filename);
169 QCOMPARE(photo->size(), size);
170 QCOMPARE(photo->exposureDateTime(), exposureTime);
171 QCOMPARE(photo->fileTimestamp(), timestamp);
172 QCOMPARE(photo->orientation(), originalOrientation);
173}
174
146QTEST_MAIN(tst_MediaObjectFactory);175QTEST_MAIN(tst_MediaObjectFactory);
147176
148#include "tst_mediaobjectfactory.moc"177#include "tst_mediaobjectfactory.moc"
149178
=== modified file 'tests/unittests/stubs/gallery-manager_stub.cpp'
--- tests/unittests/stubs/gallery-manager_stub.cpp 2013-06-28 20:38:44 +0000
+++ tests/unittests/stubs/gallery-manager_stub.cpp 2013-07-02 13:33:30 +0000
@@ -119,3 +119,8 @@
119{119{
120 Q_UNUSED(file);120 Q_UNUSED(file);
121}121}
122
123void GalleryManager::onMediaItemRemoved(qint64 mediaId)
124{
125 Q_UNUSED(mediaId);
126}
122127
=== modified file 'tests/unittests/stubs/media-table_stub.cpp'
--- tests/unittests/stubs/media-table_stub.cpp 2013-06-28 12:33:19 +0000
+++ tests/unittests/stubs/media-table_stub.cpp 2013-07-02 13:33:30 +0000
@@ -51,10 +51,6 @@
51 mediaFakeTable.clear();51 mediaFakeTable.clear();
52}52}
5353
54void MediaTable::verifyFiles()
55{
56}
57
58qint64 MediaTable::getIdForMedia(const QString& filename)54qint64 MediaTable::getIdForMedia(const QString& filename)
59{55{
60 foreach (const MediaDataRow &row, mediaFakeTable) {56 foreach (const MediaDataRow &row, mediaFakeTable) {
@@ -109,6 +105,10 @@
109{105{
110}106}
111107
108void MediaTable::emitAllRows()
109{
110}
111
112void MediaTable::getRow(qint64 mediaId, QSize& size, Orientation& 112void MediaTable::getRow(qint64 mediaId, QSize& size, Orientation&
113 originalOrientation, QDateTime& fileTimestamp, QDateTime& exposureDateTime)113 originalOrientation, QDateTime& fileTimestamp, QDateTime& exposureDateTime)
114{114{

Subscribers

People subscribed via source and target branches