Merge lp:~nik90/ubuntu-clock-app/custom-alarm-sound into lp:ubuntu-clock-app

Proposed by Nekhelesh Ramananthan on 2015-08-19
Status: Merged
Approved by: Bartosz Kosiorek on 2015-08-21
Approved revision: 369
Merged at revision: 345
Proposed branch: lp:~nik90/ubuntu-clock-app/custom-alarm-sound
Merge into: lp:ubuntu-clock-app
Prerequisite: lp:~nik90/ubuntu-clock-app/add-utility-backend
Diff against target: 733 lines (+374/-49)
12 files modified
app/alarm/AlarmSound.qml (+211/-6)
app/alarm/CMakeLists.txt (+1/-0)
app/alarm/EditAlarmPage.qml (+73/-31)
app/alarm/SoundPeerPicker.qml (+43/-0)
app/ubuntu-clock-app.qml (+7/-0)
backend/modules/Clock/Utility/customalarmsound.cpp (+12/-1)
backend/modules/Clock/Utility/customalarmsound.h (+3/-0)
debian/changelog (+1/-0)
debian/control (+2/-0)
po/com.ubuntu.clock.pot (+18/-9)
tests/unit/tst_alarmSound.qml (+2/-2)
ubuntu-clock-app.json (+1/-0)
To merge this branch: bzr merge lp:~nik90/ubuntu-clock-app/custom-alarm-sound
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve on 2015-08-21
Bartosz Kosiorek 2015-08-19 Approve on 2015-08-21
Andrew Hayzen (community) functional Approve on 2015-08-20
Review via email: mp+268499@code.launchpad.net

Commit Message

Add support for setting custom alarm sounds

Description of the Change

Added support for setting custom alarm sounds :-) This first requires the prerequisite branch to land in trunk.

Steps to test
-------------
bzr branch lp:~ahayzen/music-app/fix-1357324-content-hub-source
cd fix-1357324-content-hub-source
click-buddy
Install music-app click package in the phone
Install this MP's clock app on the phone
Reboot phone for good measure
Test feature

Things Done
-----------
- Merged prerequisite branch to trunk
- Refactor and clean code
- Rebuilt pot file
- Manual testing

To post a comment you must log in.
review: Needs Fixing (continuous-integration)
348. By Nekhelesh Ramananthan on 2015-08-19

Added ubuntu content hub package as dependecy in debian control

review: Approve (continuous-integration)
349. By Nekhelesh Ramananthan on 2015-08-19

Some minor fixes

350. By Nekhelesh Ramananthan on 2015-08-19

Some code refactor, bug fixes and polish

351. By Nekhelesh Ramananthan on 2015-08-19

Minor fix

review: Approve (continuous-integration)
352. By Nekhelesh Ramananthan on 2015-08-19

Some final touches

review: Approve (continuous-integration)
353. By Nekhelesh Ramananthan on 2015-08-20

Merged prerequisite

354. By Nekhelesh Ramananthan on 2015-08-20

Adjusted to the new properties of the customsound plugin

review: Approve (continuous-integration)
355. By Nekhelesh Ramananthan on 2015-08-20

Finally fixed the one last nagging issue.

review: Approve (continuous-integration)
356. By Nekhelesh Ramananthan on 2015-08-20

merged lp:ubuntu-clock-app

review: Approve (continuous-integration)
357. By Nekhelesh Ramananthan on 2015-08-20

Fixed ubuntu-clock-app.json breaking due to recent trunk merge

review: Approve (continuous-integration)
358. By Nekhelesh Ramananthan on 2015-08-20

Save custom sounds in their own dedicated folder. Also allow all music formats

359. By Nekhelesh Ramananthan on 2015-08-20

Elide music filenames if they are too long

review: Approve (continuous-integration)
360. By Nekhelesh Ramananthan on 2015-08-20

Create the custom alarm sound directory if it is not present to avoid issues with the qml folderlistmodel

review: Approve (continuous-integration)
Andrew Hayzen (ahayzen) wrote :

Looks good to me and is a great addition to the platform :-)

Tested adding multiple custom alarms, removing them (note bug 1486008), previewing the audio, set an alarm in the future to check that the correct sound is used and tested with an empty ~/.local/share/com.ubuntu.clock (to test startup with no CustomSounds folder).

Thanks for the extra changes in supporting all audio formats :-)

review: Approve (functional)
361. By Nekhelesh Ramananthan on 2015-08-21

Play/Stop alarm sound preview when clicking on the list item

review: Approve (continuous-integration)
362. By Nekhelesh Ramananthan on 2015-08-21

Renamed page title to add sound from

363. By Nekhelesh Ramananthan on 2015-08-21

Renamed MusicAppPicker to SoundPeerPicker

Bartosz Kosiorek (gang65) wrote :

Some small improvements.

review: Needs Information
review: Approve (continuous-integration)
364. By Nekhelesh Ramananthan on 2015-08-21

Changed variable name to defaultSoundModel

365. By Nekhelesh Ramananthan on 2015-08-21

Changed _soundName to defaultAlarmSound variable name to make it more understandable

review: Needs Fixing (continuous-integration)
Bartosz Kosiorek (gang65) wrote :

Approved.
Don't forget to regenerate translation template.

review: Approve
366. By Nekhelesh Ramananthan on 2015-08-21

Fixed failing unit test

review: Approve (continuous-integration)
367. By Nekhelesh Ramananthan on 2015-08-21

Fix empty alarm sound issue when an custom alarm is deleted elsewhere by the user

review: Approve (continuous-integration)
368. By Nekhelesh Ramananthan on 2015-08-21

Merged trunk lp:ubuntu-clock-app

369. By Nekhelesh Ramananthan on 2015-08-21

Updated pot file

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/alarm/AlarmSound.qml'
2--- app/alarm/AlarmSound.qml 2015-08-13 13:29:49 +0000
3+++ app/alarm/AlarmSound.qml 2015-08-21 16:08:35 +0000
4@@ -17,7 +17,9 @@
5 */
6
7 import QtQuick 2.4
8+import Clock.Utility 1.0
9 import QtMultimedia 5.0
10+import Ubuntu.Content 1.1
11 import Ubuntu.Components 1.2
12
13 Page {
14@@ -28,6 +30,9 @@
15 flickable: _pageFlickable
16 visible: false
17
18+ // Property used to let pageStack know that this is the alarm sound page
19+ property bool isAlarmSoundPage: true
20+
21 // Property to set the alarm sound in the edit alarm page
22 property var alarmSound
23
24@@ -35,7 +40,10 @@
25 property var alarm
26
27 // Property to set the alarm sound model in the edit alarm page
28- property var soundModel
29+ property var defaultSoundModel
30+
31+ // Property to set the custom alarm sound model in the edit alarm page
32+ property var customSoundModel
33
34 /*
35 Properties to store the previously set alarm sound values to detect
36@@ -44,6 +52,11 @@
37 property url oldAlarmSoundUrl
38 property string oldAlarmSoundName
39
40+ // Content-hub Import Properties
41+ property list<ContentItem> importItems
42+ property var activeTransfer
43+ property list<ContentPeer> peers
44+
45 Component.onCompleted: {
46 // Record the current alarm sound values (url, name)
47 oldAlarmSoundUrl = alarm.sound
48@@ -70,27 +83,211 @@
49 }
50 }
51
52+ ContentTransferHint {
53+ anchors.fill: parent
54+ activeTransfer: _alarmSoundPage.activeTransfer
55+ }
56+
57+ Connections {
58+ target: _alarmSoundPage.activeTransfer
59+ onStateChanged: {
60+ if (_alarmSoundPage.activeTransfer.state === ContentTransfer.Charged) {
61+ _alarmSoundPage.importItems = _alarmSoundPage.activeTransfer.items
62+ console.log("[LOG] Original Custom Alarm Sound URL: " + _alarmSoundPage.importItems[0].url)
63+ _alarmSoundPage.importItems[0].move(customSound.alarmSoundDirectory)
64+ console.log("[LOG] Final Custom Alarm Sound URL: " + _alarmSoundPage.importItems[0].url)
65+ }
66+ }
67+ }
68+
69 Audio {
70 id: previewAlarmSound
71 audioRole: MediaPlayer.alert
72+
73+ function controlPlayback(fileURL) {
74+ source = fileURL
75+ if (playbackState === Audio.StoppedState || playbackState === Audio.PausedState) {
76+ play()
77+ } else if (playbackState === Audio.PlayingState) {
78+ stop()
79+ }
80+ }
81+ }
82+
83+ CustomAlarmSound {
84+ id: customSound
85 }
86
87 Flickable {
88 id: _pageFlickable
89
90 anchors.fill: parent
91- contentHeight: soundModel.count * units.gu(7)
92+ contentHeight: defaultSoundModel.count * units.gu(7) +
93+ customSoundModel.count * units.gu(7) +
94+ customSoundListItem.height
95
96 Column {
97 id: _alarmSoundColumn
98
99 anchors.fill: parent
100
101+ ListItem {
102+ id: customSoundListItem
103+ height: units.gu(7)
104+ Button {
105+ id: customSoundButton
106+ text: i18n.tr("Add custom sound")
107+ width: parent.width / 1.1
108+ anchors.centerIn: parent
109+ onClicked: {
110+ pageStack.push(Qt.resolvedUrl("SoundPeerPicker.qml"), {alarmSoundPage: _alarmSoundPage})
111+ }
112+ }
113+ }
114+
115+ Repeater {
116+ id: _customAlarmSounds
117+ objectName: "customAlarmSounds"
118+
119+ model: customSoundModel
120+
121+ ListItem {
122+ id: _customAlarmSoundDelegate
123+
124+ property alias isChecked: _customSoundStatus.checked
125+
126+ height: units.gu(7)
127+
128+ leadingActions: ListItemActions {
129+ actions: [
130+ Action {
131+ iconName: "delete"
132+ onTriggered: {
133+ previewAlarmSound.stop()
134+
135+ /*
136+ In case the selected custom alarm sound is deleted by the user, then
137+ set the alarm sound back to the default sound.
138+ */
139+ if (_customAlarmSoundDelegate.isChecked) {
140+
141+ /*
142+ If the oldAlarmSoundName is the deleted custom alarm sound, then
143+ set the oldAlarmSound name & url to the default alarm ringtone as well.
144+ */
145+ if (oldAlarmSoundName === fileBaseName) {
146+ alarmSound.subText = alarmSound.defaultAlarmSound
147+ oldAlarmSoundName = alarmSound.defaultAlarmSound
148+ for (var i=0; i<defaultSoundModel.count; i++) {
149+ if (defaultSoundModel.get(i, "fileBaseName") === alarmSound.subText) {
150+ alarm.sound = defaultSoundModel.get(i, "fileURL")
151+ oldAlarmSoundUrl = alarm.sound
152+ previewAlarmSound.source = defaultSoundModel.get(i, "fileURL")
153+ _alarmSounds.itemAt(i).isChecked = true
154+ }
155+ }
156+ }
157+
158+ else {
159+ alarmSound.subText = oldAlarmSoundName
160+ alarm.sound = oldAlarmSoundUrl
161+ previewAlarmSound.source = alarm.sound
162+
163+ for (var j=0; j<defaultSoundModel.count; j++) {
164+ if (defaultSoundModel.get(j, "fileBaseName") === alarmSound.subText) {
165+ _alarmSounds.itemAt(j).isChecked = true
166+ }
167+ }
168+
169+ for (j=0; j<customSoundModel.count; j++) {
170+ if (customSoundModel.get(j, "fileBaseName") === alarmSound.subText) {
171+ _customAlarmSounds.itemAt(j).isChecked = true
172+ }
173+ }
174+ }
175+ }
176+
177+ customSound.deleteAlarmSound(fileName)
178+ }
179+ }
180+ ]
181+ }
182+
183+ Label {
184+ id: _customSoundName
185+ objectName: "customSoundName" + index
186+
187+ anchors {
188+ left: parent.left
189+ leftMargin: units.gu(2)
190+ right: _customSoundStatus.left
191+ rightMargin: units.gu(2)
192+ verticalCenter: parent.verticalCenter
193+ }
194+
195+ elide: Text.ElideRight
196+ color: UbuntuColors.midAubergine
197+ fontSize: "medium"
198+ text: fileBaseName
199+ }
200+
201+ CheckBox {
202+ id: _customSoundStatus
203+ objectName: "customSoundStatus" + index
204+
205+ anchors {
206+ right: parent.right
207+ rightMargin: units.gu(2)
208+ verticalCenter: parent.verticalCenter
209+ }
210+
211+ checked: alarmSound.subText === _customSoundName.text ? true
212+ : false
213+ onCheckedChanged: {
214+ if (checked) {
215+ previewAlarmSound.controlPlayback(fileURL)
216+ alarmSound.subText = _customSoundName.text
217+ alarm.sound = fileURL
218+
219+ // Ensures only one alarm sound is selected
220+ for(var i=0; i<customSoundModel.count; i++) {
221+ if(_customAlarmSounds.itemAt(i).isChecked &&
222+ i !== index) {
223+ _customAlarmSounds.itemAt(i).isChecked = false
224+ }
225+ }
226+
227+ // Ensures only one alarm customSoundModelsound is selected
228+ for(i=0; i<defaultSoundModel.count; i++) {
229+ _alarmSounds.itemAt(i).isChecked = false
230+ }
231+ }
232+ }
233+
234+ onClicked: {
235+ if (!checked) {
236+ checked = true
237+ } else {
238+ previewAlarmSound.controlPlayback(fileURL)
239+ }
240+ }
241+ }
242+
243+ onClicked: {
244+ if (!_customSoundStatus.checked) {
245+ _customSoundStatus.checked = true
246+ } else {
247+ previewAlarmSound.controlPlayback(fileURL)
248+ }
249+ }
250+ }
251+ }
252+
253 Repeater {
254 id: _alarmSounds
255 objectName: "alarmSounds"
256
257- model: soundModel
258+ model: defaultSoundModel
259
260 ListItem {
261 id: _alarmSoundDelegate
262@@ -128,24 +325,30 @@
263 : false
264 onCheckedChanged: {
265 if (checked) {
266- previewAlarmSound.source = fileURL
267- previewAlarmSound.play()
268+ previewAlarmSound.controlPlayback(fileURL)
269 alarmSound.subText = _soundName.text
270 alarm.sound = fileURL
271
272 // Ensures only one alarm sound is selected
273- for(var i=0; i<soundModel.count; i++) {
274+ for(var i=0; i<defaultSoundModel.count; i++) {
275 if(_alarmSounds.itemAt(i).isChecked &&
276 i !== index) {
277 _alarmSounds.itemAt(i).isChecked = false
278 }
279 }
280+
281+ // Ensures only one alarm sound is selected
282+ for(i=0; i<customSoundModel.count; i++) {
283+ _customAlarmSounds.itemAt(i).isChecked = false
284+ }
285 }
286 }
287
288 onClicked: {
289 if (!checked) {
290 checked = true
291+ } else {
292+ previewAlarmSound.controlPlayback(fileURL)
293 }
294 }
295 }
296@@ -153,6 +356,8 @@
297 onClicked: {
298 if (!_soundStatus.checked) {
299 _soundStatus.checked = true
300+ } else {
301+ previewAlarmSound.controlPlayback(fileURL)
302 }
303 }
304 }
305
306=== modified file 'app/alarm/CMakeLists.txt'
307--- app/alarm/CMakeLists.txt 2015-08-11 15:05:34 +0000
308+++ app/alarm/CMakeLists.txt 2015-08-21 16:08:35 +0000
309@@ -9,6 +9,7 @@
310 AlarmSound.qml
311 AlarmUtils.qml
312 EditAlarmPage.qml
313+ SoundPeerPicker.qml
314 )
315
316 # make the files visible in the qtcreator tree
317
318=== modified file 'app/alarm/EditAlarmPage.qml'
319--- app/alarm/EditAlarmPage.qml 2015-08-14 13:39:38 +0000
320+++ app/alarm/EditAlarmPage.qml 2015-08-21 16:08:35 +0000
321@@ -18,6 +18,7 @@
322
323 import QtQuick 2.4
324 import DateTime 1.0
325+import Clock.Utility 1.0
326 import Ubuntu.Components 1.2
327 import Qt.labs.folderlistmodel 2.1
328 import Ubuntu.Components.Pickers 1.0
329@@ -125,17 +126,50 @@
330 }
331
332 function getSoundName(chosenSoundPath) {
333- for(var i=0; i<soundModel.count; i++) {
334- if(chosenSoundPath === Qt.resolvedUrl(soundModel.get(i, "filePath"))) {
335- return soundModel.get(i, "fileBaseName")
336- }
337- }
338+ for(var i=0; i<defaultSoundModel.count; i++) {
339+ if(chosenSoundPath === Qt.resolvedUrl(defaultSoundModel.get(i, "filePath"))) {
340+ return defaultSoundModel.get(i, "fileBaseName")
341+ }
342+ }
343+
344+ for(var j=0; j<customSoundModel.count; j++) {
345+ if(chosenSoundPath === Qt.resolvedUrl(customSoundModel.get(j, "filePath"))) {
346+ return customSoundModel.get(j, "fileBaseName")
347+ }
348+ }
349+
350+ return ""
351 }
352
353 function getSoundPath(chosenSoundName) {
354- for(var i=0; i<soundModel.count; i++) {
355- if(chosenSoundName === soundModel.get(i, "fileBaseName")) {
356- return soundModel.get(i, "filePath")
357+ for(var i=0; i<defaultSoundModel.count; i++) {
358+ if(chosenSoundName === defaultSoundModel.get(i, "fileBaseName")) {
359+ return defaultSoundModel.get(i, "filePath")
360+ }
361+ }
362+
363+ for(var j=0; j<customSoundModel.count; j++) {
364+ if(chosenSoundName === customSoundModel.get(i, "fileBaseName")) {
365+ return customSoundModel.get(i, "filePath")
366+ }
367+ }
368+ }
369+
370+ function setAlarmSound() {
371+ if(isNewAlarm) {
372+ _alarm.sound = getSoundPath(_alarmSound.defaultAlarmSound)
373+ _alarmSound.subText = _alarmSound.defaultAlarmSound
374+ }
375+ else {
376+ _alarmSound.subText = getSoundName(_alarm.sound.toString())
377+ /*
378+ If the custom alarm sound of an alarm was deleted by the user,
379+ then fall back to the default alarm sound instead of showing an
380+ empty string.
381+ */
382+ if (_alarmSound.subText === "") {
383+ _alarm.sound = getSoundPath(_alarmSound.defaultAlarmSound)
384+ _alarmSound.subText = _alarmSound.defaultAlarmSound
385 }
386 }
387 }
388@@ -195,7 +229,7 @@
389 }
390
391 FolderListModel {
392- id: soundModel
393+ id: defaultSoundModel
394
395 showDirs: false
396 nameFilters: [ "*.ogg", "*.mp3" ]
397@@ -203,26 +237,33 @@
398
399 onCountChanged: {
400 if(count > 0) {
401- /*
402- When folder model is completely loaded, proceed to perform
403- the following operations,
404-
405- if new alarm, then set the sound name as "Alarm clock" and
406- retrieve the sound path from the folder model to assign to
407- the alarm model sound property.
408-
409- If it is a saved alarm, get the sound path from the alarm
410- object and retrieve the sound name from the folder model.
411- */
412- if(isNewAlarm) {
413- _alarm.sound = getSoundPath(_alarmSound._soundName)
414- _alarmSound.subText = _alarmSound._soundName
415- }
416- else {
417- _alarmSound.subText = getSoundName(_alarm.sound.toString())
418- }
419- }
420- }
421+ // When folder model is completely loaded set the alarm sound.
422+ if(!pageStack.currentPage.isAlarmSoundPage) {
423+ setAlarmSound()
424+ }
425+ }
426+ }
427+ }
428+
429+ FolderListModel {
430+ id: customSoundModel
431+
432+ showDirs: false
433+ folder: customSound.alarmSoundDirectory
434+
435+ onCountChanged: {
436+ if(count > 0) {
437+ // When folder model is completely loaded set the alarm sound.
438+ if(!pageStack.currentPage.isAlarmSoundPage) {
439+ setAlarmSound()
440+ }
441+ }
442+ }
443+ }
444+
445+ // Custom C++ Component that returns the clock app directory /home/phablet/.local/share/com.ubuntu.clock
446+ CustomAlarmSound {
447+ id: customSound
448 }
449
450 AlarmUtils {
451@@ -298,13 +339,14 @@
452 objectName: "alarmSound"
453
454 // Default Alarm Sound for new alarms
455- property string _soundName: "Alarm clock"
456+ property string defaultAlarmSound: "Alarm clock"
457
458 text: i18n.tr("Sound")
459 onClicked: pageStack.push(Qt.resolvedUrl("AlarmSound.qml"), {
460 "alarmSound": _alarmSound,
461 "alarm": _alarm,
462- "soundModel": soundModel
463+ "defaultSoundModel": defaultSoundModel,
464+ "customSoundModel": customSoundModel
465 })
466 }
467 }
468
469=== added file 'app/alarm/SoundPeerPicker.qml'
470--- app/alarm/SoundPeerPicker.qml 1970-01-01 00:00:00 +0000
471+++ app/alarm/SoundPeerPicker.qml 2015-08-21 16:08:35 +0000
472@@ -0,0 +1,43 @@
473+/*
474+ * Copyright (C) 2015 Canonical Ltd
475+ *
476+ * This file is part of Ubuntu Clock App
477+ *
478+ * Ubuntu Clock App is free software: you can redistribute it and/or modify
479+ * it under the terms of the GNU General Public License version 3 as
480+ * published by the Free Software Foundation.
481+ *
482+ * Ubuntu Clock App is distributed in the hope that it will be useful,
483+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
484+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
485+ * GNU General Public License for more details.
486+ *
487+ * You should have received a copy of the GNU General Public License
488+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
489+ */
490+
491+import QtQuick 2.4
492+import Ubuntu.Components 1.2
493+import Ubuntu.Content 1.1
494+
495+Page {
496+ id: picker
497+
498+ // #TRANSLATORS: This is the page title. Please keep the translation length to 3 words if possible
499+ title: i18n.tr("Add sound from")
500+
501+ property var alarmSoundPage
502+
503+ ContentPeerPicker {
504+ id: peerPicker
505+ handler: ContentHandler.Source
506+ contentType: ContentType.Music
507+ showTitle: false
508+
509+ onPeerSelected: {
510+ peer.selectionType = ContentTransfer.Single
511+ alarmSoundPage.activeTransfer = peer.request()
512+ pageStack.pop()
513+ }
514+ }
515+}
516
517=== modified file 'app/ubuntu-clock-app.qml'
518--- app/ubuntu-clock-app.qml 2015-08-20 21:15:00 +0000
519+++ app/ubuntu-clock-app.qml 2015-08-21 16:08:35 +0000
520@@ -19,6 +19,7 @@
521 import QtQuick 2.4
522 import DateTime 1.0
523 import U1db 1.0 as U1db
524+import Clock.Utility 1.0
525 import Ubuntu.Components 1.2
526 import "components"
527
528@@ -82,6 +83,12 @@
529 updateInterval: 1000
530 }
531
532+ CustomAlarmSound {
533+ id: customSound
534+ // Create CustomSounds directory if it does not exist on app startup
535+ Component.onCompleted: createAlarmSoundDirectory()
536+ }
537+
538 onApplicationStateChanged: {
539 localTimeSource.update()
540 /*
541
542=== modified file 'backend/modules/Clock/Utility/customalarmsound.cpp'
543--- backend/modules/Clock/Utility/customalarmsound.cpp 2015-08-20 19:08:56 +0000
544+++ backend/modules/Clock/Utility/customalarmsound.cpp 2015-08-21 16:08:35 +0000
545@@ -23,7 +23,7 @@
546
547 CustomAlarmSound::CustomAlarmSound(QObject *parent):
548 QObject(parent),
549- m_customAlarmDir(QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).first())
550+ m_customAlarmDir(QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).first() + "/CustomSounds/")
551 {
552 }
553
554@@ -37,3 +37,14 @@
555 QDir dir(m_customAlarmDir);
556 dir.remove(soundName);
557 }
558+
559+void CustomAlarmSound::createAlarmSoundDirectory()
560+{
561+ QDir dir(m_customAlarmDir);
562+
563+ if (dir.exists()) {
564+ return;
565+ }
566+
567+ dir.mkpath(m_customAlarmDir);
568+}
569
570=== modified file 'backend/modules/Clock/Utility/customalarmsound.h'
571--- backend/modules/Clock/Utility/customalarmsound.h 2015-08-20 19:08:56 +0000
572+++ backend/modules/Clock/Utility/customalarmsound.h 2015-08-21 16:08:35 +0000
573@@ -39,6 +39,9 @@
574 // Function to delete a custom alarm sound
575 void deleteAlarmSound(const QString &soundName);
576
577+ // Function to create the CustomSounds alarm directory
578+ void createAlarmSoundDirectory();
579+
580 private:
581 QString m_customAlarmDir;
582 };
583
584=== modified file 'debian/changelog'
585--- debian/changelog 2015-08-21 11:00:03 +0000
586+++ debian/changelog 2015-08-21 16:08:35 +0000
587@@ -19,6 +19,7 @@
588 * Changed default alarm sound (LP: #1354370)
589 * Added Clock Utility C++ plugin housing CustomAlarmSound type required
590 for custom alarm sound feature
591+ * Added support for setting custom alarm sounds (LP: #1450640)
592
593 [Victor Thompson]
594 * Show all README files in QtCreator
595
596=== modified file 'debian/control'
597--- debian/control 2015-08-16 13:17:00 +0000
598+++ debian/control 2015-08-21 16:08:35 +0000
599@@ -15,6 +15,7 @@
600 qtdeclarative5-u1db1.0,
601 qtdeclarative5-qtmultimedia-plugin,
602 qtdeclarative5-qtpositioning-plugin,
603+ qtdeclarative5-ubuntu-content1,
604 qt5-default,
605 qtbase5-dev,
606 qtdeclarative5-dev,
607@@ -36,6 +37,7 @@
608 qtdeclarative5-xmllistmodel-plugin,
609 qtdeclarative5-qtmultimedia-plugin,
610 qtdeclarative5-qtpositioning-plugin,
611+ qtdeclarative5-ubuntu-content1,
612 ubuntu-touch-sounds,
613 suru-icon-theme | ubuntu-mobile-icons,
614 ${misc:Depends},
615
616=== modified file 'po/com.ubuntu.clock.pot'
617--- po/com.ubuntu.clock.pot 2015-08-21 12:15:41 +0000
618+++ po/com.ubuntu.clock.pot 2015-08-21 16:08:35 +0000
619@@ -8,7 +8,7 @@
620 msgstr ""
621 "Project-Id-Version: \n"
622 "Report-Msgid-Bugs-To: \n"
623-"POT-Creation-Date: 2015-08-21 14:14+0200\n"
624+"POT-Creation-Date: 2015-08-21 18:07+0200\n"
625 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
626 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
627 "Language-Team: LANGUAGE <LL@li.org>\n"
628@@ -23,7 +23,7 @@
629 msgstr ""
630
631 #: ../app/alarm/AlarmLabel.qml:33 ../app/alarm/AlarmLabel.qml:71
632-#: ../app/alarm/EditAlarmPage.qml:290
633+#: ../app/alarm/EditAlarmPage.qml:331
634 msgid "Label"
635 msgstr ""
636
637@@ -41,8 +41,8 @@
638 msgid "Back"
639 msgstr ""
640
641-#: ../app/alarm/AlarmPage.qml:49 ../app/alarm/EditAlarmPage.qml:43
642-#: ../app/alarm/EditAlarmPage.qml:165
643+#: ../app/alarm/AlarmPage.qml:49 ../app/alarm/EditAlarmPage.qml:44
644+#: ../app/alarm/EditAlarmPage.qml:199
645 msgid "Alarm"
646 msgstr ""
647
648@@ -62,7 +62,7 @@
649 msgid "Tap the + icon to add an alarm"
650 msgstr ""
651
652-#: ../app/alarm/AlarmRepeat.qml:36 ../app/alarm/EditAlarmPage.qml:280
653+#: ../app/alarm/AlarmRepeat.qml:36 ../app/alarm/EditAlarmPage.qml:321
654 msgid "Repeat"
655 msgstr ""
656
657@@ -104,10 +104,14 @@
658 msgid "Change time and date"
659 msgstr ""
660
661-#: ../app/alarm/AlarmSound.qml:27 ../app/alarm/EditAlarmPage.qml:303
662+#: ../app/alarm/AlarmSound.qml:29 ../app/alarm/EditAlarmPage.qml:344
663 msgid "Sound"
664 msgstr ""
665
666+#: ../app/alarm/AlarmSound.qml:139
667+msgid "Add custom sound"
668+msgstr ""
669+
670 #: ../app/alarm/AlarmUtils.qml:31
671 msgid "Never"
672 msgstr ""
673@@ -148,18 +152,23 @@
674 msgid "in %1m"
675 msgstr ""
676
677-#: ../app/alarm/EditAlarmPage.qml:36
678+#: ../app/alarm/EditAlarmPage.qml:37
679 msgid "New alarm"
680 msgstr ""
681
682-#: ../app/alarm/EditAlarmPage.qml:36
683+#: ../app/alarm/EditAlarmPage.qml:37
684 msgid "Edit alarm"
685 msgstr ""
686
687-#: ../app/alarm/EditAlarmPage.qml:324
688+#: ../app/alarm/EditAlarmPage.qml:366
689 msgid "Delete alarm"
690 msgstr ""
691
692+#. TRANSLATORS: This is the page title. Please keep the translation length to 3 words if possible
693+#: ../app/alarm/SoundPeerPicker.qml:27
694+msgid "Add sound from"
695+msgstr ""
696+
697 #: ../app/clock/ClockPage.qml:225
698 msgid "Retrieving location..."
699 msgstr ""
700
701=== modified file 'tests/unit/tst_alarmSound.qml'
702--- tests/unit/tst_alarmSound.qml 2015-08-12 16:57:29 +0000
703+++ tests/unit/tst_alarmSound.qml 2015-08-21 16:08:35 +0000
704@@ -35,7 +35,7 @@
705 }
706
707 FolderListModel {
708- id: _soundModel
709+ id: _defaultSoundModel
710
711 showDirs: false
712 nameFilters: [ "*.ogg", "*.mp3" ]
713@@ -45,7 +45,7 @@
714 AlarmSound {
715 id: alarmSoundPage
716 alarm: _alarm
717- soundModel: _soundModel
718+ defaultSoundModel: _defaultSoundModel
719 alarmSound: { "subText": "Bliss" }
720 }
721
722
723=== modified file 'ubuntu-clock-app.json'
724--- ubuntu-clock-app.json 2015-08-13 18:13:33 +0000
725+++ ubuntu-clock-app.json 2015-08-21 16:08:35 +0000
726@@ -4,6 +4,7 @@
727 "calendar",
728 "networking",
729 "location",
730+ "content_exchange",
731 "keep-display-on"
732 ],
733 "policy_version": 1.3

Subscribers

People subscribed via source and target branches