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

Proposed by Florian Boucault
Status: Merged
Approved by: Bill Filler
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
Ubuntu Phablet Team 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.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~fboucault/camera-app/sdcard updated
427. By Florian Boucault

Blurred viewfinder is now darker making bottom edge more readable.

428. By Florian Boucault

Less opaque blur.

429. By Florian Boucault

Merged trunk

430. By Florian Boucault

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

431. By Florian Boucault

Update pot

432. By Florian Boucault

Better backend code.

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
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)

Revision history for this message
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
433. By Florian Boucault

Removed unwanted write/read paths from apparmor profile.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~fboucault/camera-app/sdcard updated
434. By Florian Boucault

Merged from trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~fboucault/camera-app/sdcard updated
435. By Florian Boucault

Merged from trunk

436. By Florian Boucault

Added bug

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)

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