Merge lp:~fboucault/camera-app/sdcard into lp:camera-app

Proposed by Florian Boucault on 2014-11-17
Status: Merged
Approved by: Bill Filler on 2014-12-11
Approved revision: 436
Merged at revision: 451
Proposed branch: lp:~fboucault/camera-app/sdcard
Merge into: lp:camera-app
Diff against target: 285 lines (+136/-17)
6 files modified
GalleryView.qml (+3/-1)
ViewFinderOverlay.qml (+36/-0)
camera-apparmor.json (+1/-1)
cameraapplication.cpp (+58/-0)
cameraapplication.h (+11/-0)
po/camera-app.pot (+27/-15)
To merge this branch: bzr merge lp:~fboucault/camera-app/sdcard
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing on 2014-12-12
Ubuntu Phablet Team 2014-11-17 Pending
Review via email: mp+241971@code.launchpad.net

Commit message

Add an option to save photos and videos to external SD card.
Adapted bottom edge UI to accomodate for more than 3 settings.

To post a comment you must log in.
lp:~fboucault/camera-app/sdcard updated on 2014-11-18
427. By Florian Boucault on 2014-11-17

Blurred viewfinder is now darker making bottom edge more readable.

428. By Florian Boucault on 2014-11-17

Less opaque blur.

429. By Florian Boucault on 2014-11-17

Merged trunk

430. By Florian Boucault on 2014-11-18

Show/hide SD card option when an SD card is present/not present.

431. By Florian Boucault on 2014-11-18

Update pot

432. By Florian Boucault on 2014-11-18

Better backend code.

Florian Boucault (fboucault) wrote :

Pending two security fixes:
1) https://bugs.launchpad.net/ubuntu/+source/apparmor-easyprof-ubuntu/+bug/1391930
2) creation of Pictures and Videos directories on the SD card when plugged in (sergiusens taking care of it)

Florian Boucault (fboucault) wrote :

> 2) creation of Pictures and Videos directories on the SD card when plugged in
> (sergiusens taking care of it)

Link: https://code.launchpad.net/~sergiusens/ciborium/mediadirs/+merge/242838

lp:~fboucault/camera-app/sdcard updated on 2014-12-02
433. By Florian Boucault on 2014-12-02

Removed unwanted write/read paths from apparmor profile.

lp:~fboucault/camera-app/sdcard updated on 2014-12-05
434. By Florian Boucault on 2014-12-05

Merged from trunk

lp:~fboucault/camera-app/sdcard updated on 2014-12-11
435. By Florian Boucault on 2014-12-11

Merged from trunk

436. By Florian Boucault on 2014-12-11

Added bug

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'GalleryView.qml'
--- GalleryView.qml 2014-12-03 12:37:15 +0000
+++ GalleryView.qml 2014-12-11 16:55:23 +0000
@@ -29,7 +29,9 @@
29 property bool userSelectionMode: false29 property bool userSelectionMode: false
30 property Item currentView: state == "GRID" ? photogridView : slideshowView30 property Item currentView: state == "GRID" ? photogridView : slideshowView
31 property var model: FoldersModel {31 property var model: FoldersModel {
32 folders: [application.picturesLocation, application.videosLocation]32 folders: [application.picturesLocation, application.videosLocation,
33 application.removableStoragePicturesLocation,
34 application.removableStorageVideosLocation]
33 typeFilters: !main.contentExportMode ? [ "image", "video" ]35 typeFilters: !main.contentExportMode ? [ "image", "video" ]
34 : [MimeTypeMapper.contentTypeToMimeType(main.transferContentType)]36 : [MimeTypeMapper.contentTypeToMimeType(main.transferContentType)]
35 singleSelectionOnly: main.transfer.selectionType === ContentTransfer.Single37 singleSelectionOnly: main.transfer.selectionType === ContentTransfer.Single
3638
=== modified file 'ViewFinderOverlay.qml'
--- ViewFinderOverlay.qml 2014-12-09 21:48:11 +0000
+++ ViewFinderOverlay.qml 2014-12-11 16:55:23 +0000
@@ -46,6 +46,7 @@
46 property int selfTimerDelay: 046 property int selfTimerDelay: 0
47 property int encodingQuality: 2 // QMultimedia.NormalQuality47 property int encodingQuality: 2 // QMultimedia.NormalQuality
48 property bool gridEnabled: false48 property bool gridEnabled: false
49 property bool preferRemovableStorage: false
49 }50 }
5051
51 Binding {52 Binding {
@@ -296,9 +297,39 @@
296 label: QT_TR_NOOP("Off")297 label: QT_TR_NOOP("Off")
297 value: false298 value: false
298 }299 }
300 },
301 ListModel {
302 id: removableStorageOptionsModel
303
304 property string settingsProperty: "preferRemovableStorage"
305 property string icon: ""
306 property string label: i18n.tr("SD")
307 property bool isToggle: true
308 property int selectedIndex: bottomEdge.indexForValue(removableStorageOptionsModel, settings.preferRemovableStorage)
309 property bool available: application.removableStoragePresent
310 property bool visible: available
311
312 ListElement {
313 icon: ""
314 label: QT_TR_NOOP("Save to SD Card")
315 value: true
316 }
317 ListElement {
318 icon: ""
319 label: QT_TR_NOOP("Save internally")
320 value: false
321 }
299 }322 }
300 ]323 ]
301324
325 /* FIXME: application.removableStoragePresent is not updated dynamically.
326 Workaround that by reading it when the bottom edge is opened/closed.
327 */
328 Connections {
329 target: bottomEdge
330 onOpenedChanged: removableStorageOptionsModel.available = application.removableStoragePresent
331 }
332
302 function indexForValue(model, value) {333 function indexForValue(model, value) {
303 var i;334 var i;
304 var element;335 var element;
@@ -418,6 +449,9 @@
418 }449 }
419450
420 if (camera.captureMode == Camera.CaptureVideo) {451 if (camera.captureMode == Camera.CaptureVideo) {
452 if (application.removableStoragePresent && settings.preferRemovableStorage) {
453 camera.videoRecorder.outputLocation = application.removableStorageVideosLocation;
454 }
421 if (camera.videoRecorder.recorderState == CameraRecorder.StoppedState) {455 if (camera.videoRecorder.recorderState == CameraRecorder.StoppedState) {
422 camera.videoRecorder.setMetadata("Orientation", orientation);456 camera.videoRecorder.setMetadata("Orientation", orientation);
423 camera.videoRecorder.record();457 camera.videoRecorder.record();
@@ -441,6 +475,8 @@
441 }475 }
442 if (main.contentExportMode) {476 if (main.contentExportMode) {
443 camera.imageCapture.captureToLocation(application.temporaryLocation);477 camera.imageCapture.captureToLocation(application.temporaryLocation);
478 } else if (application.removableStoragePresent && settings.preferRemovableStorage) {
479 camera.imageCapture.captureToLocation(application.removableStoragePicturesLocation);
444 } else {480 } else {
445 camera.imageCapture.captureToLocation(application.picturesLocation);481 camera.imageCapture.captureToLocation(application.picturesLocation);
446 }482 }
447483
=== modified file 'camera-apparmor.json'
--- camera-apparmor.json 2014-07-31 18:41:17 +0000
+++ camera-apparmor.json 2014-12-11 16:55:23 +0000
@@ -11,4 +11,4 @@
11 "location"11 "location"
12 ],12 ],
13 "policy_version": 1.213 "policy_version": 1.2
14}
15\ No newline at end of file14\ No newline at end of file
15}
1616
=== modified file 'cameraapplication.cpp'
--- cameraapplication.cpp 2014-09-03 18:51:53 +0000
+++ cameraapplication.cpp 2014-12-11 16:55:23 +0000
@@ -147,3 +147,61 @@
147 dir.mkpath(location);147 dir.mkpath(location);
148 return location;148 return location;
149}149}
150
151bool CameraApplication::removableStoragePresent() const
152{
153 return !removableStorageLocation().isEmpty();
154}
155
156QString CameraApplication::removableStorageLocation() const
157{
158 /* FIXME: when Qt5.4 is available, switch to using newly introduced
159 * QStorageInfo API.
160 * Ref.: http://doc-snapshot.qt-project.org/qt5-5.4/qstorageinfo.html
161 */
162 QString userName = qgetenv("USER");
163 QDir media("/media/" + userName);
164 QStringList mediaDirs = media.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
165
166 if (mediaDirs.size() > 0) {
167 return QString("/media/" + userName + "/" + mediaDirs.at(0));
168 } else {
169 return QString();
170 }
171}
172
173QString CameraApplication::removableStoragePicturesLocation() const
174{
175 QString storageLocation = removableStorageLocation();
176 if (storageLocation.isEmpty()) {
177 return QString();
178 }
179
180 QStringList locations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
181 QString pictureDir = QString(locations.at(0)).split("/").value(3);
182 if (pictureDir.isEmpty()){
183 return QString();
184 }
185 QString location = storageLocation + "/" + pictureDir;
186 QDir dir;
187 dir.mkpath(location);
188 return location;
189}
190
191QString CameraApplication::removableStorageVideosLocation() const
192{
193 QString storageLocation = removableStorageLocation();
194 if (storageLocation.isEmpty()) {
195 return QString();
196 }
197
198 QStringList locations = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation);
199 QString movieDir = QString(locations.at(0)).split("/").value(3);
200 if (movieDir.isEmpty()){
201 return QString();
202 }
203 QString location = storageLocation + "/" + movieDir;
204 QDir dir;
205 dir.mkpath(location);
206 return location;
207}
150208
=== modified file 'cameraapplication.h'
--- cameraapplication.h 2014-07-31 18:41:17 +0000
+++ cameraapplication.h 2014-12-11 16:55:23 +0000
@@ -32,6 +32,10 @@
32 Q_PROPERTY(QString picturesLocation READ picturesLocation CONSTANT)32 Q_PROPERTY(QString picturesLocation READ picturesLocation CONSTANT)
33 Q_PROPERTY(QString videosLocation READ videosLocation CONSTANT)33 Q_PROPERTY(QString videosLocation READ videosLocation CONSTANT)
34 Q_PROPERTY(QString temporaryLocation READ temporaryLocation CONSTANT)34 Q_PROPERTY(QString temporaryLocation READ temporaryLocation CONSTANT)
35 Q_PROPERTY(bool removableStoragePresent READ removableStoragePresent NOTIFY removableStoragePresentChanged)
36 Q_PROPERTY(QString removableStorageLocation READ removableStorageLocation CONSTANT)
37 Q_PROPERTY(QString removableStoragePicturesLocation READ removableStoragePicturesLocation CONSTANT)
38 Q_PROPERTY(QString removableStorageVideosLocation READ removableStorageVideosLocation CONSTANT)
3539
36public:40public:
37 CameraApplication(int &argc, char **argv);41 CameraApplication(int &argc, char **argv);
@@ -41,6 +45,13 @@
41 QString picturesLocation() const;45 QString picturesLocation() const;
42 QString videosLocation() const;46 QString videosLocation() const;
43 QString temporaryLocation() const;47 QString temporaryLocation() const;
48 bool removableStoragePresent() const;
49 QString removableStorageLocation() const;
50 QString removableStoragePicturesLocation() const;
51 QString removableStorageVideosLocation() const;
52
53Q_SIGNALS:
54 void removableStoragePresentChanged();
4455
45private:56private:
46 QScopedPointer<QQuickView> m_view;57 QScopedPointer<QQuickView> m_view;
4758
=== modified file 'po/camera-app.pot'
--- po/camera-app.pot 2014-12-08 11:49:38 +0000
+++ po/camera-app.pot 2014-12-11 16:55:23 +0000
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: camera-app\n"9"Project-Id-Version: camera-app\n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2014-12-08 09:47-0200\n"11"POT-Creation-Date: 2014-12-11 10:23-0200\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -29,7 +29,7 @@
29msgid "Cancel"29msgid "Cancel"
30msgstr ""30msgstr ""
3131
32#: ../GalleryView.qml:18032#: ../GalleryView.qml:182
33msgid "No media available."33msgid "No media available."
34msgstr ""34msgstr ""
3535
@@ -49,46 +49,58 @@
49msgid "Share"49msgid "Share"
50msgstr ""50msgstr ""
5151
52#: ../ViewFinderOverlay.qml:140 ../ViewFinderOverlay.qml:16352#: ../ViewFinderOverlay.qml:141 ../ViewFinderOverlay.qml:164
53#: ../ViewFinderOverlay.qml:191 ../ViewFinderOverlay.qml:21453#: ../ViewFinderOverlay.qml:192 ../ViewFinderOverlay.qml:215
54#: ../ViewFinderOverlay.qml:29154#: ../ViewFinderOverlay.qml:292
55msgid "On"55msgid "On"
56msgstr ""56msgstr ""
5757
58#: ../ViewFinderOverlay.qml:145 ../ViewFinderOverlay.qml:17358#: ../ViewFinderOverlay.qml:146 ../ViewFinderOverlay.qml:174
59#: ../ViewFinderOverlay.qml:196 ../ViewFinderOverlay.qml:21959#: ../ViewFinderOverlay.qml:197 ../ViewFinderOverlay.qml:220
60#: ../ViewFinderOverlay.qml:238 ../ViewFinderOverlay.qml:29660#: ../ViewFinderOverlay.qml:239 ../ViewFinderOverlay.qml:297
61msgid "Off"61msgid "Off"
62msgstr ""62msgstr ""
6363
64#: ../ViewFinderOverlay.qml:16864#: ../ViewFinderOverlay.qml:169
65msgid "Auto"65msgid "Auto"
66msgstr ""66msgstr ""
6767
68#: ../ViewFinderOverlay.qml:20568#: ../ViewFinderOverlay.qml:206
69msgid "HDR"69msgid "HDR"
70msgstr ""70msgstr ""
7171
72#: ../ViewFinderOverlay.qml:24372#: ../ViewFinderOverlay.qml:244
73msgid "5 seconds"73msgid "5 seconds"
74msgstr ""74msgstr ""
7575
76#: ../ViewFinderOverlay.qml:24876#: ../ViewFinderOverlay.qml:249
77msgid "15 seconds"77msgid "15 seconds"
78msgstr ""78msgstr ""
7979
80#: ../ViewFinderOverlay.qml:26580#: ../ViewFinderOverlay.qml:266
81msgid "Fine Quality"81msgid "Fine Quality"
82msgstr ""82msgstr ""
8383
84#: ../ViewFinderOverlay.qml:26984#: ../ViewFinderOverlay.qml:270
85msgid "Normal Quality"85msgid "Normal Quality"
86msgstr ""86msgstr ""
8787
88#: ../ViewFinderOverlay.qml:27388#: ../ViewFinderOverlay.qml:274
89msgid "Basic Quality"89msgid "Basic Quality"
90msgstr ""90msgstr ""
9191
92#: ../ViewFinderOverlay.qml:306
93msgid "SD"
94msgstr ""
95
96#: ../ViewFinderOverlay.qml:314
97msgid "Save to SD Card"
98msgstr ""
99
100#: ../ViewFinderOverlay.qml:319
101msgid "Save internally"
102msgstr ""
103
92#: ../camera-app.qml:36104#: ../camera-app.qml:36
93msgid "Flash"105msgid "Flash"
94msgstr ""106msgstr ""

Subscribers

People subscribed via source and target branches