diff --git a/data/qml/SpinnerTest.qml b/data/qml/SpinnerTest.qml
index 217b4dbcf..aa11c4031 100644
--- a/data/qml/SpinnerTest.qml
+++ b/data/qml/SpinnerTest.qml
@@ -11,6 +11,7 @@ BusyIndicator {
anchors.horizontalCenterOffset: 200
height: 200
width: 200
+ count: 11
}
Image {
diff --git a/data/qml/StationView.qml b/data/qml/StationView.qml
index 7bb79e1b4..3448c3adb 100644
--- a/data/qml/StationView.qml
+++ b/data/qml/StationView.qml
@@ -19,23 +19,42 @@ Rectangle {
width: parent.width
icon: "../images/station.svg"
title: mainView.title
- subtitle: generator.summary
+ subtitle: ""//generator.summary
showSearchField: false
showBackButton: stationListView.currentIndex > 0
- showNextButton: stationListView.currentIndex == 2
+ showNextButton: !mainView.configured && stationListView.currentIndex == 2
nextButtonText: "Save"
+ backButtonText: mainView.configured ? "Configure" : "Back"
z: 1 //cover albumcovers that may leave their area
- onBackPressed: stationListView.decrementCurrentIndex()
- onNextPressed: stationListView.incrementCurrentIndex()
+ onBackPressed: {
+ if(mainView.configured) {
+ return;
+ }
+
+ inputBubble.opacity = 0
+ stationListView.decrementCurrentIndex()
+ if(stationListView.currentIndex == 1) {
+ subtitle = modeModel.get(stationCreator.modeIndex).headerSubtitle + "..."
+ }
+ if(stationListView.currentIndex == 0) {
+ subtitle = ""
+ }
+ }
+ // In our case the next button is the save button
+ onNextPressed: {
+ inputBubble.opacity = 1
+ saveNameInput.forceActiveFocus();
+ }
}
+
ListModel {
id: modeModel
- ListElement { label: "By Artist"; image: "../../images/station-artist.svg"; creatorContent: "stations/CreateByArtist.qml" }
- ListElement { label: "By Genre"; image: "../../images/station-genre.svg"; creatorContent: "stations/CreateByGenre.qml" }
- ListElement { label: "By Year"; image: "../../images/station-year.svg"; creatorContent: "year" }
+ ListElement { label: "By Artist"; image: "../../images/station-artist.svg"; creatorContent: "stations/CreateByArtist.qml"; headerSubtitle: "by" }
+ ListElement { label: "By Genre"; image: "../../images/station-genre.svg"; creatorContent: "stations/CreateByGenre.qml"; headerSubtitle: "like" }
+ ListElement { label: "By Year"; image: "../../images/station-year.svg"; creatorContent: "stations/CreateByYear.qml"; headerSubtitle: "from" }
}
VisualItemModel {
@@ -47,8 +66,9 @@ Rectangle {
model: modeModel
onItemClicked: {
- stationCreator.content = modeModel.get(index).creatorContent
+ stationCreator.modeIndex = index
stationListView.incrementCurrentIndex()
+ header.subtitle = modeModel.get(index).headerSubtitle + "..."
}
}
@@ -57,84 +77,35 @@ Rectangle {
height: stationListView.height
width: stationListView.width
- onNext: stationListView.incrementCurrentIndex()
+ property int modeIndex
+
+ content: modeModel.get(modeIndex).creatorContent
+
+ onNext: {
+ stationListView.incrementCurrentIndex()
+ header.subtitle = modeModel.get(modeIndex).headerSubtitle + " " + text
+ }
}
- Item {
+ StationItem {
id: stationItem
height: stationListView.height
width: stationListView.width
-
- CoverFlip {
- id: coverView
- anchors.right: parent.right
- anchors.top: parent.top
- height: parent.height
- width: parent.width
- interactive: false
-
- backgroundColor: scene.color
-
- model: dynamicModel
- currentIndex: currentlyPlayedIndex
-
- onItemPlayPauseClicked: {
- mainView.playItem(index)
- }
-
- onItemClicked: {
- mainView.playItem(index)
- }
-
- states: [
- State {
- name: "empty"; when: mainView.loading
- PropertyChanges {
- target: coverView
- anchors.rightMargin: -coverView.width
- anchors.topMargin: - coverView.height
- scale: 0
- }
- }
- ]
- transitions: [
- Transition {
- from: "empty"
- to: "*"
- NumberAnimation {
- properties: "anchors.topMargin,anchors.rightMargin,scale"
- duration: 1000
- easing.type: Easing.OutQuad
- }
- }
-
- ]
-// Behavior on anchors.topMargin {
-// NumberAnimation { duration: 500 }
-// }
-// Behavior on anchors.rightMargin {
-// NumberAnimation { duration: 500 }
-// }
-// Behavior on scale {
-// NumberAnimation { duration: 500 }
-// }
-
- }
- BusyIndicator {
- id: busyIndicator
- anchors.centerIn: parent
- height: defaultFontHeight * 4
- width: height
-
- opacity: mainView.loading ? 1 : 0
- running: mainView.loading
- }
-
}
-
}
+ VisualItemModel {
+ id: configuredStationVisualModel
+
+
+ StationItem {
+ id: cfgstationItem
+ height: stationListView.height
+ width: stationListView.width
+ }
+ }
+
ListView {
id: stationListView
anchors {
@@ -147,7 +118,7 @@ Rectangle {
contentHeight: height
contentWidth: width
orientation: ListView.Horizontal
- model: stationVisualModel
+ //model: mainView.configured ? configuredStationVisualModel : stationVisualModel
interactive: false
highlightMoveDuration: 300
@@ -157,6 +128,62 @@ Rectangle {
onWidthChanged: {
contentWidth = scene.width
}
+
+ Component.onCompleted: {
+ model = mainView.configured ? configuredStationVisualModel : stationVisualModel
+ }
+ onModelChanged: print("ccccccccccccc", mainView.configured)
}
+ Rectangle {
+ id: inputBubble
+ color: "black"
+ border.width: 2
+ border.color: "white"
+ height: defaultFontHeight * 3
+ width: height * 6
+ radius: defaultFontHeight / 2
+ anchors.top: header.bottom
+ anchors.right: parent.right
+ anchors.rightMargin: defaultFontHeight / 2
+ anchors.topMargin: -defaultFontHeight / 2
+ z: 2
+ opacity: 0
+ Behavior on opacity {
+ NumberAnimation { duration: 200 }
+ }
+
+ Row {
+ anchors.centerIn: parent
+ width: parent.width - defaultFontHeight
+ spacing: defaultFontHeight / 2
+
+ function saveStation(name) {
+ mainView.title = name
+ inputBubble.opacity = 0
+ header.showNextButton = false
+ header.backButtonText = "Configure"
+ }
+
+ Text {
+ id: nameText
+ color: "white"
+ text: "Name:"
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ InputField {
+ id: saveNameInput
+ width: parent.width - nameText.width - saveOkButton.width - parent.spacing * 2
+ placeholderText: "Station"
+ onAccepted: parent.saveStation(text);
+ }
+ PushButton {
+ id: saveOkButton
+ text: "OK"
+ onClicked: parent.saveStation(saveNameInput.text)
+ }
+ }
+
+ }
+
}
diff --git a/data/qml/stations/CreateByArtist.qml b/data/qml/stations/CreateByArtist.qml
index f3f2f4ceb..359b353f7 100644
--- a/data/qml/stations/CreateByArtist.qml
+++ b/data/qml/stations/CreateByArtist.qml
@@ -6,11 +6,11 @@ Item {
id: root
anchors.fill: parent
- signal done()
+ signal done(string text)
function createStation(artist) {
mainView.startStationFromArtist(artist)
- root.done()
+ root.done(artist)
}
Column {
diff --git a/data/qml/stations/CreateByGenre.qml b/data/qml/stations/CreateByGenre.qml
index 9d2fb1b9b..1d8964183 100644
--- a/data/qml/stations/CreateByGenre.qml
+++ b/data/qml/stations/CreateByGenre.qml
@@ -6,11 +6,11 @@ Item {
id: root
anchors.fill: parent
- signal done()
+ signal done(string text)
function createStation(genre) {
mainView.startStationFromGenre(genre)
- root.done()
+ root.done(genre)
}
ListModel {
diff --git a/data/qml/stations/CreateByYear.qml b/data/qml/stations/CreateByYear.qml
new file mode 100644
index 000000000..5e1461668
--- /dev/null
+++ b/data/qml/stations/CreateByYear.qml
@@ -0,0 +1,79 @@
+import QtQuick 1.1
+import tomahawk 1.0
+import "../tomahawkimports"
+
+Item {
+ id: root
+ anchors.fill: parent
+
+ signal done(string text)
+
+ function createStation(artist) {
+ mainView.startStationFromArtist(artist)
+ root.done(artist)
+ }
+
+ Column {
+ id: upperColumn
+ anchors.horizontalCenter: parent.horizontalCenter
+ height: parent.height
+ width: defaultFontHeight * 30
+ anchors.bottomMargin: defaultFontHeight
+ spacing: defaultFontHeight
+
+ HeaderLabel {
+ id: headerText
+ text: "Create station by year..."
+ }
+
+ Row {
+ height: artistInputField.height
+ width: parent.width
+ spacing: defaultFontHeight * 0.5
+
+ InputField {
+ id: artistInputField
+ width: parent.width - createFromInputButton.width - parent.spacing
+
+ onAccepted: createStation(text)
+ }
+
+ PushButton {
+ id: createFromInputButton
+ text: "Go!"
+ enabled: artistInputField.text.length > 2
+ onClicked: createStation(artistInputField.text)
+ }
+ }
+
+// Item {
+// height: parent.height - headerText.height - artistInputField.height - parent.spacing * 3
+// width: parent.width
+// ArtistView {
+// id: artistView
+// height: parent.height
+// width: parent.width
+// model: artistChartsModel
+// clip: true
+// delegateHeight: defaultFontHeight * 6
+
+// onItemClicked: {
+// createStation(artistChartsModel.itemFromIndex(index).artistName);
+// }
+// }
+// ScrollBar {
+// listView: artistView
+// }
+// }
+
+ DoubleSlider {
+ width: parent.width
+ height: defaultFontHeight * 2
+ min: 1960
+ max: new Date().getFullYear()
+ lowerSliderPos: 1990
+ upperSliderPos: 2010
+ minMaxLabelsVisible: false
+ }
+ }
+}
diff --git a/data/qml/stations/StationCreatorPage2.qml b/data/qml/stations/StationCreatorPage2.qml
index 34f4b65cd..295069aa6 100644
--- a/data/qml/stations/StationCreatorPage2.qml
+++ b/data/qml/stations/StationCreatorPage2.qml
@@ -8,7 +8,7 @@ Item {
property int margins: defaultFontHeight * 2
property alias content: contentLoader.source
- signal next()
+ signal next(string text)
Loader {
id: contentLoader
@@ -19,7 +19,7 @@ Item {
Connections {
target: contentLoader.item
- onDone: root.next()
+ onDone: root.next(text)
}
}
diff --git a/data/qml/stations/StationItem.qml b/data/qml/stations/StationItem.qml
new file mode 100644
index 000000000..9d7804a0a
--- /dev/null
+++ b/data/qml/stations/StationItem.qml
@@ -0,0 +1,73 @@
+import QtQuick 1.1
+import tomahawk 1.0
+import "../tomahawkimports"
+
+Item {
+ id: stationItem
+
+ CoverFlip {
+ id: coverView
+ anchors.right: parent.right
+ anchors.top: parent.top
+ height: parent.height
+ width: parent.width
+ interactive: false
+
+ backgroundColor: scene.color
+
+ model: dynamicModel
+ currentIndex: currentlyPlayedIndex
+
+ onItemPlayPauseClicked: {
+ mainView.playItem(index)
+ }
+
+ onItemClicked: {
+ mainView.playItem(index)
+ }
+
+ states: [
+ State {
+ name: "empty"; when: mainView.loading
+ PropertyChanges {
+ target: coverView
+ anchors.rightMargin: -coverView.width
+ anchors.topMargin: - coverView.height
+ scale: 0
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ from: "empty"
+ to: "*"
+ NumberAnimation {
+ properties: "anchors.topMargin,anchors.rightMargin,scale"
+ duration: 1000
+ easing.type: Easing.OutQuad
+ }
+ }
+
+ ]
+// Behavior on anchors.topMargin {
+// NumberAnimation { duration: 500 }
+// }
+// Behavior on anchors.rightMargin {
+// NumberAnimation { duration: 500 }
+// }
+// Behavior on scale {
+// NumberAnimation { duration: 500 }
+// }
+
+ }
+ BusyIndicator {
+ id: busyIndicator
+ anchors.centerIn: parent
+ height: defaultFontHeight * 4
+ width: height
+
+ opacity: mainView.loading ? 1 : 0
+ running: mainView.loading
+ }
+
+}
diff --git a/data/qml/tomahawkimports/CoverFlip.qml b/data/qml/tomahawkimports/CoverFlip.qml
index 58e85824c..742dcce71 100644
--- a/data/qml/tomahawkimports/CoverFlip.qml
+++ b/data/qml/tomahawkimports/CoverFlip.qml
@@ -49,8 +49,6 @@ PathView {
right: parent.right
}
- backgroundColor: coverView.backgroundColor
-
showLabels: true
showMirror: true
artistName: model.artistName
diff --git a/data/qml/tomahawkimports/CoverImage.qml b/data/qml/tomahawkimports/CoverImage.qml
index 518137aac..e3f2c1d30 100644
--- a/data/qml/tomahawkimports/CoverImage.qml
+++ b/data/qml/tomahawkimports/CoverImage.qml
@@ -25,9 +25,6 @@ Item {
// The border width for the cover image
property int borderWidth: 2
- // needed to adjust the shadow
- property color backgroundColor: "black"
-
// sets the brightness for the item and its mirror (1: brightest, 0: darkest)
property double itemBrightness: 1
property double mirrorBrightness: .5
@@ -55,7 +52,7 @@ Item {
Rectangle {
id: itemShadow
- color: backgroundColor
+ color: "black"
anchors.fill: parent
//opacity: 1 - itemBrightness
diff --git a/data/qml/tomahawkimports/DoubleSlider.qml b/data/qml/tomahawkimports/DoubleSlider.qml
index b1dc522cc..08061b96e 100644
--- a/data/qml/tomahawkimports/DoubleSlider.qml
+++ b/data/qml/tomahawkimports/DoubleSlider.qml
@@ -2,8 +2,6 @@ import QtQuick 1.1
Item {
id: root
- width: 500
- height: 10
property int min: 0
property int max: 100
@@ -16,71 +14,144 @@ Item {
/** Should the floating label indicating the current position be shown? */
property bool showFloatingLabel: true
+ property bool minMaxLabelsVisible: true
property int lowerSliderPos: 25
property int upperSliderPos: 75
+ onUpperSliderPosChanged: print("fooooooooo", upperSliderPos)
+
signal valueChanged()
+ QtObject {
+ id: priv
+
+ property int steps: root.max - root.min + 1
+
+ property int sliderHeight: root.height
+ property int sliderWidth: root.height / 2
+ }
+
Row {
anchors.fill: parent
+ anchors.topMargin: defaultFontHeight * 1.2
+ anchors.bottomMargin: defaultFontHeight * 1.2
spacing: 10
Text {
id: minText
text: root.minLabel.length > 0 ? root.minLabel : min
color: "white"
+ visible: root.minMaxLabelsVisible
}
Item {
id: sliderRect
height: root.height
- width: parent.width - minText.width - maxText.width - parent.spacing * 2
+ property int maxWidth: parent.width - (minText.visible ? minText.width : 0) - (maxText.visible ? maxText.width : 0) - parent.spacing * 2
+ width: maxWidth - (maxWidth % priv.steps)
+ anchors.horizontalCenter: parent.horizontalCenter
function sliderPosToValue( sliderPos ) {
- var percent = sliderPos * 100 / (sliderRect.width - lowerSlider.width);
- return Math.floor(percent * (root.max - root.min) / 100) + root.min
+ var percent = sliderPos * 100 / (sliderRect.width - priv.sliderWidth/2);
+ return Math.floor(percent * (priv.steps-1) / 100) + root.min
}
function valueToSloderPos( value ) {
- var percent = (value - root.min) * 100 / (root.max - root.min)
- return percent * (sliderRect.width - lowerSlider.width) / 100
+ var percent = (value - root.min) * 100 / (priv.steps-1)
+ return percent * (sliderRect.width - priv.sliderWidth/2) / 100
}
Rectangle {
id: sliderBase
- height: root.height / 5
- width: parent.width
+ height: root.height / 1.5
+ width: parent.width + defaultFontHeight * 1.5
color: "white"
radius: height / 2
anchors.centerIn: parent
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#ffffffff" }
+ GradientStop { position: 1.0; color: "#aaffffff" }
+ }
+
+ Rectangle {
+ anchors.fill: sliderBase
+ anchors.leftMargin: lowerSlider.x + priv.sliderWidth
+ anchors.rightMargin: sliderBase.width - upperSlider.x - priv.sliderWidth
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#aa962c26" }
+ GradientStop { position: 1.0; color: "#962c26" }
+ }
+ }
+
+ Row {
+ id: stepRow
+ anchors.fill: parent
+ anchors.leftMargin: defaultFontHeight - lineWidth/2
+ anchors.rightMargin: defaultFontHeight - lineWidth/2
+ property int stepCount: root.max - root.min + 1
+ property int lineHeight: height
+ property int lineWidth: lineHeight / 15
+ spacing: (width - (stepCount * lineWidth)) / stepCount
+
+ Repeater {
+ model: stepRow.stepCount
+
+ Rectangle {
+ id: marker
+ height: stepRow.lineHeight * (isHighlight ? 1.2 : 1)
+ width: stepRow.lineWidth
+ color: "black"
+
+ property bool isHighlight: index % 10 === 0
+
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: marker.isHighlight ? "white" : "black" }
+ GradientStop { position: 1.0; color: marker.isHighlight ? "#aaffffff" : "black" }
+ }
+
+ Text {
+ text: root.min + index
+ visible: marker.isHighlight
+ anchors.horizontalCenter: marker.horizontalCenter
+ anchors.top: marker.bottom
+ anchors.topMargin: defaultFontHeight / 2
+ color: "white"
+ }
+
+ }
+
+ }
+ }
+
}
+
Rectangle {
id: lowerSlider
- height: root.height
- width: height
+ height: priv.sliderHeight
+ width: priv.sliderWidth
anchors.top: root.top
- radius: height/2
+ radius: height/4
border.color: "black"
border.width: 2
- x: sliderRect.valueToSloderPos(root.lowerSliderPos)
+ x: sliderRect.valueToSloderPos(root.lowerSliderPos) - priv.sliderWidth/2
Rectangle {
id: lowerFloatingRect
color: "white"
anchors.bottom: lowerSlider.top
anchors.bottomMargin: 10
- visible: root.showFloatingLabel && lowerSliderMouseArea.pressed
+// visible: root.showFloatingLabel && lowerSliderMouseArea.pressed
width: lowerFloatingText.width * 1.2
height: lowerFloatingText.height + height * 1.2
- x: -(width - lowerSlider.width) / 2
- radius: height / 4
+ x: -(width - priv.sliderWidth) / 2
+ radius: height / 8
Text {
id: lowerFloatingText
anchors.centerIn: parent
- text: sliderRect.sliderPosToValue(lowerSlider.x)
+ text: sliderRect.sliderPosToValue(lowerSlider.x + priv.sliderWidth/2)
}
}
}
@@ -89,10 +160,10 @@ Item {
anchors.fill: lowerSlider
drag.target: lowerSlider
drag.axis: "XAxis"
- drag.minimumX: 0
- drag.maximumX: upperSlider.x - lowerSlider.width
+ drag.minimumX: -priv.sliderWidth / 2
+ drag.maximumX: upperSlider.x - priv.sliderWidth
onReleased: {
- root.lowerSliderPos = sliderRect.sliderPosToValue( lowerSlider.x );
+ root.lowerSliderPos = sliderRect.sliderPosToValue( lowerSlider.x + priv.sliderWidth/2 );
root.valueChanged();
}
}
@@ -100,9 +171,9 @@ Item {
Rectangle {
id: upperSlider
height: root.height
- width: height
+ width: height / 2
anchors.top: root.top
- radius: height/2
+ radius: height / 4
border.color: "black"
border.width: 2
x: sliderRect.valueToSloderPos(root.upperSliderPos)
@@ -111,16 +182,16 @@ Item {
color: "white"
anchors.bottom: upperSlider.top
anchors.bottomMargin: 10
- visible: root.showFloatingLabel && upperSliderMouseArea.pressed
+// visible: root.showFloatingLabel && upperSliderMouseArea.pressed
width: upperFloatingText.width * 1.2
height: upperFloatingText.height + height * 1.2
radius: height / 4
- x: -(width - upperSlider.width) / 2
+ x: -(width - priv.sliderWidth) / 2
Text {
id: upperFloatingText
anchors.centerIn: parent
- text: sliderRect.sliderPosToValue(upperSlider.x)
+ text: sliderRect.sliderPosToValue(upperSlider.x + priv.sliderWidth/2)
}
}
@@ -131,14 +202,16 @@ Item {
onClicked: print("button pressed")
drag.target: upperSlider
drag.axis: "XAxis"
- drag.minimumX: lowerSlider.x + lowerSlider.width
- drag.maximumX: parent.width - upperSlider.width
+ drag.minimumX: lowerSlider.x + priv.sliderWidth
+ drag.maximumX: parent.width - priv.sliderWidth
onReleased: {
- root.upperSliderPos = sliderRect.sliderPosToValue( upperSlider.x );
+ root.upperSliderPos = sliderRect.sliderPosToValue( upperSlider.x + priv.sliderWidth/2 );
root.valueChanged();
}
}
+
+
}
@@ -146,6 +219,7 @@ Item {
id: maxText
text: root.maxLabel.length > 0 ? root.maxLabel : max
color: "white"
+ visible: root.minMaxLabelsVisible
}
}
}
diff --git a/data/qml/tomahawkimports/InputField.qml b/data/qml/tomahawkimports/InputField.qml
index 9f052124d..c15d03077 100644
--- a/data/qml/tomahawkimports/InputField.qml
+++ b/data/qml/tomahawkimports/InputField.qml
@@ -17,6 +17,12 @@ Rectangle {
property int spacing: defaultFontHeight * 0.2
signal accepted( string text )
+ onFocusChanged: {
+ if(focus) {
+ textInput.forceActiveFocus();
+ }
+ }
+
Image {
id: searchIcon
anchors {
diff --git a/data/qml/tomahawkimports/TagCloud.qml b/data/qml/tomahawkimports/TagCloud.qml
index ba3de03aa..ccdc82cd3 100644
--- a/data/qml/tomahawkimports/TagCloud.qml
+++ b/data/qml/tomahawkimports/TagCloud.qml
@@ -16,7 +16,7 @@ Item {
Flow {
anchors.centerIn: parent
width: parent.width
- spacing: 3
+ spacing: defaultFontSize
Repeater {
id: cloudRepeater
@@ -26,7 +26,7 @@ Item {
id: cloudItem
width: delegateText.width * 1.1
height: delegateText.height
- property double itemScale: Math.random() + .3
+ property double itemScale: tagCloud.randomNumber(0.5, 1.2)
scale: itemScale
Text {
id: delegateText
@@ -35,7 +35,7 @@ Item {
text: modelData
font.pointSize: 16
anchors.verticalCenter: parent.verticalCenter
- anchors.verticalCenterOffset: tagCloud.randomNumber(0, 15)
+ //anchors.verticalCenterOffset: tagCloud.randomNumber(0, 15)
states: [
State {
diff --git a/resources.qrc b/resources.qrc
index 5c0708890..100c6a0f7 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -103,9 +103,11 @@
data/qml/tomahawkimports/CoverFlip.qml
data/qml/tomahawkimports/BusyIndicator.qml
data/qml/StationView.qml
+ data/qml/stations/StationItem.qml
data/qml/stations/StationCreatorPage1.qml
data/qml/stations/StationCreatorPage2.qml
data/qml/stations/CreateByArtist.qml
+ data/qml/stations/CreateByYear.qml
data/qml/stations/StationConfig.qml
data/qml/QmlGridView.qml
data/qml/stations/CreateByGenre.qml
diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.cpp
index c4b149df1..0b5c1edd4 100644
--- a/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.cpp
+++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.cpp
@@ -82,7 +82,22 @@ DynamicQmlWidget::playlistInterface() const
QString
DynamicQmlWidget::title() const
{
- return m_model->title();
+ if ( !m_playlist->title().isEmpty() ) {
+ return m_playlist->title();
+ }
+ return "Listen to radio...";
+}
+
+
+void
+DynamicQmlWidget::setTitle(const QString &title)
+{
+ m_model->setTitle( title );
+ m_playlist->setTitle( title );
+ m_model->playlist()->setTitle( title );
+ m_playlist->createNewRevision( uuid(), m_playlist->currentrevision(), m_playlist->type(), m_playlist->generator()->controls() );
+ m_playlist->reportCreated( m_playlist );
+ emit titleChanged();
}
diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.h b/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.h
index 382bf314a..c5a0ceac7 100644
--- a/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.h
+++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicQmlWidget.h
@@ -37,7 +37,7 @@ class DynamicQmlWidget : public DeclarativeView, public Tomahawk::ViewPage
{
Q_OBJECT
- Q_PROPERTY(QString title READ title NOTIFY titleChanged)
+ Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
Q_PROPERTY(bool configured READ configured NOTIFY configuredChanged)
@@ -49,6 +49,7 @@ public:
virtual Tomahawk::playlistinterface_ptr playlistInterface() const;
virtual QString title() const;
+ virtual void setTitle(const QString &title);
virtual QString description() const;
virtual QString iconSource() const;