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
1=== modified file 'src/database/media-table.cpp'
2--- src/database/media-table.cpp 2013-06-28 12:33:19 +0000
3+++ src/database/media-table.cpp 2013-07-02 13:33:30 +0000
4@@ -34,45 +34,6 @@
5 }
6
7 /*!
8- * \brief MediaTable::verifyFiles
9- * Runs though the table, removes references to files
10- * that have been deleted from disk.
11- */
12-void MediaTable::verifyFiles()
13-{
14- QSqlQuery query(*m_db->getDB());
15- QList<qint64> to_delete;
16- query.prepare("SELECT id, filename FROM MediaTable");
17- if (!query.exec())
18- m_db->logSqlError(query);
19-
20- // Stat each file. Make a list of files that no longer exist.
21- while (query.next()) {
22- // stat'ing and sync'ing file info over even several hundred photos is an
23- // expensive operation since it involves lots of I/O, so spin the event
24- // loop so that the UI remains responsive
25- QApplication::processEvents();
26-
27- qint64 id = query.value(0).toLongLong();
28- QFile file(query.value(1).toString());
29-
30- if (!file.exists())
31- to_delete.append(id);
32- }
33-
34- // Delete any references to non-existent files.
35- m_db->getDB()->transaction();
36- foreach (qint64 id, to_delete) {
37- // spin the event loop so that the UI remains responsive
38- QApplication::processEvents();
39-
40- remove(id);
41- }
42-
43- m_db->getDB()->commit();
44-}
45-
46-/*!
47 * \brief MediaTable::getIdForMedia Returns the row ID for the given photo.
48 * \param filename
49 * \return Returns the row ID for the given photo. If none exists, -1 will be returned.
50@@ -263,6 +224,31 @@
51 }
52
53 /*!
54+ * \brief MediaTable::emitAllRows goes through the whole DB and emits a row() signal
55+ * for every single row with all the Database
56+ */
57+void MediaTable::emitAllRows()
58+{
59+ QSqlQuery query(*m_db->getDB());
60+ query.prepare("SELECT * FROM MediaTable");
61+ if (!query.exec())
62+ m_db->logSqlError(query);
63+
64+ while (query.next()) {
65+ qint64 id = query.value(0).toInt();
66+ QString filename = query.value(1).toString();
67+ QSize size(query.value(2).toInt(), query.value(3).toInt());
68+ QDateTime timestamp;
69+ timestamp.setMSecsSinceEpoch(query.value(4).toLongLong());
70+ QDateTime exposuretime;
71+ exposuretime.setMSecsSinceEpoch(query.value(5).toLongLong());
72+ Orientation orientation = static_cast<Orientation>(query.value(6).toInt());
73+ qint64 filesize = query.value(7).toInt();
74+ emit row(id, filename, size, timestamp, exposuretime, orientation, filesize);
75+ }
76+}
77+
78+/*!
79 * \brief MediaTable::getRow Gets a row that already exists
80 * \param mediaId
81 * \param size
82
83=== modified file 'src/database/media-table.h'
84--- src/database/media-table.h 2013-06-28 12:33:19 +0000
85+++ src/database/media-table.h 2013-07-02 13:33:30 +0000
86@@ -37,8 +37,6 @@
87 public:
88 explicit MediaTable(Database* db, QObject *parent = 0);
89
90- void verifyFiles();
91-
92 qint64 getIdForMedia(const QString& filename);
93
94 qint64 createIdForMedia(const QString& filename, const QDateTime& timestamp,
95@@ -63,6 +61,13 @@
96
97 QDateTime getExposureTime(qint64 mediaId);
98
99+ void emitAllRows();
100+
101+signals:
102+ void row(qint64 mediaId, const QString& filename, const QSize& size,
103+ const QDateTime& timestamp, const QDateTime& exposureTime,
104+ Orientation originalOrientation, qint64 filesize);
105+
106 private:
107 Database* m_db;
108 };
109
110=== modified file 'src/gallery-application.cpp'
111--- src/gallery-application.cpp 2013-06-28 11:53:54 +0000
112+++ src/gallery-application.cpp 2013-07-02 13:33:30 +0000
113@@ -206,7 +206,10 @@
114 filterType = MediaSource::Photo;
115 m_galleryManager->enableContentLoadFilter(filterType);
116 }
117+ QApplication::processEvents();
118+
119 m_galleryManager->postInit();
120+ QApplication::processEvents();
121 if (m_cmdLineParser->startupTimer())
122 qDebug() << "GalleryManager initialized" << m_timer->elapsed() << "ms";
123
124@@ -230,4 +233,3 @@
125
126 m_timer->restart();
127 }
128-
129
130=== modified file 'src/gallery-manager.cpp'
131--- src/gallery-manager.cpp 2013-07-01 07:40:13 +0000
132+++ src/gallery-manager.cpp 2013-07-02 13:33:30 +0000
133@@ -193,13 +193,12 @@
134 m_database = new Database(m_resource->databaseDirectory(),
135 m_resource->getRcUrl("sql").path());
136 m_mediaFactory->setMediaTable(m_database->getMediaTable());
137- m_database->getMediaTable()->verifyFiles();
138 m_defaultTemplate = new AlbumDefaultTemplate();
139 m_mediaCollection = new MediaCollection();
140
141 initPreviewManager();
142+ fillMediaCollection();
143 startFileMonitoring();
144- fillMediaCollection();
145
146 collectionsInitialised = true;
147
148@@ -229,7 +228,7 @@
149 EventCollection *GalleryManager::eventCollection()
150 {
151 if (!m_eventCollection)
152- m_eventCollection = new EventCollection;
153+ m_eventCollection = new EventCollection();
154
155 return m_eventCollection;
156 }
157@@ -303,23 +302,10 @@
158 {
159 Q_ASSERT(m_mediaCollection);
160
161- QSet<DataObject*> photos;
162- foreach (const QString &dirName, m_resource->mediaDirectories()) {
163- QDir mediaDir(dirName);
164- mediaDir.setFilter(QDir::Files);
165- mediaDir.setSorting(QDir::Name);
166-
167- const QStringList filenames = mediaDir.entryList();
168- foreach (const QString& filename, filenames) {
169- QFileInfo file(mediaDir, filename);
170- DataObject *media = m_mediaFactory->create(file);
171- if (media) {
172- photos.insert(media);
173- }
174- }
175- }
176-
177- m_mediaCollection->addMany(photos);
178+ QSet<DataObject*> medias;
179+ medias = m_mediaFactory->mediasFromDB();
180+ m_mediaCollection->addMany(medias);
181+ m_mediaFactory->clear();
182 }
183
184 /*!
185@@ -334,7 +320,11 @@
186 m_monitor = new MediaMonitor();
187 QObject::connect(m_monitor, SIGNAL(mediaItemAdded(QString)),
188 this, SLOT(onMediaItemAdded(QString)));
189+ QObject::connect(m_monitor, SIGNAL(mediaItemRemoved(qint64)),
190+ this, SLOT(onMediaItemRemoved(qint64)));
191+
192 m_monitor->startMonitoring(m_resource->mediaDirectories());
193+ m_monitor->checkConsitency(m_mediaCollection);
194 }
195
196 /*!
197@@ -343,12 +333,19 @@
198 */
199 void GalleryManager::onMediaItemAdded(QString file)
200 {
201- QFileInfo fi(file);
202- MediaSource* media = m_mediaCollection->mediaFromFileinfo(fi);
203- if (media == 0) {
204- media = m_mediaFactory->create(fi);
205- }
206- if (media) {
207- m_mediaCollection->add(media);
208- }
209+ if (! m_mediaCollection->containsFile(file)) {
210+ QFileInfo fi(file);
211+ MediaSource *media = m_mediaFactory->create(fi);
212+ if (media)
213+ m_mediaCollection->add(media);
214+ }
215+}
216+
217+/*!
218+ * \brief GalleryManager::onMediaItemRemoved
219+ * \param mediaId
220+ */
221+void GalleryManager::onMediaItemRemoved(qint64 mediaId)
222+{
223+ m_mediaCollection->destroy(mediaId);
224 }
225
226=== modified file 'src/gallery-manager.h'
227--- src/gallery-manager.h 2013-06-28 20:38:44 +0000
228+++ src/gallery-manager.h 2013-07-02 13:33:30 +0000
229@@ -84,6 +84,7 @@
230
231 private slots:
232 void onMediaItemAdded(QString file);
233+ void onMediaItemRemoved(qint64 mediaId);
234
235 private:
236 GalleryManager(const GalleryManager&);
237
238=== modified file 'src/media-object-factory.cpp'
239--- src/media-object-factory.cpp 2013-06-28 12:33:19 +0000
240+++ src/media-object-factory.cpp 2013-07-02 13:33:30 +0000
241@@ -59,6 +59,43 @@
242 }
243
244 /*!
245+ * \brief MediaObjectFactory::photosFromDB creates a set with all photos and video
246+ * stored in the DB.
247+ * Someone else needs to take the responsibility to delete all the objects in the set.
248+ * You should call clear() afterwards, to remove temporary data.
249+ * \return All medias stored in the DB
250+ */
251+QSet<DataObject *> MediaObjectFactory::mediasFromDB()
252+{
253+ Q_ASSERT(m_mediaTable);
254+
255+ m_mediasFromDB.clear();
256+
257+ connect(m_mediaTable,
258+ SIGNAL(row(qint64,QString,QSize,QDateTime,QDateTime,Orientation,qint64)),
259+ this,
260+ SLOT(addMedia(qint64,QString,QSize,QDateTime,QDateTime,Orientation,qint64)));
261+
262+ m_mediaTable->emitAllRows();
263+
264+ disconnect(m_mediaTable,
265+ SIGNAL(row(qint64,QString,QSize,QDateTime,QDateTime,Orientation,qint64)),
266+ this,
267+ SLOT(addMedia(qint64,QString,QSize,QDateTime,QDateTime,Orientation,qint64)));
268+
269+ return m_mediasFromDB;
270+}
271+
272+/*!
273+ * \brief MediaObjectFactory::clear
274+ */
275+void MediaObjectFactory::clear()
276+{
277+ clearMetadata();
278+ m_mediasFromDB.clear();
279+}
280+
281+/*!
282 * \brief MediaObjectFactory::create loads the data for a photo or video file.
283 * Creates / updates the database as well.
284 * \param file the file to load
285@@ -89,13 +126,11 @@
286
287 MediaSource *media = 0;
288 Photo *photo = 0;
289- Video *video = 0;
290 if (mediaType == MediaSource::Photo) {
291 photo = new Photo(file);
292 media = photo;
293 } else {
294- video = new Video(file);
295- media = video;
296+ media = new Video(file);
297 }
298
299 if (id == INVALID_ID) {
300@@ -129,6 +164,49 @@
301 }
302
303 /*!
304+ * \brief MediaObjectFactory::addMedia creates a media object, and adds it to the
305+ * internal set. This is used for mediasFromDB().
306+ * \param mediaId
307+ * \param filename
308+ * \param size
309+ * \param timestamp
310+ * \param exposureTime
311+ * \param originalOrientation
312+ * \param filesize
313+ * \return
314+ */
315+void MediaObjectFactory::addMedia(qint64 mediaId, const QString &filename,
316+ const QSize &size, const QDateTime &timestamp,
317+ const QDateTime &exposureTime,
318+ Orientation originalOrientation, qint64 filesize)
319+{
320+ Q_UNUSED(filesize);
321+
322+ QFileInfo file(filename);
323+ MediaSource::MediaType mediaType = MediaSource::Photo;
324+ if (Video::isCameraVideo(file))
325+ mediaType = MediaSource::Video;
326+
327+ MediaSource *media = 0;
328+ Photo *photo = 0;
329+ if (mediaType == MediaSource::Photo) {
330+ photo = new Photo(file);
331+ media = photo;
332+ } else {
333+ media = new Video(file);
334+ }
335+
336+ media->setSize(size);
337+ media->setFileTimestamp(timestamp);
338+ media->setExposureDateTime(exposureTime);
339+ if (mediaType == MediaSource::Photo)
340+ photo->setOriginalOrientation(originalOrientation);
341+ media->setId(mediaId);
342+
343+ m_mediasFromDB.insert(media);
344+}
345+
346+/*!
347 * \brief MediaObjectFactory::clearMetadata resets all memeber variables
348 * regarding metadata
349 */
350
351=== modified file 'src/media-object-factory.h'
352--- src/media-object-factory.h 2013-06-26 08:59:08 +0000
353+++ src/media-object-factory.h 2013-07-02 13:33:30 +0000
354@@ -25,6 +25,7 @@
355
356 #include <QDateTime>
357 #include <QFileInfo>
358+#include <QObject>
359 #include <QSize>
360
361 class MediaTable;
362@@ -32,17 +33,27 @@
363 /*!
364 * \brief The MediaObjectFactory creates phot and video objects
365 */
366-class MediaObjectFactory
367+class MediaObjectFactory : public QObject
368 {
369+ Q_OBJECT
370+
371 public:
372 explicit MediaObjectFactory();
373
374 void setMediaTable(MediaTable *mediaTable);
375 void enableContentLoadFilter(MediaSource::MediaType filterType);
376
377+ QSet<DataObject*> mediasFromDB();
378+ void clear();
379+
380 MediaSource *create(const QFileInfo& file);
381
382-private:
383+private slots:
384+ void addMedia(qint64 mediaId, const QString& filename, const QSize& size,
385+ const QDateTime& timestamp, const QDateTime& exposureTime,
386+ Orientation originalOrientation, qint64 filesize);
387+
388+private:
389 void clearMetadata();
390 bool readPhotoMetadata(const QFileInfo &file);
391 bool readVideoMetadata(const QFileInfo &file);
392@@ -56,6 +67,8 @@
393
394 MediaSource::MediaType m_filterType;
395
396+ QSet<DataObject*> m_mediasFromDB;
397+
398 friend class tst_MediaObjectFactory;
399 };
400
401
402=== modified file 'src/media/media-collection.cpp'
403--- src/media/media-collection.cpp 2013-06-10 07:37:09 +0000
404+++ src/media/media-collection.cpp 2013-07-02 13:33:30 +0000
405@@ -137,12 +137,22 @@
406 * \param file_to_load
407 * \return
408 */
409-MediaSource *MediaCollection::mediaFromFileinfo(const QFileInfo& file)
410+const MediaSource *MediaCollection::mediaFromFileinfo(const QFileInfo& file) const
411 {
412 return m_fileMediaMap.value(file.absoluteFilePath(), 0);
413 }
414
415 /*!
416+ * \brief MediaCollection::containsFile
417+ * \param filename
418+ * \return
419+ */
420+bool MediaCollection::containsFile(const QString &filename) const
421+{
422+ return m_fileMediaMap.contains(filename);
423+}
424+
425+/*!
426 * \reimp
427 */
428 void MediaCollection::addMany(const QSet<DataObject *> &objects)
429@@ -154,3 +164,24 @@
430
431 DataCollection::addMany(objects);
432 }
433+
434+/*!
435+ * \brief MediaCollection::destroy
436+ * \param media
437+ */
438+void MediaCollection::destroy(MediaSource *media)
439+{
440+ SourceCollection::destroy(media, true, true);
441+}
442+
443+/*!
444+ * \brief MediaCollection::remove
445+ * \param id
446+ */
447+void MediaCollection::destroy(qint64 id)
448+{
449+ if (m_idMap.contains(id)) {
450+ MediaSource *media = qobject_cast<MediaSource*>(m_idMap[id]);
451+ SourceCollection::destroy(media, true, true);
452+ }
453+}
454
455=== modified file 'src/media/media-collection.h'
456--- src/media/media-collection.h 2013-06-10 06:32:08 +0000
457+++ src/media/media-collection.h 2013-07-02 13:33:30 +0000
458@@ -44,10 +44,14 @@
459 static bool exposureDateTimeDescendingComparator(DataObject* a, DataObject* b);
460
461 MediaSource* mediaForId(qint64 id);
462- MediaSource* mediaFromFileinfo(const QFileInfo &file);
463+ const MediaSource* mediaFromFileinfo(const QFileInfo &file) const;
464+ bool containsFile(const QString& filename) const;
465
466 virtual void addMany(const QSet<DataObject*>& objects);
467
468+ void destroy(MediaSource *media);
469+ void destroy(qint64 id);
470+
471 protected slots:
472 virtual void notifyContentsChanged(const QSet<DataObject*>* added,
473 const QSet<DataObject*>* removed);
474
475=== modified file 'src/media/media-monitor.cpp'
476--- src/media/media-monitor.cpp 2013-06-28 11:53:54 +0000
477+++ src/media/media-monitor.cpp 2013-07-02 13:33:30 +0000
478@@ -18,14 +18,17 @@
479 */
480
481 #include "media-monitor.h"
482+#include "media-collection.h"
483+#include "media-source.h"
484
485 #include <QDir>
486+#include <QElapsedTimer>
487+#include <QFileInfo>
488 #include <QSet>
489 #include <QString>
490
491 /*!
492 * \brief MediaMonitor::MediaMonitor
493- * \param targetDirectory
494 */
495 MediaMonitor::MediaMonitor(QObject *parent)
496 : QObject(parent),
497@@ -38,6 +41,8 @@
498
499 QObject::connect(m_worker, SIGNAL(mediaItemAdded(QString)),
500 this, SIGNAL(mediaItemAdded(QString)), Qt::QueuedConnection);
501+ QObject::connect(m_worker, SIGNAL(mediaItemRemoved(qint64)),
502+ this, SIGNAL(mediaItemRemoved(qint64)), Qt::QueuedConnection);
503
504 m_workerThread.start(QThread::LowPriority);
505 }
506@@ -52,7 +57,8 @@
507 }
508
509 /*!
510- * \brief MediaMonitor::startMonitoring
511+ * \brief MediaMonitor::startMonitoring starts monitoring the given directories
512+ * new and delted files
513 * \param targetDirectories
514 */
515 void MediaMonitor::startMonitoring(const QStringList &targetDirectories)
516@@ -61,10 +67,20 @@
517 Q_ARG(QStringList, targetDirectories));
518 }
519
520+/*!
521+ * \brief MediaMonitor::checkConsitency checks the given datastructure, if it is
522+ * in sync with the file system (files got added, deleted meanwhile)
523+ * \param mediaCollection
524+ */
525+void MediaMonitor::checkConsitency(const MediaCollection *mediaCollection)
526+{
527+ m_worker->setMediaCollection(mediaCollection);
528+ QMetaObject::invokeMethod(m_worker, "checkConsitency", Qt::QueuedConnection);
529+}
530+
531
532 /*!
533 * \brief MediaMonitor::MediaMonitor
534- * \param targetDirectory
535 */
536 MediaMonitorWorker::MediaMonitorWorker(QObject *parent)
537 : QObject(parent),
538@@ -89,6 +105,15 @@
539 }
540
541 /*!
542+ * \brief MediaMonitorWorker::setMediaCollection
543+ * \param mediaCollection
544+ */
545+void MediaMonitorWorker::setMediaCollection(const MediaCollection *mediaCollection)
546+{
547+ m_mediaCollection = mediaCollection;
548+}
549+
550+/*!
551 * \brief MediaMonitor::startMonitoring
552 * \param targetDirectories
553 */
554@@ -105,6 +130,16 @@
555 }
556
557 /*!
558+ * \brief MediaMonitorWorker::checkConsitency
559+ * \param mediaCollection
560+ */
561+void MediaMonitorWorker::checkConsitency()
562+{
563+ checkForRemovedMedias();
564+ checkForNewMedias();
565+}
566+
567+/*!
568 * \brief MediaMonitor::onDirectoryEvent
569 * \param eventSource
570 */
571@@ -120,9 +155,17 @@
572 {
573 QStringList new_manifest = getManifest(m_targetDirectories);
574
575- QStringList difference = subtractManifest(new_manifest, m_manifest);
576- for (int i = 0; i < difference.size(); i++)
577- emit mediaItemAdded(difference.at(i));
578+ QStringList added = subtractManifest(new_manifest, m_manifest);
579+ for (int i = 0; i < added.size(); i++)
580+ emit mediaItemAdded(added.at(i));
581+
582+ QStringList removed = subtractManifest(m_manifest, new_manifest);
583+ for (int i = 0; i < removed.size(); i++) {
584+ QFileInfo file(removed.at(i));
585+ const MediaSource *media = m_mediaCollection->mediaFromFileinfo(file);
586+ if (media)
587+ emit mediaItemRemoved(media->id());
588+ }
589
590 m_manifest = new_manifest;
591 }
592@@ -158,3 +201,31 @@
593 result.subtract(QSet<QString>::fromList(m2));
594 return QStringList(result.toList());
595 }
596+
597+/*!
598+ * \brief MediaMonitorWorker::checkForNewMedias checks for files in the filesystem
599+ * that are not in the datastructure
600+ * \param mediaCollection
601+ */
602+void MediaMonitorWorker::checkForNewMedias()
603+{
604+ foreach (const QString& file, m_manifest) {
605+ if (!m_mediaCollection->containsFile(file))
606+ emit mediaItemAdded(file);
607+ }
608+}
609+
610+/*!
611+ * \brief MediaMonitorWorker::checkForRemovedMedias checks if there are files in
612+ * the datastructure, but not in the file system
613+ */
614+void MediaMonitorWorker::checkForRemovedMedias()
615+{
616+ const QList<DataObject*> medias = m_mediaCollection->getAll();
617+ foreach (const DataObject* obj, medias) {
618+ const MediaSource *media = qobject_cast<const MediaSource*>(obj);
619+ Q_ASSERT(media);
620+ if (!m_manifest.contains(media->file().absoluteFilePath()))
621+ emit mediaItemRemoved(media->id());
622+ }
623+}
624
625=== modified file 'src/media/media-monitor.h'
626--- src/media/media-monitor.h 2013-06-28 11:53:54 +0000
627+++ src/media/media-monitor.h 2013-07-02 13:33:30 +0000
628@@ -26,11 +26,13 @@
629 #include <QThread>
630 #include <QTimer>
631
632+class MediaCollection;
633 class MediaMonitorWorker;
634
635 /*!
636- * \brief The MediaMonitor class monitor directories for added files
637- * All it's time consuming tasks are automaticly run in a separate thread
638+ * \brief The MediaMonitor class monitor directories for added files. And does a
639+ * check if the files in the datastructure and on thef ile system are in sync.
640+ * All this is done in an extra thread.
641 */
642 class MediaMonitor : public QObject
643 {
644@@ -41,9 +43,11 @@
645 virtual ~MediaMonitor();
646
647 void startMonitoring(const QStringList& targetDirectories);
648+ void checkConsitency(const MediaCollection *mediaCollection);
649
650 signals:
651 void mediaItemAdded(QString newItem);
652+ void mediaItemRemoved(qint64 mediaId);
653
654 private:
655 MediaMonitorWorker* m_worker;
656@@ -63,25 +67,31 @@
657 MediaMonitorWorker(QObject *parent=0);
658 virtual ~MediaMonitorWorker();
659
660+ void setMediaCollection(const MediaCollection *mediaCollection);
661+
662 public slots:
663 void startMonitoring(const QStringList& targetDirectories);
664+ void checkConsitency();
665
666 signals:
667 void mediaItemAdded(QString newItem);
668+ void mediaItemRemoved(qint64 mediaId);
669
670 private slots:
671 void onDirectoryEvent(const QString& eventSource);
672 void onFileActivityCeased();
673
674 private:
675- static QStringList getManifest(const QStringList& dirs);
676- static QStringList subtractManifest(const QStringList& m1,
677- const QStringList& m2);
678+ QStringList getManifest(const QStringList& dirs);
679+ QStringList subtractManifest(const QStringList& m1, const QStringList& m2);
680+ void checkForNewMedias();
681+ void checkForRemovedMedias();
682
683 QStringList m_targetDirectories;
684 QFileSystemWatcher m_watcher;
685 QStringList m_manifest;
686 QTimer m_fileActivityTimer;
687+ const MediaCollection *m_mediaCollection;
688 };
689
690 #endif // GALLERY_MEDIA_MONITOR_H_
691
692=== modified file 'src/photo/photo-caches.cpp'
693--- src/photo/photo-caches.cpp 2013-06-10 07:59:26 +0000
694+++ src/photo/photo-caches.cpp 2013-07-02 13:33:30 +0000
695@@ -102,7 +102,7 @@
696
697 m_file.dir().mkdir(ORIGINAL_DIR);
698
699- return rename(m_file, m_originalFile);
700+ return copy(m_file, m_originalFile);
701 }
702
703 /*!
704
705=== modified file 'src/qml/qml-media-collection-model.cpp'
706--- src/qml/qml-media-collection-model.cpp 2013-06-11 19:44:28 +0000
707+++ src/qml/qml-media-collection-model.cpp 2013-07-02 13:33:30 +0000
708@@ -93,7 +93,7 @@
709 MediaSource* media = VariantToObject<MediaSource*>(vmedia);
710
711 if (media != NULL)
712- GalleryManager::instance()->mediaCollection()->destroy(media, true, true);
713+ GalleryManager::instance()->mediaCollection()->destroy(media);
714 }
715
716 /*!
717
718=== modified file 'tests/autopilot/gallery_app/emulators/gallery_utils.py'
719--- tests/autopilot/gallery_app/emulators/gallery_utils.py 2013-06-21 16:00:49 +0000
720+++ tests/autopilot/gallery_app/emulators/gallery_utils.py 2013-07-02 13:33:30 +0000
721@@ -119,12 +119,7 @@
722 def get_first_image_in_event_view(self):
723 """Returns the first photo of the gallery."""
724 event = self.get_first_event()
725- list_view = event.get_children_by_type("QQuickListView")[0]
726- item = list_view.get_children_by_type("QQuickItem")[0]
727- first_delegate = item.get_children_by_type("QQuickItem",
728- objectName="eventPhoto")[0]
729- first_photo = first_delegate.get_children_by_type("UbuntuShape")[0]
730- return first_photo
731+ return event.select_many("OrganicItemInteraction")[1]
732
733 def get_all_albums(self):
734 """Returns all albums in the albums view"""
735
736=== modified file 'tests/autopilot/gallery_app/tests/test_events_view.py'
737--- tests/autopilot/gallery_app/tests/test_events_view.py 2013-06-26 09:02:33 +0000
738+++ tests/autopilot/gallery_app/tests/test_events_view.py 2013-07-02 13:33:30 +0000
739@@ -47,6 +47,11 @@
740 first_photo = self.events_view.get_first_image_in_event_view()
741 self.click_item(first_photo)
742
743+ def get_delete_dialog(self):
744+ delete_dialog = self.gallery_utils.get_delete_dialog()
745+ self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
746+ return delete_dialog
747+
748 def click_delete_action(self):
749 trash_button = self.events_view.get_toolbar_delete_button()
750 self.click_item(trash_button)
751@@ -69,8 +74,7 @@
752 self.click_first_photo()
753 self.click_delete_action()
754
755- delete_dialog = self.events_view.get_delete_dialog()
756- self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
757+ delete_dialog = self.get_delete_dialog()
758
759 cancel_item = self.events_view.get_delete_dialog_cancel_button()
760 self.click_item(cancel_item)
761@@ -83,8 +87,7 @@
762
763 self.click_delete_action()
764
765- delete_dialog = self.events_view.get_delete_dialog()
766- self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
767+ delete_dialog = self.get_delete_dialog()
768
769 delete_item = self.events_view.get_delete_dialog_delete_button()
770 self.click_item(delete_item)
771
772=== modified file 'tests/autopilot/gallery_app/tests/test_photo_viewer.py'
773--- tests/autopilot/gallery_app/tests/test_photo_viewer.py 2013-06-26 09:02:33 +0000
774+++ tests/autopilot/gallery_app/tests/test_photo_viewer.py 2013-07-02 13:33:30 +0000
775@@ -52,6 +52,11 @@
776 def setUp(self):
777 super(TestPhotoViewer, self).setUp()
778
779+ def get_delete_dialog(self):
780+ delete_dialog = self.photo_viewer.get_delete_dialog()
781+ self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
782+ return delete_dialog
783+
784 def test_nav_bar_back_button(self):
785 """Clicking the back button must close the photo."""
786 photo_viewer = self.photo_viewer.get_main_photo_viewer()
787@@ -68,8 +73,7 @@
788 self.pointing_device.move_to_object(trash_button)
789 self.pointing_device.click()
790
791- delete_dialog = self.photo_viewer.get_delete_dialog()
792- self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
793+ delete_dialog = self.get_delete_dialog()
794
795 cancel_item = self.photo_viewer.get_delete_popover_cancel_item()
796 self.click_item(cancel_item)
797@@ -82,8 +86,7 @@
798 self.pointing_device.move_to_object(trash_button)
799 self.pointing_device.click()
800
801- delete_dialog = self.photo_viewer.get_delete_dialog()
802- self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
803+ delete_dialog = self.get_delete_dialog()
804
805 delete_item = self.photo_viewer.get_delete_popover_delete_item()
806 self.click_item(delete_item)
807@@ -94,8 +97,7 @@
808 self.reveal_toolbar()
809 self.pointing_device.click_object(trash_button)
810
811- delete_dialog = self.photo_viewer.get_delete_dialog()
812- self.assertThat(delete_dialog.visible, Eventually(Equals(True)))
813+ delete_dialog = self.get_delete_dialog()
814
815 delete_item = self.photo_viewer.get_delete_popover_delete_item()
816 self.click_item(delete_item)
817
818=== modified file 'tests/autopilot/gallery_app/tests/test_photos_view.py'
819--- tests/autopilot/gallery_app/tests/test_photos_view.py 2013-06-26 08:59:08 +0000
820+++ tests/autopilot/gallery_app/tests/test_photos_view.py 2013-07-02 13:33:30 +0000
821@@ -60,6 +60,11 @@
822 trash_button = self.photos_view.get_toolbar_delete_button()
823 self.click_item(trash_button)
824
825+ def get_delete_dialog(self):
826+ delete_dialog = self.gallery_utils.get_delete_dialog()
827+ self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
828+ return delete_dialog
829+
830 def test_open_photo(self):
831 self.click_first_photo()
832 photo_viewer = self.photos_view.get_main_photo_viewer()
833@@ -83,8 +88,7 @@
834 self.click_first_photo()
835 self.click_delete_action()
836
837- delete_dialog = self.photos_view.get_delete_dialog()
838- self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
839+ delete_dialog = self.get_delete_dialog()
840
841 cancel_item = self.photos_view.get_delete_dialog_cancel_button()
842 self.click_item(cancel_item)
843@@ -97,8 +101,7 @@
844
845 self.click_delete_action()
846
847- delete_dialog = self.photos_view.get_delete_dialog()
848- self.assertThat(delete_dialog.opacity, Eventually(Equals(1)))
849+ delete_dialog = self.get_delete_dialog()
850
851 delete_item = self.photos_view.get_delete_dialog_delete_button()
852 self.click_item(delete_item)
853
854=== modified file 'tests/unittests/mediaobjectfactory/tst_mediaobjectfactory.cpp'
855--- tests/unittests/mediaobjectfactory/tst_mediaobjectfactory.cpp 2013-06-28 12:33:19 +0000
856+++ tests/unittests/mediaobjectfactory/tst_mediaobjectfactory.cpp 2013-07-02 13:33:30 +0000
857@@ -41,6 +41,7 @@
858 void readPhotoMetadata();
859 void readVideoMetadata();
860 void enableContentLoadFilter();
861+ void addMedia();
862
863 private:
864 MediaTable *m_mediaTable;
865@@ -143,6 +144,34 @@
866 QVERIFY(media == 0);
867 }
868
869+void tst_MediaObjectFactory::addMedia()
870+{
871+ qint64 id = 123;
872+ QString filename("/some/photo.jpg");
873+ QSize size(320, 200);
874+ QDateTime timestamp(QDate(2013, 02, 03), QTime(12, 12, 12));
875+ QDateTime exposureTime(QDate(2013, 03, 04), QTime(1, 2, 3));
876+ Orientation originalOrientation(BOTTOM_RIGHT_ORIGIN);
877+ qint64 filesize = 2048;
878+
879+ m_factory->addMedia(id, filename, size, timestamp,
880+ exposureTime, originalOrientation,
881+ filesize);
882+
883+ QCOMPARE(m_factory->m_mediasFromDB.size(), 1);
884+ QSet<DataObject*>::iterator it;
885+ it = m_factory->m_mediasFromDB.begin();
886+ DataObject *obj = *it;
887+ Photo *photo = qobject_cast<Photo*>(obj);
888+ QVERIFY(photo != 0);
889+ QCOMPARE(photo->id(), id);
890+ QCOMPARE(photo->path().toLocalFile(), filename);
891+ QCOMPARE(photo->size(), size);
892+ QCOMPARE(photo->exposureDateTime(), exposureTime);
893+ QCOMPARE(photo->fileTimestamp(), timestamp);
894+ QCOMPARE(photo->orientation(), originalOrientation);
895+}
896+
897 QTEST_MAIN(tst_MediaObjectFactory);
898
899 #include "tst_mediaobjectfactory.moc"
900
901=== modified file 'tests/unittests/stubs/gallery-manager_stub.cpp'
902--- tests/unittests/stubs/gallery-manager_stub.cpp 2013-06-28 20:38:44 +0000
903+++ tests/unittests/stubs/gallery-manager_stub.cpp 2013-07-02 13:33:30 +0000
904@@ -119,3 +119,8 @@
905 {
906 Q_UNUSED(file);
907 }
908+
909+void GalleryManager::onMediaItemRemoved(qint64 mediaId)
910+{
911+ Q_UNUSED(mediaId);
912+}
913
914=== modified file 'tests/unittests/stubs/media-table_stub.cpp'
915--- tests/unittests/stubs/media-table_stub.cpp 2013-06-28 12:33:19 +0000
916+++ tests/unittests/stubs/media-table_stub.cpp 2013-07-02 13:33:30 +0000
917@@ -51,10 +51,6 @@
918 mediaFakeTable.clear();
919 }
920
921-void MediaTable::verifyFiles()
922-{
923-}
924-
925 qint64 MediaTable::getIdForMedia(const QString& filename)
926 {
927 foreach (const MediaDataRow &row, mediaFakeTable) {
928@@ -109,6 +105,10 @@
929 {
930 }
931
932+void MediaTable::emitAllRows()
933+{
934+}
935+
936 void MediaTable::getRow(qint64 mediaId, QSize& size, Orientation&
937 originalOrientation, QDateTime& fileTimestamp, QDateTime& exposureDateTime)
938 {

Subscribers

People subscribed via source and target branches