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
1=== modified file 'GalleryView.qml'
2--- GalleryView.qml 2014-12-03 12:37:15 +0000
3+++ GalleryView.qml 2014-12-11 16:55:23 +0000
4@@ -29,7 +29,9 @@
5 property bool userSelectionMode: false
6 property Item currentView: state == "GRID" ? photogridView : slideshowView
7 property var model: FoldersModel {
8- folders: [application.picturesLocation, application.videosLocation]
9+ folders: [application.picturesLocation, application.videosLocation,
10+ application.removableStoragePicturesLocation,
11+ application.removableStorageVideosLocation]
12 typeFilters: !main.contentExportMode ? [ "image", "video" ]
13 : [MimeTypeMapper.contentTypeToMimeType(main.transferContentType)]
14 singleSelectionOnly: main.transfer.selectionType === ContentTransfer.Single
15
16=== modified file 'ViewFinderOverlay.qml'
17--- ViewFinderOverlay.qml 2014-12-09 21:48:11 +0000
18+++ ViewFinderOverlay.qml 2014-12-11 16:55:23 +0000
19@@ -46,6 +46,7 @@
20 property int selfTimerDelay: 0
21 property int encodingQuality: 2 // QMultimedia.NormalQuality
22 property bool gridEnabled: false
23+ property bool preferRemovableStorage: false
24 }
25
26 Binding {
27@@ -296,9 +297,39 @@
28 label: QT_TR_NOOP("Off")
29 value: false
30 }
31+ },
32+ ListModel {
33+ id: removableStorageOptionsModel
34+
35+ property string settingsProperty: "preferRemovableStorage"
36+ property string icon: ""
37+ property string label: i18n.tr("SD")
38+ property bool isToggle: true
39+ property int selectedIndex: bottomEdge.indexForValue(removableStorageOptionsModel, settings.preferRemovableStorage)
40+ property bool available: application.removableStoragePresent
41+ property bool visible: available
42+
43+ ListElement {
44+ icon: ""
45+ label: QT_TR_NOOP("Save to SD Card")
46+ value: true
47+ }
48+ ListElement {
49+ icon: ""
50+ label: QT_TR_NOOP("Save internally")
51+ value: false
52+ }
53 }
54 ]
55
56+ /* FIXME: application.removableStoragePresent is not updated dynamically.
57+ Workaround that by reading it when the bottom edge is opened/closed.
58+ */
59+ Connections {
60+ target: bottomEdge
61+ onOpenedChanged: removableStorageOptionsModel.available = application.removableStoragePresent
62+ }
63+
64 function indexForValue(model, value) {
65 var i;
66 var element;
67@@ -418,6 +449,9 @@
68 }
69
70 if (camera.captureMode == Camera.CaptureVideo) {
71+ if (application.removableStoragePresent && settings.preferRemovableStorage) {
72+ camera.videoRecorder.outputLocation = application.removableStorageVideosLocation;
73+ }
74 if (camera.videoRecorder.recorderState == CameraRecorder.StoppedState) {
75 camera.videoRecorder.setMetadata("Orientation", orientation);
76 camera.videoRecorder.record();
77@@ -441,6 +475,8 @@
78 }
79 if (main.contentExportMode) {
80 camera.imageCapture.captureToLocation(application.temporaryLocation);
81+ } else if (application.removableStoragePresent && settings.preferRemovableStorage) {
82+ camera.imageCapture.captureToLocation(application.removableStoragePicturesLocation);
83 } else {
84 camera.imageCapture.captureToLocation(application.picturesLocation);
85 }
86
87=== modified file 'camera-apparmor.json'
88--- camera-apparmor.json 2014-07-31 18:41:17 +0000
89+++ camera-apparmor.json 2014-12-11 16:55:23 +0000
90@@ -11,4 +11,4 @@
91 "location"
92 ],
93 "policy_version": 1.2
94-}
95\ No newline at end of file
96+}
97
98=== modified file 'cameraapplication.cpp'
99--- cameraapplication.cpp 2014-09-03 18:51:53 +0000
100+++ cameraapplication.cpp 2014-12-11 16:55:23 +0000
101@@ -147,3 +147,61 @@
102 dir.mkpath(location);
103 return location;
104 }
105+
106+bool CameraApplication::removableStoragePresent() const
107+{
108+ return !removableStorageLocation().isEmpty();
109+}
110+
111+QString CameraApplication::removableStorageLocation() const
112+{
113+ /* FIXME: when Qt5.4 is available, switch to using newly introduced
114+ * QStorageInfo API.
115+ * Ref.: http://doc-snapshot.qt-project.org/qt5-5.4/qstorageinfo.html
116+ */
117+ QString userName = qgetenv("USER");
118+ QDir media("/media/" + userName);
119+ QStringList mediaDirs = media.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
120+
121+ if (mediaDirs.size() > 0) {
122+ return QString("/media/" + userName + "/" + mediaDirs.at(0));
123+ } else {
124+ return QString();
125+ }
126+}
127+
128+QString CameraApplication::removableStoragePicturesLocation() const
129+{
130+ QString storageLocation = removableStorageLocation();
131+ if (storageLocation.isEmpty()) {
132+ return QString();
133+ }
134+
135+ QStringList locations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
136+ QString pictureDir = QString(locations.at(0)).split("/").value(3);
137+ if (pictureDir.isEmpty()){
138+ return QString();
139+ }
140+ QString location = storageLocation + "/" + pictureDir;
141+ QDir dir;
142+ dir.mkpath(location);
143+ return location;
144+}
145+
146+QString CameraApplication::removableStorageVideosLocation() const
147+{
148+ QString storageLocation = removableStorageLocation();
149+ if (storageLocation.isEmpty()) {
150+ return QString();
151+ }
152+
153+ QStringList locations = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation);
154+ QString movieDir = QString(locations.at(0)).split("/").value(3);
155+ if (movieDir.isEmpty()){
156+ return QString();
157+ }
158+ QString location = storageLocation + "/" + movieDir;
159+ QDir dir;
160+ dir.mkpath(location);
161+ return location;
162+}
163
164=== modified file 'cameraapplication.h'
165--- cameraapplication.h 2014-07-31 18:41:17 +0000
166+++ cameraapplication.h 2014-12-11 16:55:23 +0000
167@@ -32,6 +32,10 @@
168 Q_PROPERTY(QString picturesLocation READ picturesLocation CONSTANT)
169 Q_PROPERTY(QString videosLocation READ videosLocation CONSTANT)
170 Q_PROPERTY(QString temporaryLocation READ temporaryLocation CONSTANT)
171+ Q_PROPERTY(bool removableStoragePresent READ removableStoragePresent NOTIFY removableStoragePresentChanged)
172+ Q_PROPERTY(QString removableStorageLocation READ removableStorageLocation CONSTANT)
173+ Q_PROPERTY(QString removableStoragePicturesLocation READ removableStoragePicturesLocation CONSTANT)
174+ Q_PROPERTY(QString removableStorageVideosLocation READ removableStorageVideosLocation CONSTANT)
175
176 public:
177 CameraApplication(int &argc, char **argv);
178@@ -41,6 +45,13 @@
179 QString picturesLocation() const;
180 QString videosLocation() const;
181 QString temporaryLocation() const;
182+ bool removableStoragePresent() const;
183+ QString removableStorageLocation() const;
184+ QString removableStoragePicturesLocation() const;
185+ QString removableStorageVideosLocation() const;
186+
187+Q_SIGNALS:
188+ void removableStoragePresentChanged();
189
190 private:
191 QScopedPointer<QQuickView> m_view;
192
193=== modified file 'po/camera-app.pot'
194--- po/camera-app.pot 2014-12-08 11:49:38 +0000
195+++ po/camera-app.pot 2014-12-11 16:55:23 +0000
196@@ -8,7 +8,7 @@
197 msgstr ""
198 "Project-Id-Version: camera-app\n"
199 "Report-Msgid-Bugs-To: \n"
200-"POT-Creation-Date: 2014-12-08 09:47-0200\n"
201+"POT-Creation-Date: 2014-12-11 10:23-0200\n"
202 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
203 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
204 "Language-Team: LANGUAGE <LL@li.org>\n"
205@@ -29,7 +29,7 @@
206 msgid "Cancel"
207 msgstr ""
208
209-#: ../GalleryView.qml:180
210+#: ../GalleryView.qml:182
211 msgid "No media available."
212 msgstr ""
213
214@@ -49,46 +49,58 @@
215 msgid "Share"
216 msgstr ""
217
218-#: ../ViewFinderOverlay.qml:140 ../ViewFinderOverlay.qml:163
219-#: ../ViewFinderOverlay.qml:191 ../ViewFinderOverlay.qml:214
220-#: ../ViewFinderOverlay.qml:291
221+#: ../ViewFinderOverlay.qml:141 ../ViewFinderOverlay.qml:164
222+#: ../ViewFinderOverlay.qml:192 ../ViewFinderOverlay.qml:215
223+#: ../ViewFinderOverlay.qml:292
224 msgid "On"
225 msgstr ""
226
227-#: ../ViewFinderOverlay.qml:145 ../ViewFinderOverlay.qml:173
228-#: ../ViewFinderOverlay.qml:196 ../ViewFinderOverlay.qml:219
229-#: ../ViewFinderOverlay.qml:238 ../ViewFinderOverlay.qml:296
230+#: ../ViewFinderOverlay.qml:146 ../ViewFinderOverlay.qml:174
231+#: ../ViewFinderOverlay.qml:197 ../ViewFinderOverlay.qml:220
232+#: ../ViewFinderOverlay.qml:239 ../ViewFinderOverlay.qml:297
233 msgid "Off"
234 msgstr ""
235
236-#: ../ViewFinderOverlay.qml:168
237+#: ../ViewFinderOverlay.qml:169
238 msgid "Auto"
239 msgstr ""
240
241-#: ../ViewFinderOverlay.qml:205
242+#: ../ViewFinderOverlay.qml:206
243 msgid "HDR"
244 msgstr ""
245
246-#: ../ViewFinderOverlay.qml:243
247+#: ../ViewFinderOverlay.qml:244
248 msgid "5 seconds"
249 msgstr ""
250
251-#: ../ViewFinderOverlay.qml:248
252+#: ../ViewFinderOverlay.qml:249
253 msgid "15 seconds"
254 msgstr ""
255
256-#: ../ViewFinderOverlay.qml:265
257+#: ../ViewFinderOverlay.qml:266
258 msgid "Fine Quality"
259 msgstr ""
260
261-#: ../ViewFinderOverlay.qml:269
262+#: ../ViewFinderOverlay.qml:270
263 msgid "Normal Quality"
264 msgstr ""
265
266-#: ../ViewFinderOverlay.qml:273
267+#: ../ViewFinderOverlay.qml:274
268 msgid "Basic Quality"
269 msgstr ""
270
271+#: ../ViewFinderOverlay.qml:306
272+msgid "SD"
273+msgstr ""
274+
275+#: ../ViewFinderOverlay.qml:314
276+msgid "Save to SD Card"
277+msgstr ""
278+
279+#: ../ViewFinderOverlay.qml:319
280+msgid "Save internally"
281+msgstr ""
282+
283 #: ../camera-app.qml:36
284 msgid "Flash"
285 msgstr ""

Subscribers

People subscribed via source and target branches