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