forked from nesnomis/harbour-allradio2
Initial commit (new git name)
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
Page {
|
||||
Flickable {
|
||||
id: flick
|
||||
//width:parent.width
|
||||
height: parent.height - Theme.paddingLarge * 3
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: Theme.paddingLarge * 3
|
||||
anchors.leftMargin: Theme.paddingMedium
|
||||
anchors.rightMargin: Theme.paddingMedium
|
||||
contentHeight: column1.height
|
||||
|
||||
Column{
|
||||
id: column1
|
||||
width: parent.width
|
||||
spacing: Theme.paddingLarge
|
||||
Label {
|
||||
font.pixelSize: Theme.fontSizeExtraLarge
|
||||
font.bold: true
|
||||
text: "AllRadio2 v"+ _version
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
}
|
||||
|
||||
Text {
|
||||
focus: false
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.primaryColor
|
||||
linkColor: Theme.highlightColor
|
||||
//wrapMode: TextEdit.WordWrap
|
||||
//verticalAlignment: Text.Center
|
||||
horizontalAlignment: Text.Center
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
// text: qsTr("License: <a href='file:///gpl-2.0-standalone.html'>GPLv2</a>")
|
||||
text: qsTr("License: GPLv2")
|
||||
}
|
||||
|
||||
Image{
|
||||
source: "../images/community.png"
|
||||
height: Theme.itemSizeHuge
|
||||
width: height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
Text {
|
||||
focus: false
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
width: parent.width
|
||||
color: Theme.primaryColor
|
||||
linkColor: Theme.highlightColor
|
||||
wrapMode: TextEdit.WordWrap
|
||||
verticalAlignment: Text.AlignLeft
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
text: "<p>This is version 2 of my old app AllRadio. It fixes the API changes made a couple of years ago in <a href='https://api.radio-browser.info/'>Radio Browser</a>.</p>
|
||||
<p>What i have done (for now):<p>
|
||||
<ul>
|
||||
<li>Cleaned up the code.</li>
|
||||
<li>Included some old requests.</li>
|
||||
<li>Added a simple tv station video player.</li></ul>
|
||||
|
||||
<p>It is propably buggy and lacking of some functions, but i will try to update and fix it when i find the time for it.</p>
|
||||
<p>For now, the source code is hosted on this <a href='http://gitea.nesnomis.nu/nesnomis/harbour-allradio'>git server</a>."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,447 @@
|
||||
import QtQuick 2.2
|
||||
import Sailfish.Silica 1.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
import "../items"
|
||||
import "../models"
|
||||
import "../delegates"
|
||||
import "../helpers/db.js" as Favorites
|
||||
import "../helpers/jsFunctions.js" as JS
|
||||
|
||||
Page {
|
||||
|
||||
id: page
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: mediaPlayerPanel.visibleSize
|
||||
|
||||
property int _appStart: Favorites.getSetting("appStart",0)
|
||||
property bool _loading: radioBrowser.loading
|
||||
property bool stationOk: radioPlayer.stationOk
|
||||
property bool online: radioBrowser.online
|
||||
property GetCountryStations getTrending1: GetCountryStations {id: getTrending1}
|
||||
property GetCountryStations getTrending2: GetCountryStations {id: getTrending2}
|
||||
property GetCountryStations getTrendingWorld: GetCountryStations {id: getTrendingWorld}
|
||||
property GetCountryStations getTags1: GetCountryStations {id: getTags1}
|
||||
property GetCountryStations getTags2: GetCountryStations {id: getTags2}
|
||||
property GetCountryStations getTags3: GetCountryStations {id: getTags3}
|
||||
property ListModel playedCountries: ListModel {id: playedCountries}
|
||||
property ListModel playedTags: ListModel {id: playedTags}
|
||||
property ListModel favorites: ListModel {id: favorites}
|
||||
|
||||
onOnlineChanged: if (online) reloadDbData()
|
||||
onStationOkChanged: if (stationOk) reloadDbData()
|
||||
on_LoadingChanged: {
|
||||
if (!_loading) {
|
||||
appAutoPlay()
|
||||
//console.log(" *** AUTOPLAY")
|
||||
} //else console.log(" *** INTE AUTOPLAY")
|
||||
}
|
||||
|
||||
Splash {
|
||||
id: splashItem
|
||||
visible: radioBrowser.loading ? true : false
|
||||
}
|
||||
|
||||
SilicaFlickable {
|
||||
anchors.fill: parent
|
||||
contentHeight: mainColumn.height
|
||||
clip: mediaPlayerPanel.expanded
|
||||
visible: !splashItem.visible
|
||||
|
||||
onVisibleChanged: if (visible) reloadDbData()
|
||||
|
||||
PullDownMenu {
|
||||
MenuItem {
|
||||
text: qsTr("About")
|
||||
onClicked: pageStack.push("AboutPage.qml")
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Settings")
|
||||
onClicked: pageStack.push("SettingsPage.qml")
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Sleep timer")
|
||||
onClicked: {
|
||||
pageStack.push("SleepTimerPage.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: mainColumn
|
||||
width: parent.width
|
||||
spacing: Theme.paddingMedium
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Theme.itemSizeHuge
|
||||
Label {
|
||||
id: hlabel
|
||||
font.pixelSize: Theme.fontSizeExtraLarge
|
||||
text: JS.getGreeting()
|
||||
color: Theme.highlightColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
}
|
||||
|
||||
Image {
|
||||
id: logo
|
||||
anchors.verticalCenter: hlabel.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
height: Theme.itemSizeMedium
|
||||
width: height
|
||||
smooth: true
|
||||
source: "../images/community.png"
|
||||
}
|
||||
|
||||
ColorOverlay {
|
||||
anchors.fill: logo
|
||||
source: logo
|
||||
color: Theme.highlightColor
|
||||
}
|
||||
}
|
||||
|
||||
BackgroundItem {
|
||||
width: parent.width
|
||||
height: Theme.itemSizeMedium
|
||||
|
||||
ButtonRect {fill: false}
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.paddingMedium
|
||||
|
||||
Image {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: "image://theme/icon-m-search"
|
||||
}
|
||||
|
||||
Label {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: qsTr("Search")
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: "image://theme/icon-m-right"
|
||||
}
|
||||
|
||||
onClicked: pageStack.push("SearchStationsPage.qml",{searchby:"name"})}
|
||||
|
||||
// Most played countries
|
||||
Column {
|
||||
//visible: playedCountries.count > 0
|
||||
width: parent.width
|
||||
|
||||
Item {height: Theme.paddingLarge;width: parent.width}
|
||||
|
||||
HeaderButton {
|
||||
headerText: qsTr("Countries")
|
||||
onClicked: pageStack.push("CountryListPage.qml")
|
||||
}
|
||||
|
||||
Item {height: Theme.paddingMedium;width: parent.width}
|
||||
|
||||
SilicaGridView {
|
||||
clip: true
|
||||
visible: playedCountries.count > 0
|
||||
width: parent.width
|
||||
height: playedCountries.count > 0 ? Theme.itemSizeExtraSmall * Math.round(playedCountries.count / 2) : 0
|
||||
cellWidth: parent.width / 2
|
||||
cellHeight: Theme.itemSizeExtraSmall
|
||||
model: playedCountries
|
||||
delegate: FavoriteCountryList {onClicked: pageStack.push("CountryStationsPage.qml",{searchby:"name",_countrycode: alpha_2})}
|
||||
}
|
||||
}
|
||||
|
||||
// Most played favorites
|
||||
Item {height: Theme.paddingLarge;width: parent.width;visible: favorites.count > 0}
|
||||
|
||||
HeaderButton {
|
||||
visible: favorites.count > 0
|
||||
headerText: qsTr("My Favorites")
|
||||
onClicked: pageStack.push("FavoritesPage.qml")
|
||||
}
|
||||
|
||||
GridView {
|
||||
//clip: true
|
||||
id: favoriteView
|
||||
clip: true
|
||||
height: Theme.itemSizeHuge * 1.35
|
||||
width: page.width
|
||||
cellHeight: height
|
||||
cellWidth: cellHeight * 0.75
|
||||
flow: GridView.TopToBottom
|
||||
snapMode: SlideshowView.NoSnap
|
||||
layoutDirection: Qt.LeftToRight
|
||||
visible: favorites.count > 0
|
||||
|
||||
model: favorites
|
||||
|
||||
delegate: SmallStationsDelegate {
|
||||
flagVisible: true
|
||||
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._cc = model.countrycode// THIS IS THE FUNCTION DESTROYING AARCH64?!?
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec
|
||||
radioPlayer._bitrate = model.bitrate
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
radioPlayer.getStationFavorite(model.stationuuid)
|
||||
radioPlayer.playlistIndex = index
|
||||
} else radioPlayer.resumeStream()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recently played
|
||||
Item {height: Theme.paddingLarge;width: parent.width;visible: radioPlayer.playHistory.count > 0}
|
||||
|
||||
HeaderButton {
|
||||
visible: radioPlayer.playHistory.count > 0
|
||||
headerText: qsTr("Play history")
|
||||
onClicked: pageStack.push("HistoryPage.qml")
|
||||
}
|
||||
|
||||
GridView {
|
||||
visible: radioPlayer.playHistory.count > 0
|
||||
clip: true
|
||||
height: playedTags.count > 0 ? Theme.itemSizeHuge * 1.35 : 0
|
||||
width: page.width
|
||||
cellHeight: height
|
||||
cellWidth: cellHeight * 0.75
|
||||
flow: GridView.TopToBottom
|
||||
snapMode: SlideshowView.NoSnap
|
||||
layoutDirection: Qt.LeftToRight
|
||||
|
||||
model: radioPlayer.playHistory
|
||||
|
||||
delegate: SmallStationsDelegate {
|
||||
flagVisible: true
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._cc = model.countrycode// THIS IS THE FUNCTION DESTROYING AARCH64?!?
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec
|
||||
radioPlayer._bitrate = model.bitrate
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
radioPlayer.getStationFavorite(model.stationuuid)
|
||||
} else radioPlayer.resumeStream()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Most played tags
|
||||
Item {height: Theme.paddingLarge;width: parent.width;visible: radioPlayer.playHistory.count > 0}
|
||||
|
||||
HeaderButton {
|
||||
visible: radioPlayer.playHistory.count > 0
|
||||
headerText: qsTr("My most played Tags")
|
||||
onClicked: pageStack.push("TagListPage.qml",{})
|
||||
}
|
||||
|
||||
GridView {
|
||||
visible: radioPlayer.playHistory.count > 0
|
||||
clip: true
|
||||
height: playedTags.count > 0 ? Theme.itemSizeHuge * 1.35 : 0
|
||||
width: page.width
|
||||
cellHeight: height
|
||||
cellWidth: cellHeight * 0.75
|
||||
flow: GridView.TopToBottom
|
||||
snapMode: SlideshowView.NoSnap
|
||||
layoutDirection: Qt.LeftToRight
|
||||
model: playedTags
|
||||
delegate: SmallTagsDelegate {
|
||||
onClicked: pageStack.push("CountryStationsPage.qml",{filterby: "tag",searchby: "clicktrend",stext: tag,comboIndex: 1 })
|
||||
}
|
||||
}
|
||||
|
||||
Item {height: Theme.paddingLarge;width: parent.width;visible: radioBrowser.getCountryName(_country) || playedCountries.count > 0 ? true : false}
|
||||
|
||||
HeaderButton {
|
||||
visible: radioBrowser.getCountryName(_country) || playedCountries.count > 0 ? true : false
|
||||
headerText: playedCountries.count > 0 ? qsTr("Trending in")+ " " + radioBrowser.getCountryName(playedCountries.get(0).alpha_2) : qsTr("Trending in") + " " + radioBrowser.getCountryName(_country)
|
||||
onClicked: pageStack.push("CountryStationsPage.qml",{searchby:"clicktrend",_countrycode: playedCountries.count > 0 ? playedCountries.get(0).alpha_2 : _country})
|
||||
}
|
||||
|
||||
GridView {
|
||||
clip: true
|
||||
height: Theme.itemSizeHuge * 1.35
|
||||
width: page.width
|
||||
cellHeight: height
|
||||
cellWidth: cellHeight * 0.75
|
||||
flow: GridView.TopToBottom
|
||||
snapMode: SlideshowView.NoSnap
|
||||
layoutDirection: Qt.LeftToRight
|
||||
visible: radioBrowser.getCountryName(_country) || playedCountries.count > 0 ? true : false
|
||||
|
||||
model: getTrending1.searchModel
|
||||
|
||||
delegate: SmallStationsDelegate {
|
||||
flagVisible: false
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._cc = model.countrycode// THIS IS THE FUNCTION DESTROYING AARCH64?!?
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec
|
||||
radioPlayer._bitrate = model.bitrate
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
radioPlayer.getStationFavorite(model.stationuuid)
|
||||
} else radioPlayer.resumeStream()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {height: Theme.paddingLarge;width: parent.width;visible: playedCountries.count > 1}
|
||||
|
||||
HeaderButton {
|
||||
visible: playedCountries.count > 1
|
||||
headerText: playedCountries.count > 1 ? qsTr("Trending in")+" " + radioBrowser.getCountryName(playedCountries.get(1).alpha_2) : qsTr("Trending in")+" " + radioBrowser.getCountryName(_country)
|
||||
onClicked: pageStack.push("CountryStationsPage.qml",{searchby:"clicktrend",_countrycode: playedCountries.get(1).alpha_2})
|
||||
}
|
||||
|
||||
GridView {
|
||||
clip: true
|
||||
height: Theme.itemSizeHuge * 1.35
|
||||
width: page.width
|
||||
cellHeight: height
|
||||
cellWidth: cellHeight * 0.75
|
||||
flow: GridView.TopToBottom
|
||||
snapMode: SlideshowView.NoSnap
|
||||
layoutDirection: Qt.LeftToRight
|
||||
visible: playedCountries.count > 1
|
||||
|
||||
model: getTrending2.searchModel
|
||||
|
||||
delegate: SmallStationsDelegate {
|
||||
flagVisible: false
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._cc = model.countrycode// THIS IS THE FUNCTION DESTROYING AARCH64?!?
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec//getCodec(model.codec)
|
||||
radioPlayer._bitrate = model.bitrate //getBitrate(model.bitrate)
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
radioPlayer.getStationFavorite(model.stationuuid)
|
||||
} else radioPlayer.resumeStream()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {height: Theme.paddingLarge;width: parent.width}
|
||||
|
||||
HeaderButton {
|
||||
headerText: qsTr("Trending in the world")
|
||||
onClicked: pageStack.push("CountryStationsPage.qml",{searchby:"clicktrend",_countrycode: ""})
|
||||
}
|
||||
|
||||
GridView {
|
||||
clip: true
|
||||
height: Theme.itemSizeHuge * 1.35
|
||||
width: page.width
|
||||
cellHeight: height
|
||||
cellWidth: cellHeight * 0.75
|
||||
flow: GridView.TopToBottom
|
||||
snapMode: SlideshowView.NoSnap
|
||||
layoutDirection: Qt.LeftToRight
|
||||
model: getTrendingWorld.searchModel
|
||||
delegate: SmallStationsDelegate {
|
||||
flagVisible: true
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._cc = model.countrycode// THIS IS THE FUNCTION DESTROYING AARCH64?!?
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec//getCodec(model.codec)
|
||||
radioPlayer._bitrate = model.bitrate //getBitrate(model.bitrate)
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
radioPlayer.getStationFavorite(model.stationuuid)
|
||||
} else radioPlayer.resumeStream()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function appAutoPlay() {
|
||||
switch (_appStart) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
radioPlayer.loadRecentPlay()
|
||||
radioPlayer.playStream()
|
||||
break;
|
||||
case 2:
|
||||
radioPlayer.loadRandomPlay()
|
||||
radioPlayer.playStream()
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function reloadDbData() {
|
||||
Favorites.getTagsRecentClicked(playedTags,15)
|
||||
Favorites.getFavorites(favorites,"myclickcount",15)
|
||||
Favorites.getCountryRecentClicked(playedCountries,4)
|
||||
getTrending1.countrycode = playedCountries.count > 0 ? playedCountries.get(0).alpha_2 : _country
|
||||
getTrending1.order = "clicktrend"
|
||||
getTrending1.offset = 0
|
||||
getTrending1.limit = 15
|
||||
if (getTrending1.searchModel.count !== 0) getTrending1.clear = true; else getTrending1.getStations()
|
||||
|
||||
if (playedCountries.count > 1) {
|
||||
getTrending2.countrycode = playedCountries.get(1).alpha_2
|
||||
getTrending2.order = "clicktrend"
|
||||
getTrending2.offset = 0
|
||||
getTrending2.limit = 15
|
||||
if (getTrending2.searchModel.count !== 0) getTrending2.clear = true; else getTrending2.getStations()
|
||||
}
|
||||
|
||||
getTrendingWorld.countrycode = ""
|
||||
getTrendingWorld.order = "clicktrend"
|
||||
getTrendingWorld.offset = 0
|
||||
getTrendingWorld.limit = 15
|
||||
if (getTrendingWorld.searchModel.count !== 0) getTrendingWorld.clear=true; else getTrendingWorld.getStations()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
Favorites.init()
|
||||
radioBrowser.getList()
|
||||
reloadDbData()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import "../helpers/db.js" as Favorites
|
||||
import "../delegates"
|
||||
|
||||
Page {
|
||||
property bool sfocus: false
|
||||
property bool pageAcitve
|
||||
|
||||
z:1
|
||||
|
||||
SilicaListView {
|
||||
id: view
|
||||
anchors.fill: parent
|
||||
clip: mediaPlayerPanel.expanded
|
||||
anchors.bottomMargin: mediaPlayerPanel.visibleSize
|
||||
VerticalScrollDecorator {}
|
||||
|
||||
header: Column {
|
||||
width: parent.width
|
||||
|
||||
PageHeader {title: "Community Radio Browser";description: qsTr("Found")+" "+view.count + " " +qsTr("countries")}
|
||||
|
||||
SearchField {
|
||||
id: sfield
|
||||
width: parent.width
|
||||
placeholderText: qsTr("Search")
|
||||
text: ""
|
||||
inputMethodHints: Qt.ImhNoAutoUppercase
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||
EnterKey.onClicked: {focus = false}
|
||||
focus: sfocus
|
||||
onTextChanged: radioBrowser.countriesModel.filter = text
|
||||
onClicked: {view.currentIndex = -1}
|
||||
}
|
||||
}
|
||||
|
||||
model: radioBrowser.countriesModel.countryModel
|
||||
|
||||
delegate: CountryListDelegate {
|
||||
id: countryListDelegate;
|
||||
|
||||
onClicked: {
|
||||
sfocus=false;
|
||||
Favorites.setSetting("lastCountry",alpha_2)
|
||||
pageStack.push("CountryStationsPage.qml",{stationCount: stationcount,_countrycode: alpha_2,searchby:"name"})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import "../models"
|
||||
import "../delegates"
|
||||
|
||||
Page {
|
||||
property string sortedby: ""
|
||||
property string filterby
|
||||
property alias searchby: getCountryStations.order
|
||||
property string searchtext: ""
|
||||
property string _countrycode: ""
|
||||
property int stationCount: 0
|
||||
property alias name: getCountryStations.name
|
||||
property alias tag: getCountryStations.tag
|
||||
property string stext: ""
|
||||
property GetCountryStations getCountryStations: GetCountryStations {id: getCountryStations}
|
||||
property bool sfocus
|
||||
property int comboIndex: 0
|
||||
|
||||
onStatusChanged: if (status !== PageStatus.Active) sfocus=false
|
||||
|
||||
onSearchbyChanged: {
|
||||
switch (searchby){
|
||||
case "name": sortedby = qsTr("Sorted by Name");break;
|
||||
case "votes": sortedby = qsTr("Most likes");break;
|
||||
case "clicktrend": sortedby = qsTr("Trending right now");break;
|
||||
case "clickcount": sortedby = qsTr("Most played");
|
||||
}
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
id: busy
|
||||
visible: running
|
||||
anchors.centerIn: parent
|
||||
size: BusyIndicatorSize.Large
|
||||
running: !getCountryStations.finished && getCountryStations.offset > 0
|
||||
}
|
||||
|
||||
SilicaListView {
|
||||
id: view
|
||||
enabled: !busy.visible
|
||||
opacity: enabled ? 1 : 0.5
|
||||
anchors.fill: parent
|
||||
clip: mediaPlayerPanel.expanded
|
||||
anchors.bottomMargin: sfocus ? 0 : mediaPlayerPanel.visibleSize
|
||||
|
||||
ViewPlaceholder {
|
||||
anchors.centerIn: parent
|
||||
enabled: view.count == 0
|
||||
text: getCountryStations.finished && view.count === 0 ? qsTr("Oh no...") : qsTr("Please wait")
|
||||
hintText: getCountryStations.finished && view.count === 0 ? qsTr("No radio stations!?!") : qsTr("getting radio stations")
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {}
|
||||
|
||||
onAtYEndChanged: {
|
||||
if (atYEnd && view.count >= getCountryStations.limit) {
|
||||
if (getCountryStations.offset + getCountryStations.limit < stationCount) {
|
||||
getCountryStations.offset = getCountryStations.offset + getCountryStations.limit + 1
|
||||
getCountryStations.getStations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header: Column {
|
||||
width: parent.width
|
||||
|
||||
PageHeader {
|
||||
id: pheader
|
||||
|
||||
Column {
|
||||
id: headerCol
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.paddingLarge
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
spacing: Theme.paddingMedium
|
||||
Image {
|
||||
id: headerLogo
|
||||
anchors.bottom: ccode.bottom
|
||||
height: ccode.height * 0.8
|
||||
fillMode: Image.PreserveAspectFit
|
||||
smooth: true
|
||||
source: _countrycode === "" ? "../images/bycountry_t.png" : "../flags/"+_countrycode.toLowerCase()+".png"
|
||||
}
|
||||
Label {
|
||||
id: ccode
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
color: Theme.highlightColor
|
||||
wrapMode: Text.WordWrap
|
||||
elide: Text.ElideLeft
|
||||
text: getCountryStations.country
|
||||
}
|
||||
}
|
||||
Label {
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.secondaryHighlightColor
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: sortedby
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: row
|
||||
width: parent.width
|
||||
SearchField {
|
||||
id: sfield
|
||||
placeholderText: qsTr("Search")
|
||||
inputMethodHints: Qt.ImhNoAutoUppercase
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||
EnterKey.onClicked: focus = false
|
||||
focus: sfocus
|
||||
text: stext
|
||||
|
||||
onFocusChanged: sfocus = focus
|
||||
|
||||
onTextChanged: {
|
||||
if (searchtext !== text) {
|
||||
if (text.length > 0) {
|
||||
searchtext = text
|
||||
switch(searchCombo.currentIndex) {
|
||||
case 0: filterby="name";getCountryStations.offset=0;getCountryStations.name=text;getCountryStations.tag="";break
|
||||
case 1: filterby="tag";getCountryStations.offset=0;getCountryStations.tag=text;getCountryStations.name=""
|
||||
}
|
||||
} else {
|
||||
getCountryStations.name=""
|
||||
getCountryStations.tag=""
|
||||
}
|
||||
getCountryStations.offset=0;
|
||||
getCountryStations.clear = true
|
||||
getCountryStations.getStations()
|
||||
}
|
||||
}
|
||||
onClicked: {view.currentIndex = -1}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: searchCombo
|
||||
label: qsTr("Search by:")
|
||||
currentIndex: comboIndex
|
||||
menu: ContextMenu {
|
||||
MenuItem { text: qsTr("Name") }
|
||||
MenuItem { text: qsTr("Tag") }
|
||||
}
|
||||
onValueChanged: {
|
||||
switch(currentIndex) {
|
||||
case 0: filterby="name";getCountryStations.offset=0;getCountryStations.name=sfield.text;getCountryStations.tag="";break
|
||||
case 1: filterby="tag";getCountryStations.offset=0;getCountryStations.tag=sfield.text;getCountryStations.name=""
|
||||
}
|
||||
if (searchtext.length !== 0) {
|
||||
getCountryStations.offset=0;
|
||||
getCountryStations.clear = true
|
||||
getCountryStations.getStations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PullDownMenu {
|
||||
MenuItem {
|
||||
text: qsTr("Name")
|
||||
onClicked: {getCountryStations.clear=true;getCountryStations.order = "name";getCountryStations.getStations()}//;xmlModel.running = true}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Most likes")
|
||||
onClicked: {getCountryStations.clear=true;getCountryStations.order = "votes";getCountryStations.getStations()}//;xmlModel.running = true}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Most played")
|
||||
onClicked: {getCountryStations.clear=true;getCountryStations.order = "clickcount";getCountryStations.getStations()}//xmlModel.running = true}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Trending right now")
|
||||
onClicked: {getCountryStations.clear=true;getCountryStations.order = "clicktrend";getCountryStations.getStations()}//xmlModel.running = true}
|
||||
}
|
||||
}
|
||||
|
||||
model: getCountryStations.stationsModel
|
||||
|
||||
delegate: StationsDelegate{
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._cc = model.countrycode
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec
|
||||
radioPlayer._bitrate = model.bitrate
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
radioPlayer.getStationFavorite(model.stationuuid)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
getCountryStations.countrycode=_countrycode
|
||||
getCountryStations.order=searchby
|
||||
getCountryStations.getStations()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import QtQuick 2.2
|
||||
import Sailfish.Silica 1.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import "../delegates"
|
||||
import "../helpers/db.js" as Favorites
|
||||
|
||||
Page {
|
||||
property ListModel favorites: ListModel {id: favorites}
|
||||
property real showP: 0.0
|
||||
property int tab: 0//allradioSettings.value("favoriteTab",0)
|
||||
SilicaListView {
|
||||
|
||||
id: view
|
||||
// enabled: !splashItem.visible
|
||||
opacity: enabled ? 1 : 0
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: mediaPlayerPanel.visibleSize
|
||||
clip: mediaPlayerPanel.expanded
|
||||
|
||||
onVisibleChanged: if (visible) updateFav()
|
||||
|
||||
|
||||
header: Column {
|
||||
width: parent.width
|
||||
spacing: Theme.paddingLarge
|
||||
PageHeader{
|
||||
title: qsTr("Favorites")
|
||||
description: qsTr("Radio stations: ")+view.count
|
||||
}
|
||||
|
||||
Row {
|
||||
id: row
|
||||
|
||||
// width: parent.width
|
||||
//anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width
|
||||
TabButton {
|
||||
id: home
|
||||
//anchors.verticalCenter: parent.verticalCenter
|
||||
down: tab === 0
|
||||
width: parent.width / 3
|
||||
fontSize: Theme.fontSizeMedium
|
||||
fontColor: down ? Theme.secondaryColor : Theme.secondaryColor
|
||||
iconVisible: false
|
||||
// icon: "image://theme/icon-m-home" //"image://theme/icon-m-video"
|
||||
text: qsTr("By name")
|
||||
onButtonClick: {showP=0.0;tab = 0;Favorites.getFavorites(favorites,"name",10000)}
|
||||
}
|
||||
TabButton {
|
||||
id: search
|
||||
// anchors.verticalCenter: parent.verticalCenter
|
||||
down: tab === 1
|
||||
width: parent.width / 3
|
||||
fontSize: Theme.fontSizeMedium
|
||||
fontColor: down ? Theme.secondaryColor : Theme.secondaryColor
|
||||
iconVisible: false
|
||||
// icon: "image://theme/icon-m-search"
|
||||
text: qsTr("Most played")
|
||||
onButtonClick: {showP=0.0;tab = 1;Favorites.getFavorites(favorites,"myclickcount",10000)}
|
||||
}
|
||||
TabButton {
|
||||
id: favorite
|
||||
// anchors.verticalCenter: parent.verticalCenter
|
||||
down: tab === 2
|
||||
width: parent.width / 3
|
||||
fontSize: Theme.fontSizeMedium
|
||||
fontColor: down ? Theme.secondaryColor : Theme.secondaryColor
|
||||
iconVisible: false
|
||||
// icon: "image://theme/icon-m-favorite"
|
||||
text: qsTr("Last played")
|
||||
onButtonClick: {showP=0.0;tab = 2;Favorites.getFavorites(favorites,"myclicktimestamp",10000);console.log("CLICK")}
|
||||
}
|
||||
}
|
||||
Item {width: parent.width;height: Theme.paddingLarge}
|
||||
}
|
||||
|
||||
|
||||
ViewPlaceholder {
|
||||
anchors.centerIn: allRadio.center
|
||||
enabled: view.count == 0
|
||||
text: qsTr("Favorites")
|
||||
hintText: qsTr("add favorites here")
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {}
|
||||
model: favorites
|
||||
delegate: StationsDelegate{
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._cc = model.countrycode
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec//getCodec(model.codec)
|
||||
radioPlayer._bitrate = model.bitrate //getBitrate(model.bitrate)
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
radioPlayer._favorite = model.favorite ? true : false
|
||||
radioPlayer.fav
|
||||
radioPlayer.playlistIndex = index
|
||||
} else radioPlayer.resumeStream()
|
||||
}
|
||||
}
|
||||
function updateFav() {
|
||||
var sort
|
||||
switch (tab){
|
||||
case 0: sort = "name";break
|
||||
case 1: sort = "myclickcount";break
|
||||
case 2: sort = "myclicktimestamp";break
|
||||
}
|
||||
Favorites.getFavorites(favorites,sort,10000)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
|
||||
updateFav()
|
||||
}
|
||||
Component.onDestruction: {
|
||||
//allradioSettings.setValue("favoriteTab",tab)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import QtQuick 2.2
|
||||
import Sailfish.Silica 1.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import "../delegates"
|
||||
import "../helpers/db.js" as Favorites
|
||||
|
||||
Page {
|
||||
property ListModel history: ListModel {id: history}
|
||||
SilicaListView {
|
||||
id: view
|
||||
|
||||
enabled: !splashItem.visible
|
||||
//visible: enabled
|
||||
opacity: enabled ? 1 : 0
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: mediaPlayerPanel.visibleSize
|
||||
clip: mediaPlayerPanel.expanded
|
||||
onVisibleChanged: if (visible) updateHist()
|
||||
ViewPlaceholder {
|
||||
anchors.centerIn: allRadio.center
|
||||
enabled: view.count == 0
|
||||
text: qsTr("History")
|
||||
hintText: qsTr("see you play history here")
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {}
|
||||
header: PageHeader{title: qsTr("Play history");description: qsTr("Radio stations: ")+view.count}
|
||||
|
||||
|
||||
/* onAtYEndChanged: {
|
||||
if (atYEnd && view.count >= getCountryStations.limit) {
|
||||
// console.log("AT BOTTOM: "+view.count)
|
||||
if (getCountryStations.offset + getCountryStations.limit < stationCount) {
|
||||
getCountryStations.offset = getCountryStations.offset + getCountryStations.limit + 1
|
||||
getCountryStations.getStations()
|
||||
}
|
||||
}
|
||||
} */
|
||||
model: history
|
||||
delegate: StationsDelegate{
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._cc = model.countrycode
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec//getCodec(model.codec)
|
||||
radioPlayer._bitrate = model.bitrate //getBitrate(model.bitrate)
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
radioPlayer._favorite = model.favorite ? true : false
|
||||
radioPlayer.playlistIndex = favoriteView.currentIndex
|
||||
//pageStack.push("RadioPlayerPage.qml")
|
||||
} else radioPlayer.resumeStream()
|
||||
}
|
||||
}
|
||||
function updateHist() {
|
||||
Favorites.getHistory(history,10000)
|
||||
}
|
||||
|
||||
Component.onCompleted: updateHist()
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
import QtQuick 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
import Sailfish.Silica 1.0
|
||||
import "../delegates"
|
||||
import "../items"
|
||||
import "../helpers/jsFunctions.js" as JSfunctions
|
||||
|
||||
Page {
|
||||
id: page
|
||||
property bool keepScreenOn: Qt.application.active && radioPlayer.isPlaying && radioPlayer.radioVideo ? true : false
|
||||
|
||||
allowedOrientations: radioPlayer.isPlaying && radioPlayer.radioVideo ? Orientation.All : Orientation.Portrait
|
||||
|
||||
backNavigation: orientation === Orientation.Portrait ? true : false//radioPlayer.isPlaying && radioPlayer.radioVideo && Orientation.Portrait ? false : true
|
||||
|
||||
ScreenBlank {
|
||||
id: screenBlank
|
||||
enabled: keepScreenOn
|
||||
}
|
||||
|
||||
VideoPlayer {
|
||||
id: videoPlayer
|
||||
z:97
|
||||
anchors.top: orientation === Orientation.Portrait ? radioName.top : page.top
|
||||
anchors.bottom: orientation === Orientation.Portrait ? radioName.bottom : page.bottom
|
||||
anchors.left: orientation === Orientation.Portrait ? radioName.left : page.left
|
||||
anchors.right: orientation === Orientation.Portrait ? radioName.right : page.right
|
||||
anchors.margins: orientation === Orientation.Portrait ? radioName.border.width : 0
|
||||
visible: radioPlayer.radioVideo && !radioPlayer.isPaused ? true : false
|
||||
onVisibleChanged: visible ? enabled=true : enabled = false
|
||||
videoSource: radioPlayer
|
||||
}
|
||||
|
||||
PageHeader {
|
||||
id: pheader
|
||||
z: orientation === Orientation.Portrait //|| !screenTimer.running ? 98 : 0
|
||||
visible: orientation !== Orientation.LandscapeMask
|
||||
|
||||
Column {
|
||||
id: headerCol
|
||||
visible: orientation === Orientation.Portrait
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.paddingLarge
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
spacing: Theme.paddingSmall
|
||||
Row {
|
||||
spacing: Theme.paddingMedium
|
||||
anchors.right: parent.right
|
||||
Text{
|
||||
id: countryName
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
color: Theme.highlightColor
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: radioPlayer.radioCountryName
|
||||
}
|
||||
Image {
|
||||
anchors.bottom: countryName.bottom
|
||||
height: countryName.height * 0.9
|
||||
fillMode: Image.PreserveAspectFit
|
||||
smooth: false
|
||||
source: radioPlayer._cc === "" ? "../images/bycountry_t.png" : "../flags/"+radioPlayer._cc.toLowerCase()+".png"
|
||||
}
|
||||
}
|
||||
Label {
|
||||
anchors.right: parent.right
|
||||
color: Theme.secondaryHighlightColor
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
text: JSfunctions.getAll(radioPlayer._hls,radioPlayer._codec,radioPlayer._bitrate)
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: radioName
|
||||
anchors.top: pheader.bottom
|
||||
anchors.topMargin: Theme.paddingLarge
|
||||
anchors.bottom: artistSongName.top
|
||||
anchors.bottomMargin: Theme.paddingLarge
|
||||
color: Theme.rgba(Theme.overlayBackgroundColor,0.5)
|
||||
radius: 20
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width - (Theme.paddingLarge * 2)
|
||||
|
||||
Behavior on opacity {
|
||||
FadeAnimator {}
|
||||
}
|
||||
|
||||
|
||||
Label {
|
||||
id: nameLabel
|
||||
z:99
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.paddingLarge * 2
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
font.bold: false
|
||||
color: Theme.secondaryColor
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
fontSizeMode: Text.Fit
|
||||
maximumLineCount: 2
|
||||
width: parent.width - (Theme.paddingLarge * 2)
|
||||
height: Theme.itemSizeExtraSmall
|
||||
elide: Text.ElideLeft
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: radioPlayer._name
|
||||
}
|
||||
|
||||
RadioImage {
|
||||
anchors.top: nameLabel.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: Theme.paddingLarge
|
||||
anchors.bottomMargin: Theme.paddingLarge * 2
|
||||
id: radioImage
|
||||
width: height
|
||||
stationBorder: false
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
stationImage: radioPlayer._favicon ? radioPlayer._favicon : ""
|
||||
stationLabel: radioPlayer._name
|
||||
flag: false
|
||||
onWidthChanged: if (width > radioName.width - (Theme.paddingLarge * 2)) width = radioName.width - (Theme.paddingLarge * 2)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: artistSongName
|
||||
anchors.bottom: playerControls.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: Theme.paddingLarge
|
||||
color: Theme.rgba(Theme.overlayBackgroundColor,0.5)
|
||||
radius: 20
|
||||
width: parent.width
|
||||
height: radioname.height + radiocountry.height + (Theme.paddingMedium * 3)
|
||||
opacity: radioname.text !== "" ? 1.0 : 0.0
|
||||
Behavior on opacity {
|
||||
FadeAnimator {}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.margins: Theme.paddingSmall
|
||||
|
||||
Label {
|
||||
id: radioname
|
||||
color: Theme.secondaryColor
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
fontSizeMode: Text.Fit
|
||||
maximumLineCount: 5
|
||||
width: parent.width - (Theme.paddingMedium * 2)
|
||||
elide: Text.ElideLeft
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: text.length > 0
|
||||
text: radioPlayer.radioVideo && !radioPlayer.isPaused ? radioPlayer._name : radioPlayer.radioArtist // radioPlayer._name
|
||||
}
|
||||
|
||||
Label {
|
||||
id: radiocountry
|
||||
color: Theme.secondaryColor
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
fontSizeMode: Text.Fit
|
||||
maximumLineCount: 5
|
||||
width: parent.width - (Theme.paddingMedium * 2)
|
||||
elide: Text.ElideLeft
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: text.length > 0
|
||||
text: radioPlayer.radioSong
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Radio player controls
|
||||
Item {
|
||||
id: playerControls
|
||||
visible: orientation === Orientation.Portrait
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Theme.paddingMedium
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: Theme.itemSizeLarge
|
||||
width: parent.width
|
||||
|
||||
Rectangle {
|
||||
width: row.width + (Theme.paddingMedium * 3)
|
||||
height: play.height + (Theme.paddingMedium * 2)
|
||||
radius: 90
|
||||
color: Theme.rgba(Theme.overlayBackgroundColor,0.5)
|
||||
border.width: 0
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
|
||||
Row {
|
||||
id: row
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.paddingMedium
|
||||
Image {
|
||||
id: playprev
|
||||
enabled: radioPlayer.playlistIndex > 0 && radioPlayer._favorite
|
||||
visible: radioPlayer._favorite
|
||||
opacity: enabled ? 1.0 : 0.4
|
||||
source: "image://theme/icon-m-previous"
|
||||
height: play.height
|
||||
width: height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.verticalCenter: play.verticalCenter
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
radioPlayer.playPrev()
|
||||
}
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: play
|
||||
source: radioPlayer.isPlaying ? "image://theme/icon-l-pause" : "image://theme/icon-l-play"
|
||||
height: Theme.itemSizeSmall * 0.75
|
||||
width: height
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: radioPlayer.isPlaying ? radioPlayer.pauseStream() : radioPlayer.resumeStream()//icon.source == "image://theme/icon-l-play" ? icon.source = "image://theme/icon-l-pause" : icon.source = "image://theme/icon-l-play"
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: playDLNA
|
||||
enabled: radioPlayer.playlistIndex < radioPlayer.playlist.count -1 && radioPlayer._favorite
|
||||
visible: radioPlayer._favorite
|
||||
opacity: enabled ? 1.0 : 0.4
|
||||
source: "image://theme/icon-m-next"
|
||||
height: play.height
|
||||
width: height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.verticalCenter: play.verticalCenter
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
radioPlayer.playNext()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: orientation === Orientation.Portrait
|
||||
width: sleeptimer.width + upvote.width + favorite.width + (Theme.paddingMedium * 4)
|
||||
height: upvote.height + (Theme.paddingMedium * 2)
|
||||
radius: 90
|
||||
color: Theme.rgba(Theme.overlayBackgroundColor,0.5)
|
||||
border.width: 0
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.paddingMedium
|
||||
Image {
|
||||
id: sleeptimer
|
||||
source: "image://theme/icon-s-timer"
|
||||
height: play.height
|
||||
width: favorite.height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.verticalCenter: favorite.verticalCenter
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
pageStack.push("SleepTimerPage.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: favorite
|
||||
source: radioPlayer._favorite ? "image://theme/icon-m-favorite-selected" : "image://theme/icon-m-favorite"
|
||||
height: Theme.itemSizeSmall * 0.75
|
||||
width: height
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
radioPlayer._favorite ? radioPlayer._favorite = false : radioPlayer._favorite = true
|
||||
radioPlayer.setStationFavorite(radioPlayer._stationuuid,radioPlayer._name,radioPlayer._cc,radioPlayer._homepage,radioPlayer._url_resolved,radioPlayer._favicon,radioPlayer._tags,radioPlayer._codec,radioPlayer._bitrate,radioPlayer._hls,radioPlayer._favorite)
|
||||
}
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: upvote
|
||||
property bool returnValue: false
|
||||
source: returnValue ? "image://theme/icon-m-like" : "image://theme/icon-m-outline-like"
|
||||
height: favorite.height
|
||||
anchors.verticalCenter: favorite.verticalCenter
|
||||
width: height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
onReturnValueChanged: console.log(" RETURN VALUE: "+upvote.returnValue)
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {radioBrowser.upVote(radioPlayer._stationuuid,upvote.returnValue)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
mediaPlayerPanel.open=false
|
||||
radioPlayer.playerPageOpen=true
|
||||
}
|
||||
Component.onDestruction: {
|
||||
if (radioPlayer.radioVideo) radioPlayer.pauseStream()
|
||||
radioPlayer.playerPageOpen=false
|
||||
mediaPlayerPanel.open=true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import "../models"
|
||||
import "../delegates"
|
||||
//import "../radio-browser"
|
||||
|
||||
Page {
|
||||
property string sortedby: ""
|
||||
property string filterby
|
||||
property alias searchby: getCountryStations.order
|
||||
property string searchtext: ""
|
||||
property string _countrycode: ""
|
||||
property int stationCount: 0
|
||||
property alias name: getCountryStations.name
|
||||
property alias tag: getCountryStations.tag
|
||||
property GetCountryStations getCountryStations: GetCountryStations {id: getCountryStations}
|
||||
property bool sfocus
|
||||
|
||||
onStatusChanged: if (status !== PageStatus.Active) sfocus=false
|
||||
|
||||
onSearchbyChanged: {
|
||||
// console.log("SEARCHBY: "+searchby)
|
||||
switch (searchby){
|
||||
case "name": sortedby = qsTr("By Name");break;
|
||||
case "votes": sortedby = qsTr("Most likes");break;
|
||||
case "clicktrend": sortedby = qsTr("Trending right now");break;
|
||||
case "clickcount": sortedby = qsTr("Most played");
|
||||
}
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
id: busy
|
||||
visible: running
|
||||
anchors.centerIn: parent
|
||||
size: BusyIndicatorSize.Large
|
||||
running: !getCountryStations.finished && getCountryStations.offset > 0
|
||||
}
|
||||
|
||||
SilicaListView {
|
||||
id: view
|
||||
enabled: !busy.visible
|
||||
opacity: enabled ? 1 : 0.5
|
||||
anchors.fill: parent
|
||||
|
||||
clip: mediaPlayerPanel.expanded
|
||||
anchors.bottomMargin: sfocus ? 0 : mediaPlayerPanel.visibleSize
|
||||
|
||||
ViewPlaceholder {
|
||||
anchors.centerIn: parent
|
||||
enabled: view.count == 0
|
||||
text: getCountryStations.finished && view.count === 0 ? qsTr("Search") : qsTr("Please wait")
|
||||
hintText: getCountryStations.finished && view.count === 0 ? qsTr("radio stations") : qsTr("getting radio stations")
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {}
|
||||
|
||||
onAtYEndChanged: {
|
||||
if (atYEnd && view.count >= getCountryStations.limit) {
|
||||
// console.log("AT BOTTOM: "+view.count)
|
||||
if (getCountryStations.offset + getCountryStations.limit < stationCount) {
|
||||
getCountryStations.offset = getCountryStations.offset + getCountryStations.limit + 1
|
||||
getCountryStations.getStations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header: Column {
|
||||
width: parent.width
|
||||
|
||||
PageHeader {
|
||||
id: pheader
|
||||
|
||||
|
||||
Column {
|
||||
id: headerCol
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.paddingLarge
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
anchors.rightMargin: Theme.paddingLarge//headerLogo.width + (Theme.paddingLarge * 2)
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
spacing: Theme.paddingMedium
|
||||
Image {
|
||||
id: headerLogo
|
||||
anchors.bottom: ccode.bottom
|
||||
height: ccode.height * 0.8
|
||||
fillMode: Image.PreserveAspectFit
|
||||
smooth: true
|
||||
source: _countrycode === "" ? "../images/bycountry_t.png" : "../flags/"+_countrycode.toLowerCase()+".png"
|
||||
}
|
||||
Label {
|
||||
id: ccode
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
color: Theme.highlightColor
|
||||
wrapMode: Text.WordWrap
|
||||
elide: Text.ElideLeft
|
||||
text: getCountryStations.country //+ " ["+stationCount+"]"
|
||||
}
|
||||
}
|
||||
Label {
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.secondaryHighlightColor
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: sortedby//view.count + " channels"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: row
|
||||
width: parent.width
|
||||
SearchField {
|
||||
id: sfield
|
||||
placeholderText: qsTr("Search")
|
||||
inputMethodHints: Qt.ImhNoAutoUppercase //| Qt.ImhNoPredictiveText
|
||||
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||
EnterKey.onClicked: focus = false
|
||||
focus: sfocus
|
||||
|
||||
onFocusChanged: {
|
||||
sfocus = focus
|
||||
//radioPlayer.isPlaying || radioPlayer.isPaused && !focus ? mediaPlayerPanel.open = false : mediaPlayerPanel.open = true
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
if (searchtext !== text) {
|
||||
// console.log(" *** TEXT CHANGED: "+searchCombo.currentIndex+" --- TEXT: "+text)
|
||||
if (text.length > 0) {
|
||||
searchtext = text
|
||||
switch(searchCombo.currentIndex) {
|
||||
case 0: filterby="name";getCountryStations.offset=0;getCountryStations.name=text;getCountryStations.tag="";break
|
||||
case 1: filterby="tag";getCountryStations.offset=0;getCountryStations.tag=text;getCountryStations.name=""
|
||||
}
|
||||
} else {
|
||||
getCountryStations.name=""
|
||||
getCountryStations.tag=""
|
||||
}
|
||||
getCountryStations.offset=0;
|
||||
getCountryStations.clear = true
|
||||
if (text !== "") getCountryStations.getStations()
|
||||
}
|
||||
}
|
||||
onClicked: {view.currentIndex = -1}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: searchCombo
|
||||
label: qsTr("Search by:")
|
||||
currentIndex: 0
|
||||
menu: ContextMenu {
|
||||
MenuItem { text: qsTr("Name") }
|
||||
MenuItem { text: qsTr("Tag") }
|
||||
}
|
||||
onValueChanged: {
|
||||
switch(currentIndex) {
|
||||
case 0: filterby="name";getCountryStations.offset=0;getCountryStations.name=sfield.text;getCountryStations.tag="";break
|
||||
case 1: filterby="tag";getCountryStations.offset=0;getCountryStations.tag=sfield.text;getCountryStations.name=""
|
||||
}
|
||||
if (searchtext.length !== 0) {
|
||||
getCountryStations.offset=0;
|
||||
getCountryStations.clear = true
|
||||
getCountryStations.getStations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PullDownMenu {
|
||||
MenuItem {
|
||||
text: qsTr("Name")
|
||||
onClicked: {getCountryStations.order = "name";if (view.count > 0) {getCountryStations.clear=true;getCountryStations.getStations()}}//;xmlModel.running = true}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Most likes")
|
||||
onClicked: {getCountryStations.order = "votes";if (view.count > 0) {getCountryStations.clear=true;getCountryStations.getStations()}}//;xmlModel.running = true}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Most played")
|
||||
onClicked: {getCountryStations.order = "clickcount";if (view.count > 0) {getCountryStations.clear=true;getCountryStations.getStations()}}//xmlModel.running = true}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Trending right now")
|
||||
onClicked: {getCountryStations.order = "clicktrend";if (view.count > 0) {getCountryStations.clear=true;getCountryStations.getStations()}}//xmlModel.running = true}
|
||||
}
|
||||
}
|
||||
|
||||
model: getCountryStations.stationsModel
|
||||
delegate: StationsDelegate{
|
||||
onClicked: {
|
||||
if (model.url_resolved !== radioPlayer._url_resolved) {
|
||||
radioPlayer._favicon = model.favicon
|
||||
radioPlayer._name = model.name
|
||||
radioPlayer._cc = model.countrycode
|
||||
radioPlayer._tags = model.tags
|
||||
radioPlayer._codec = model.codec//getCodec(model.codec)
|
||||
radioPlayer._bitrate = model.bitrate //getBitrate(model.bitrate)
|
||||
radioPlayer._hls = model.hls
|
||||
radioPlayer._url_resolved = model.url_resolved
|
||||
radioPlayer._homepage = model.homepage
|
||||
radioPlayer._stationuuid = model.stationuuid
|
||||
//radioPlayer._favorite = model.favorite ? true : false
|
||||
radioPlayer.getStationFavorite(model.stationuuid)
|
||||
// pageStack.push("RadioPlayerPage.qml")
|
||||
} else radioPlayer.resumeStream()
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
//MediaPlayerPanel.open = false
|
||||
getCountryStations.countrycode=""
|
||||
getCountryStations.order=searchby
|
||||
//getCountryStations.getStations()
|
||||
}
|
||||
// Component.onDestruction: if (radioPlayer.isPlaying || radioPlayer.isPaused) mediaPlayerPanel.open ? mediaPlayerPanel.open = false : mediaPlayerPanel.open = true
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
Page {
|
||||
id: page
|
||||
|
||||
// The effective value will be restricted by ApplicationWindow.allowedOrientations
|
||||
allowedOrientations: Orientation.All
|
||||
|
||||
SilicaListView {
|
||||
id: listView
|
||||
model: 20
|
||||
anchors.fill: parent
|
||||
header: PageHeader {
|
||||
title: qsTr("Nested Page")
|
||||
}
|
||||
delegate: BackgroundItem {
|
||||
id: delegate
|
||||
|
||||
Label {
|
||||
x: Theme.horizontalPageMargin
|
||||
text: qsTr("Item") + " " + index
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
|
||||
}
|
||||
onClicked: console.log("Clicked " + index)
|
||||
}
|
||||
VerticalScrollDecorator {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import QtQuick 2.0
|
||||
import QtQml 2.2
|
||||
import Sailfish.Silica 1.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
import "../helpers/db.js" as Favorites
|
||||
|
||||
Dialog {
|
||||
id: settingsDialog
|
||||
|
||||
Column {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: Theme.paddingMedium
|
||||
|
||||
DialogHeader {}
|
||||
|
||||
Label {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
color: Theme.highlightColor
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
text: qsTr("Player settings")
|
||||
}
|
||||
|
||||
Separator {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingMedium
|
||||
color: Theme.highlightColor
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: appStart
|
||||
width: parent.width
|
||||
label: qsTr("Auto play")
|
||||
anchors.margins: Theme.paddingLarge
|
||||
description: qsTr("What to do when AllRadio2 starts")
|
||||
currentIndex: Favorites.getSetting("appStart",0)
|
||||
menu: ContextMenu {
|
||||
MenuItem { text: qsTr("Off") }
|
||||
MenuItem { text: qsTr("Last played") }
|
||||
MenuItem { text: qsTr("Random favorite") }
|
||||
}
|
||||
}
|
||||
Label {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
color: Theme.highlightColor
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
text: qsTr("Server settings")
|
||||
}
|
||||
|
||||
Separator {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingMedium
|
||||
color: Theme.highlightColor
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: serverL
|
||||
width: parent.width
|
||||
anchors.margins: Theme.paddingLarge
|
||||
label: qsTr("Connected to")
|
||||
description: qsTr("Available servers (just information, won't change server yet!)")
|
||||
currentIndex: radioBrowser.serverIndex
|
||||
menu : ContextMenu {
|
||||
id: contextMenu
|
||||
Repeater {
|
||||
model: radioBrowser.serversModel
|
||||
delegate: MenuItem {
|
||||
text: server
|
||||
onClicked: radioBrowser.connectServer(currentIndex)//{radioBrowser.server = serverUrl;radioBrowser.serverIndex=currentIndex;}//console.log("***"+serverUrl)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* menu: ContextMenu {
|
||||
MenuItem { text: qsTr("None") }
|
||||
MenuItem { text: qsTr("Last played") }
|
||||
MenuItem { text: qsTr("Random favorite") }
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: Favorites.setSetting("appStart",appStart.currentIndex)
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import "../items"
|
||||
|
||||
Page {
|
||||
id: page
|
||||
property bool closePanel: false
|
||||
onClosePanelChanged: if (closePanel) mediaPlayerPanel.open = false
|
||||
// property int sleepTime: 0
|
||||
|
||||
//allowedOrientations: Orientation.All
|
||||
|
||||
SilicaFlickable {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
anchors.bottomMargin: mediaPlayerPanel.visibleSize
|
||||
VerticalScrollDecorator {}
|
||||
PageHeader {title: qsTr("Sleep timer");description: ((sleepTime > 0) ? (qsTr("Remaning time: ") + (sleepTime) + qsTr(" minutes")) : qsTr("choose time: ") + minutes.value )}
|
||||
|
||||
ValuePicker {
|
||||
id: minutes
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
max: 121
|
||||
min: 1
|
||||
value: sleepTime
|
||||
}
|
||||
Label {
|
||||
text: minutes.value
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.secondaryHighlightColor
|
||||
font.family: Theme.fontFamilyHeading
|
||||
font.pixelSize: Theme.fontSizeHuge
|
||||
}
|
||||
Row {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 40
|
||||
spacing: Theme.paddingLarge
|
||||
|
||||
Button {
|
||||
text: ((sleepTime > 0) ? (qsTr("Change")) : (qsTr("Start")))
|
||||
onPressed: sleepTime = minutes.value
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Stop")
|
||||
onPressed: sleepTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: if (mediaPlayerPanel.open) closePanel = true; else closePanel = false;
|
||||
Component.onDestruction: if (closePanel) mediaPlayerPanel.open = true
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import "../helpers/db.js" as Favorites
|
||||
|
||||
Page {
|
||||
property int maxTags: 0
|
||||
|
||||
property int fontMin: Theme.fontSizeExtraSmall
|
||||
property int fontMax: Theme.fontSizeHuge
|
||||
|
||||
property ListModel playedTags: ListModel {id: playedTags}
|
||||
|
||||
function getCrSize(size) { /// Calculate and return a more nice looking fontsize based on number of stations.
|
||||
//console.log("FUNCTION: "+size)
|
||||
var fs = size === 100 ? fontMin : (size / maxTags) * (fontMax - fontMin) + fontMin;
|
||||
return fs
|
||||
}
|
||||
|
||||
onMaxTagsChanged: console.log("MAXTAGS: "+maxTags)
|
||||
|
||||
SilicaFlickable {
|
||||
id: flick
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: mediaPlayerPanel.visibleSize
|
||||
contentWidth: parent.width;
|
||||
contentHeight: flow.childrenRect.height + header.height + (Theme.paddingLarge * 2)
|
||||
|
||||
clip: true
|
||||
// header: PageHeader{title: "Play history";description: "Radio stations: "+view.count}
|
||||
|
||||
ScrollDecorator {flickable:flick}
|
||||
|
||||
Column {
|
||||
id: header
|
||||
width: parent.width
|
||||
|
||||
PageHeader {
|
||||
title: qsTr("Played tags")
|
||||
description: qsTr("Found ")+playedTags.count
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
id: flow
|
||||
anchors.top: header.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: Theme.paddingMedium
|
||||
clip: true
|
||||
spacing: Theme.paddingLarge
|
||||
|
||||
Repeater {
|
||||
id: elements
|
||||
model: playedTags
|
||||
|
||||
//onItemAdded: "ITEM ADDED: "+model.tag
|
||||
|
||||
Text {
|
||||
id: tagtext
|
||||
text: tag
|
||||
font.pixelSize: getCrSize(myclickcount) //((stationcount / 3000) * 100) * (Theme.fontSizeExtraLarge - Theme.fontSizeSmall) + Theme.fontSizeSmall
|
||||
//font.bold: if (font.pixelSize >= Theme.fontSizeLarge) true; else false
|
||||
|
||||
color: {
|
||||
if (font.pixelSize <= Theme.fontSizeMedium) Theme.secondaryColor;
|
||||
else if (font.pixelSize > Theme.fontSizeMedium) Theme.primaryColor
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: m
|
||||
anchors.fill: parent
|
||||
onPressedChanged: pressed ? tagtext.color = Theme.highlightColor : tagtext.color = Theme.primaryColor
|
||||
onClicked: pageStack.push("CountryStationsPage.qml",{filterby: "tag",searchby: "name",stext: tag,comboIndex: 1 })//pageStack.push("CrTagStationsPage.qml",{filter: tag}) //pageStack.push("TagStationsPage.qml",{filter: tag,running: true})// //{Qt.inputMethod.hide();flick.focus=true ;pageStack.push("TagStationsPage.qml",{filter: tag,running: true})}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {Favorites.getTagsClicked(playedTags,100000)}
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>GNU General Public License v2.0 - GNU Project - Free Software Foundation (FSF)</title>
|
||||
<link rel="alternate" type="application/rdf+xml"
|
||||
href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.rdf" />
|
||||
</head>
|
||||
<body>
|
||||
<h3 id="SEC1">GNU GENERAL PUBLIC LICENSE</h3>
|
||||
<p>
|
||||
Version 2, June 1991
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
<<a href="https://fsf.org/">https://fsf.org/</a>>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
</pre>
|
||||
|
||||
<span id="SEC2"></span>
|
||||
<h4 id="preamble">Preamble</h4>
|
||||
|
||||
<p>
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
</p>
|
||||
|
||||
<span id="SEC3"></span>
|
||||
<h4 id="terms">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</h4>
|
||||
|
||||
<p id="section0">
|
||||
<strong>0.</strong>
|
||||
This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
</p>
|
||||
|
||||
<p id="section1">
|
||||
<strong>1.</strong>
|
||||
You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
</p>
|
||||
|
||||
<p id="section2">
|
||||
<strong>2.</strong>
|
||||
You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<strong>a)</strong>
|
||||
You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
</dd>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<strong>b)</strong>
|
||||
You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
</dd>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<strong>c)</strong>
|
||||
If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
</p>
|
||||
|
||||
<p id="section3">
|
||||
<strong>3.</strong>
|
||||
You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
</p>
|
||||
|
||||
<!-- we use this doubled UL to get the sub-sections indented, -->
|
||||
<!-- while making the bullets as unobvious as possible. -->
|
||||
|
||||
<dl>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<strong>a)</strong>
|
||||
Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
</dd>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<strong>b)</strong>
|
||||
Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
</dd>
|
||||
<dt></dt>
|
||||
<dd>
|
||||
<strong>c)</strong>
|
||||
Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
</p>
|
||||
|
||||
<p id="section4">
|
||||
<strong>4.</strong>
|
||||
You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
</p>
|
||||
|
||||
<p id="section5">
|
||||
<strong>5.</strong>
|
||||
You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
</p>
|
||||
|
||||
<p id="section6">
|
||||
<strong>6.</strong>
|
||||
Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
</p>
|
||||
|
||||
<p id="section7">
|
||||
<strong>7.</strong>
|
||||
If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
</p>
|
||||
|
||||
<p id="section8">
|
||||
<strong>8.</strong>
|
||||
If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
</p>
|
||||
|
||||
<p id="section9">
|
||||
<strong>9.</strong>
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
</p>
|
||||
|
||||
<p id="section10">
|
||||
<strong>10.</strong>
|
||||
If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
</p>
|
||||
|
||||
<p id="section11"><strong>NO WARRANTY</strong></p>
|
||||
|
||||
<p>
|
||||
<strong>11.</strong>
|
||||
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
</p>
|
||||
|
||||
<p id="section12">
|
||||
<strong>12.</strong>
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
</p>
|
||||
|
||||
<h4>END OF TERMS AND CONDITIONS</h4>
|
||||
|
||||
<span id="SEC4"></span>
|
||||
<h4 id="howto">How to Apply These Terms to Your New Programs</h4>
|
||||
|
||||
<p>
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<var>one line to give the program's name and an idea of what it does.</var>
|
||||
Copyright (C) <var>yyyy</var> <var>name of author</var>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see
|
||||
<<a href="https://www.gnu.org/licenses/">https://www.gnu.org/licenses/</a>>.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Gnomovision version 69, Copyright (C) <var>year</var> <var>name of author</var>
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
|
||||
type `show w'. This is free software, and you are welcome
|
||||
to redistribute it under certain conditions; type `show c'
|
||||
for details.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The hypothetical commands <samp>`show w'</samp> and <samp>`show c'</samp> should show
|
||||
the appropriate parts of the General Public License. Of course, the
|
||||
commands you use may be called something other than <samp>`show w'</samp> and
|
||||
<samp>`show c'</samp>; they could even be mouse-clicks or menu items--whatever
|
||||
suits your program.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
</p>
|
||||
|
||||
|
||||
<pre>
|
||||
Yoyodyne, Inc., hereby disclaims all copyright
|
||||
interest in the program `Gnomovision'
|
||||
(which makes passes at compilers) written
|
||||
by James Hacker.
|
||||
|
||||
<var>signature of Moe Ghoul</var>, 1 April 1989
|
||||
Moe Ghoul, President of Vice
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the
|
||||
<a href="https://www.gnu.org/licenses/lgpl.html">GNU Lesser General Public License</a>
|
||||
instead of this License.
|
||||
</p>
|
||||
|
||||
</body></html>
|
||||
Reference in New Issue
Block a user