parent
ad56fdc932
commit
294eae80dd
|
@ -57,5 +57,7 @@
|
||||||
<file>media-playback-start-32.png</file>
|
<file>media-playback-start-32.png</file>
|
||||||
<file>lightbulb.png</file>
|
<file>lightbulb.png</file>
|
||||||
<file>shuffle.png</file>
|
<file>shuffle.png</file>
|
||||||
|
<file>open_media.png</file>
|
||||||
|
<file>open_stream.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 796 B |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,62 @@
|
||||||
|
#include "addstreamdialog.h"
|
||||||
|
#include "radiomodel.h"
|
||||||
|
#include "savedradio.h"
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
const char* AddStreamDialog::kSettingsGroup = "AddStreamDialog";
|
||||||
|
|
||||||
|
AddStreamDialog::AddStreamDialog(QWidget *parent)
|
||||||
|
: QDialog(parent),
|
||||||
|
saved_radio_(NULL)
|
||||||
|
{
|
||||||
|
ui_.setupUi(this);
|
||||||
|
|
||||||
|
connect(ui_.url, SIGNAL(textChanged(QString)), SLOT(TextChanged(QString)));
|
||||||
|
TextChanged(QString::null);
|
||||||
|
|
||||||
|
// Restore settings
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
ui_.save->setChecked(s.value("save", true).toBool());
|
||||||
|
ui_.url->setText(s.value("url").toString());
|
||||||
|
|
||||||
|
// Connections to the saved streams service
|
||||||
|
saved_radio_ = qobject_cast<SavedRadio*>(
|
||||||
|
RadioModel::ServiceByName(SavedRadio::kServiceName));
|
||||||
|
|
||||||
|
connect(saved_radio_, SIGNAL(ShowAddStreamDialog()), SLOT(show()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl AddStreamDialog::url() const {
|
||||||
|
return QUrl::fromUserInput(ui_.url->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddStreamDialog::accept() {
|
||||||
|
if (ui_.save->isChecked()) {
|
||||||
|
saved_radio_->Add(url());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save settings
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
s.setValue("save", ui_.save->isChecked());
|
||||||
|
s.setValue("url", url().toString());
|
||||||
|
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddStreamDialog::TextChanged(const QString &text) {
|
||||||
|
// Decide whether the URL is valid
|
||||||
|
QUrl url(QUrl::fromUserInput(text));
|
||||||
|
|
||||||
|
bool valid = url.isValid() &&
|
||||||
|
!url.scheme().isEmpty() &&
|
||||||
|
!url.toString().isEmpty();
|
||||||
|
|
||||||
|
ui_.button_box->button(QDialogButtonBox::Ok)->setEnabled(valid);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef ADDSTREAMDIALOG_H
|
||||||
|
#define ADDSTREAMDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "ui_addstreamdialog.h"
|
||||||
|
|
||||||
|
class SavedRadio;
|
||||||
|
|
||||||
|
class AddStreamDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AddStreamDialog(QWidget *parent = 0);
|
||||||
|
|
||||||
|
QUrl url() const;
|
||||||
|
|
||||||
|
void accept();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void TextChanged(const QString& text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char* kSettingsGroup;
|
||||||
|
|
||||||
|
Ui::AddStreamDialog ui_;
|
||||||
|
|
||||||
|
SavedRadio* saved_radio_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ADDSTREAMDIALOG_H
|
|
@ -0,0 +1,97 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AddStreamDialog</class>
|
||||||
|
<widget class="QDialog" name="AddStreamDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>122</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Add Stream</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enter the URL of an internet radio stream:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="url"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="save">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save this stream in the Radio tab</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>7</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="button_box">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>button_box</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>AddStreamDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>button_box</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>AddStreamDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -15,6 +15,7 @@
|
||||||
#include "settingsdialog.h"
|
#include "settingsdialog.h"
|
||||||
#include "libraryconfigdialog.h"
|
#include "libraryconfigdialog.h"
|
||||||
#include "about.h"
|
#include "about.h"
|
||||||
|
#include "addstreamdialog.h"
|
||||||
|
|
||||||
#include "qxtglobalshortcut.h"
|
#include "qxtglobalshortcut.h"
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QSignalMapper>
|
#include <QSignalMapper>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -48,6 +50,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
player_(new Player(playlist_, radio_model_->GetLastFMService(), this)),
|
player_(new Player(playlist_, radio_model_->GetLastFMService(), this)),
|
||||||
library_(new Library(player_->GetEngine(), this)),
|
library_(new Library(player_->GetEngine(), this)),
|
||||||
settings_dialog_(new SettingsDialog(this)),
|
settings_dialog_(new SettingsDialog(this)),
|
||||||
|
add_stream_dialog_(new AddStreamDialog(this)),
|
||||||
playlist_menu_(new QMenu(this)),
|
playlist_menu_(new QMenu(this)),
|
||||||
library_sort_model_(new QSortFilterProxyModel(this)),
|
library_sort_model_(new QSortFilterProxyModel(this)),
|
||||||
track_position_timer_(new QTimer(this))
|
track_position_timer_(new QTimer(this))
|
||||||
|
@ -104,6 +107,9 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
connect(ui_.action_configure, SIGNAL(triggered()), settings_dialog_, SLOT(show()));
|
connect(ui_.action_configure, SIGNAL(triggered()), settings_dialog_, SLOT(show()));
|
||||||
connect(ui_.action_about, SIGNAL(triggered()), about_dialog_, SLOT(show()));
|
connect(ui_.action_about, SIGNAL(triggered()), about_dialog_, SLOT(show()));
|
||||||
connect(ui_.action_shuffle, SIGNAL(triggered()), playlist_, SLOT(Shuffle()));
|
connect(ui_.action_shuffle, SIGNAL(triggered()), playlist_, SLOT(Shuffle()));
|
||||||
|
connect(ui_.action_open_media, SIGNAL(triggered()), SLOT(AddMedia()));
|
||||||
|
connect(ui_.action_add_media, SIGNAL(triggered()), SLOT(AddMedia()));
|
||||||
|
connect(ui_.action_add_stream, SIGNAL(triggered()), SLOT(AddStream()));
|
||||||
|
|
||||||
// Give actions to buttons
|
// Give actions to buttons
|
||||||
ui_.forward_button->setDefaultAction(ui_.action_next_track);
|
ui_.forward_button->setDefaultAction(ui_.action_next_track);
|
||||||
|
@ -243,6 +249,9 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
connect(settings_dialog_, SIGNAL(accepted()), player_, SLOT(ReloadSettings()));
|
connect(settings_dialog_, SIGNAL(accepted()), player_, SLOT(ReloadSettings()));
|
||||||
connect(settings_dialog_, SIGNAL(accepted()), osd_, SLOT(ReloadSettings()));
|
connect(settings_dialog_, SIGNAL(accepted()), osd_, SLOT(ReloadSettings()));
|
||||||
|
|
||||||
|
// Add stream dialog
|
||||||
|
connect(add_stream_dialog_, SIGNAL(accepted()), SLOT(AddStreamAccepted()));
|
||||||
|
|
||||||
// Analyzer
|
// Analyzer
|
||||||
ui_.analyzer->set_engine(player_->GetEngine());
|
ui_.analyzer->set_engine(player_->GetEngine());
|
||||||
|
|
||||||
|
@ -557,3 +566,40 @@ void MainWindow::LibraryScanFinished() {
|
||||||
void MainWindow::PlayerInitFinished() {
|
void MainWindow::PlayerInitFinished() {
|
||||||
multi_loading_indicator_->TaskFinished(MultiLoadingIndicator::LoadingAudioEngine);
|
multi_loading_indicator_->TaskFinished(MultiLoadingIndicator::LoadingAudioEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::AddMedia() {
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
|
||||||
|
// Last used directory
|
||||||
|
QString directory = s.value("add_media_path", QDir::currentPath()).toString();
|
||||||
|
|
||||||
|
// Show dialog
|
||||||
|
QStringList file_names = QFileDialog::getOpenFileNames(this, "Add media", directory);
|
||||||
|
if (file_names.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Save last used directory
|
||||||
|
s.setValue("add_media_path", file_names[0]);
|
||||||
|
|
||||||
|
// Add media
|
||||||
|
QList<QUrl> urls;
|
||||||
|
foreach (const QString& path, file_names) {
|
||||||
|
QUrl url(path);
|
||||||
|
if (url.scheme().isEmpty())
|
||||||
|
url.setScheme("file");
|
||||||
|
urls << url;
|
||||||
|
}
|
||||||
|
playlist_->InsertPaths(urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::AddStream() {
|
||||||
|
add_stream_dialog_->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::AddStreamAccepted() {
|
||||||
|
QList<QUrl> urls;
|
||||||
|
urls << add_stream_dialog_->url();
|
||||||
|
|
||||||
|
playlist_->InsertStreamUrls(urls);
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ class EditTagDialog;
|
||||||
class MultiLoadingIndicator;
|
class MultiLoadingIndicator;
|
||||||
class SettingsDialog;
|
class SettingsDialog;
|
||||||
class About;
|
class About;
|
||||||
|
class AddStreamDialog;
|
||||||
|
|
||||||
class QSortFilterProxyModel;
|
class QSortFilterProxyModel;
|
||||||
class SystemTrayIcon;
|
class SystemTrayIcon;
|
||||||
|
@ -71,6 +72,10 @@ class MainWindow : public QMainWindow {
|
||||||
|
|
||||||
void PlayerInitFinished();
|
void PlayerInitFinished();
|
||||||
|
|
||||||
|
void AddMedia();
|
||||||
|
void AddStream();
|
||||||
|
void AddStreamAccepted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SaveGeometry();
|
void SaveGeometry();
|
||||||
|
|
||||||
|
@ -93,6 +98,7 @@ class MainWindow : public QMainWindow {
|
||||||
Library* library_;
|
Library* library_;
|
||||||
|
|
||||||
SettingsDialog* settings_dialog_;
|
SettingsDialog* settings_dialog_;
|
||||||
|
AddStreamDialog* add_stream_dialog_;
|
||||||
|
|
||||||
QMenu* playlist_menu_;
|
QMenu* playlist_menu_;
|
||||||
QAction* playlist_play_pause_;
|
QAction* playlist_play_pause_;
|
||||||
|
|
|
@ -353,6 +353,9 @@
|
||||||
<attribute name="headerVisible">
|
<attribute name="headerVisible">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
<attribute name="headerVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -434,13 +437,15 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>804</width>
|
<width>804</width>
|
||||||
<height>23</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuMusic">
|
<widget class="QMenu" name="menuMusic">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Music</string>
|
<string>Music</string>
|
||||||
</property>
|
</property>
|
||||||
|
<addaction name="action_open_media"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="action_previous_track"/>
|
<addaction name="action_previous_track"/>
|
||||||
<addaction name="action_play_pause"/>
|
<addaction name="action_play_pause"/>
|
||||||
<addaction name="action_stop"/>
|
<addaction name="action_stop"/>
|
||||||
|
@ -455,6 +460,9 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Playlist</string>
|
<string>Playlist</string>
|
||||||
</property>
|
</property>
|
||||||
|
<addaction name="action_add_media"/>
|
||||||
|
<addaction name="action_add_stream"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="action_clear_playlist"/>
|
<addaction name="action_clear_playlist"/>
|
||||||
<addaction name="action_shuffle"/>
|
<addaction name="action_shuffle"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -657,6 +665,33 @@
|
||||||
<string>Shuffle playlist</string>
|
<string>Shuffle playlist</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="action_add_media">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../data/data.qrc">
|
||||||
|
<normaloff>:/open_media.png</normaloff>:/open_media.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add media...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action_add_stream">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../data/data.qrc">
|
||||||
|
<normaloff>:/open_stream.png</normaloff>:/open_stream.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add stream...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action_open_media">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../data/data.qrc">
|
||||||
|
<normaloff>:/open_media.png</normaloff>:/open_media.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Open media...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "songplaylistitem.h"
|
#include "songplaylistitem.h"
|
||||||
#include "radiomimedata.h"
|
#include "radiomimedata.h"
|
||||||
#include "radioplaylistitem.h"
|
#include "radioplaylistitem.h"
|
||||||
|
#include "radiomodel.h"
|
||||||
|
#include "savedradio.h"
|
||||||
|
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
@ -292,6 +294,15 @@ QModelIndex Playlist::InsertRadioStations(const QList<RadioItem*>& items, int af
|
||||||
return InsertItems(playlist_items, after);
|
return InsertItems(playlist_items, after);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QModelIndex Playlist::InsertStreamUrls(const QList<QUrl>& urls, int after) {
|
||||||
|
QList<PlaylistItem*> playlist_items;
|
||||||
|
foreach (const QUrl& url, urls) {
|
||||||
|
playlist_items << new RadioPlaylistItem(
|
||||||
|
RadioModel::ServiceByName(SavedRadio::kServiceName), url.toString(), url.toString(), QString());
|
||||||
|
}
|
||||||
|
return InsertItems(playlist_items, after);
|
||||||
|
}
|
||||||
|
|
||||||
QMimeData* Playlist::mimeData(const QModelIndexList& indexes) const {
|
QMimeData* Playlist::mimeData(const QModelIndexList& indexes) const {
|
||||||
QMimeData* data = new QMimeData;
|
QMimeData* data = new QMimeData;
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ class Playlist : public QAbstractListModel {
|
||||||
QModelIndex InsertItems(const QList<PlaylistItem*>& items, int after = -1);
|
QModelIndex InsertItems(const QList<PlaylistItem*>& items, int after = -1);
|
||||||
QModelIndex InsertSongs(const SongList& items, int after = -1);
|
QModelIndex InsertSongs(const SongList& items, int after = -1);
|
||||||
QModelIndex InsertRadioStations(const QList<RadioItem*>& items, int after = -1);
|
QModelIndex InsertRadioStations(const QList<RadioItem*>& items, int after = -1);
|
||||||
|
QModelIndex InsertStreamUrls(const QList<QUrl>& urls, int after = -1);
|
||||||
QModelIndex InsertPaths(QList<QUrl> urls, int after = -1);
|
QModelIndex InsertPaths(QList<QUrl> urls, int after = -1);
|
||||||
void StopAfter(int row);
|
void StopAfter(int row);
|
||||||
void ReloadItems(const QList<int>& rows);
|
void ReloadItems(const QList<int>& rows);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "lastfmservice.h"
|
#include "lastfmservice.h"
|
||||||
#include "somafmservice.h"
|
#include "somafmservice.h"
|
||||||
#include "radiomimedata.h"
|
#include "radiomimedata.h"
|
||||||
|
#include "savedradio.h"
|
||||||
|
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
@ -18,6 +19,7 @@ RadioModel::RadioModel(QObject* parent)
|
||||||
|
|
||||||
AddService(new LastFMService(this));
|
AddService(new LastFMService(this));
|
||||||
AddService(new SomaFMService(this));
|
AddService(new SomaFMService(this));
|
||||||
|
AddService(new SavedRadio(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadioModel::AddService(RadioService *service) {
|
void RadioModel::AddService(RadioService *service) {
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
#include "savedradio.h"
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
|
const char* SavedRadio::kServiceName = "SavedRadio";
|
||||||
|
const char* SavedRadio::kSettingsGroup = "SavedRadio";
|
||||||
|
|
||||||
|
SavedRadio::SavedRadio(QObject* parent)
|
||||||
|
: RadioService(kServiceName, parent),
|
||||||
|
root_(NULL),
|
||||||
|
context_menu_(new QMenu)
|
||||||
|
{
|
||||||
|
add_action_ = context_menu_->addAction(QIcon(":media-playback-start.png"), tr("Add to playlist"), this, SLOT(AddToPlaylist()));
|
||||||
|
remove_action_ = context_menu_->addAction(QIcon(":list-remove.png"), tr("Remove"), this, SLOT(Remove()));
|
||||||
|
context_menu_->addSeparator();
|
||||||
|
context_menu_->addAction(QIcon(":open_stream.png"), tr("Add another stream..."), this, SIGNAL(ShowAddStreamDialog()));
|
||||||
|
|
||||||
|
LoadStreams();
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedRadio::~SavedRadio() {
|
||||||
|
delete context_menu_;
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioItem* SavedRadio::CreateRootItem(RadioItem* parent) {
|
||||||
|
root_ = new RadioItem(this, RadioItem::Type_Service, "Your radio streams", parent);
|
||||||
|
root_->icon = QIcon(":open_stream.png");
|
||||||
|
return root_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedRadio::LazyPopulate(RadioItem* item) {
|
||||||
|
switch (item->type) {
|
||||||
|
case RadioItem::Type_Service:
|
||||||
|
foreach (const QString& stream, streams_)
|
||||||
|
ItemForStream(stream, root_);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->lazy_loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedRadio::LoadStreams() {
|
||||||
|
// Load saved streams
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
|
||||||
|
int count = s.beginReadArray("streams");
|
||||||
|
for (int i=0 ; i<count ; ++i) {
|
||||||
|
s.setArrayIndex(i);
|
||||||
|
streams_ << s.value("url").toString();
|
||||||
|
}
|
||||||
|
s.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedRadio::SaveStreams() {
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
|
||||||
|
int count = streams_.size();
|
||||||
|
s.beginWriteArray("streams", count);
|
||||||
|
for (int i=0 ; i<count ; ++i) {
|
||||||
|
s.setArrayIndex(i);
|
||||||
|
s.setValue("url", streams_[i]);
|
||||||
|
}
|
||||||
|
s.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedRadio::ShowContextMenu(RadioItem* item, const QPoint& global_pos) {
|
||||||
|
context_item_ = item;
|
||||||
|
|
||||||
|
add_action_->setEnabled(item != root_);
|
||||||
|
remove_action_->setEnabled(item != root_);
|
||||||
|
|
||||||
|
context_menu_->popup(global_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedRadio::Remove() {
|
||||||
|
streams_.removeAll(context_item_->key);
|
||||||
|
context_item_->parent->DeleteNotify(context_item_->row);
|
||||||
|
SaveStreams();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedRadio::StartLoading(const QUrl& url) {
|
||||||
|
emit StreamReady(url, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedRadio::AddToPlaylist() {
|
||||||
|
emit AddItemToPlaylist(context_item_);
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioItem* SavedRadio::ItemForStream(const QUrl& url, RadioItem* parent) {
|
||||||
|
RadioItem* s = new RadioItem(this, Type_Stream, url.toString(), parent);
|
||||||
|
s->lazy_loaded = true;
|
||||||
|
s->icon = QIcon(":last.fm/icon_radio.png");
|
||||||
|
s->playable = true;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedRadio::Add(const QUrl &url) {
|
||||||
|
if (streams_.contains(url.toString()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
streams_ << url.toString();
|
||||||
|
|
||||||
|
if (root_->lazy_loaded) {
|
||||||
|
RadioItem* s = ItemForStream(url, NULL);
|
||||||
|
s->InsertNotify(root_);
|
||||||
|
}
|
||||||
|
SaveStreams();
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef SAVEDRADIO_H
|
||||||
|
#define SAVEDRADIO_H
|
||||||
|
|
||||||
|
#include "radioservice.h"
|
||||||
|
|
||||||
|
class QMenu;
|
||||||
|
|
||||||
|
class SavedRadio : public RadioService {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SavedRadio(QObject* parent = 0);
|
||||||
|
~SavedRadio();
|
||||||
|
|
||||||
|
enum ItemType {
|
||||||
|
Type_Stream = 2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* kServiceName;
|
||||||
|
static const char* kSettingsGroup;
|
||||||
|
|
||||||
|
RadioItem* CreateRootItem(RadioItem* parent);
|
||||||
|
void LazyPopulate(RadioItem* item);
|
||||||
|
|
||||||
|
void ShowContextMenu(RadioItem* item, const QPoint& global_pos);
|
||||||
|
|
||||||
|
void StartLoading(const QUrl& url);
|
||||||
|
|
||||||
|
void Add(const QUrl& url);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void ShowAddStreamDialog();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void AddToPlaylist();
|
||||||
|
void Remove();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void LoadStreams();
|
||||||
|
void SaveStreams();
|
||||||
|
RadioItem* ItemForStream(const QUrl& url, RadioItem* parent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RadioItem* root_;
|
||||||
|
QMenu* context_menu_;
|
||||||
|
RadioItem* context_item_;
|
||||||
|
|
||||||
|
QAction* add_action_;
|
||||||
|
QAction* remove_action_;
|
||||||
|
|
||||||
|
QStringList streams_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SAVEDRADIO_H
|
15
src/src.pro
15
src/src.pro
|
@ -52,7 +52,9 @@ SOURCES += main.cpp \
|
||||||
libraryconfigdialog.cpp \
|
libraryconfigdialog.cpp \
|
||||||
lastfmconfigdialog.cpp \
|
lastfmconfigdialog.cpp \
|
||||||
about.cpp \
|
about.cpp \
|
||||||
albumcoverfetcher.cpp
|
albumcoverfetcher.cpp \
|
||||||
|
addstreamdialog.cpp \
|
||||||
|
savedradio.cpp
|
||||||
HEADERS += mainwindow.h \
|
HEADERS += mainwindow.h \
|
||||||
player.h \
|
player.h \
|
||||||
library.h \
|
library.h \
|
||||||
|
@ -105,7 +107,9 @@ HEADERS += mainwindow.h \
|
||||||
libraryconfigdialog.h \
|
libraryconfigdialog.h \
|
||||||
lastfmconfigdialog.h \
|
lastfmconfigdialog.h \
|
||||||
about.h \
|
about.h \
|
||||||
albumcoverfetcher.h
|
albumcoverfetcher.h \
|
||||||
|
addstreamdialog.h \
|
||||||
|
savedradio.h
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
libraryconfig.ui \
|
libraryconfig.ui \
|
||||||
fileview.ui \
|
fileview.ui \
|
||||||
|
@ -117,7 +121,8 @@ FORMS += mainwindow.ui \
|
||||||
settingsdialog.ui \
|
settingsdialog.ui \
|
||||||
libraryconfigdialog.ui \
|
libraryconfigdialog.ui \
|
||||||
lastfmconfigdialog.ui \
|
lastfmconfigdialog.ui \
|
||||||
about.ui
|
about.ui \
|
||||||
|
addstreamdialog.ui
|
||||||
RESOURCES += ../data/data.qrc \
|
RESOURCES += ../data/data.qrc \
|
||||||
translations.qrc
|
translations.qrc
|
||||||
OTHER_FILES += ../data/schema.sql \
|
OTHER_FILES += ../data/schema.sql \
|
||||||
|
@ -144,7 +149,9 @@ win32|fedora-win32-cross {
|
||||||
LIBS += -llastfm
|
LIBS += -llastfm
|
||||||
|
|
||||||
# Enable a bunch of warnings
|
# Enable a bunch of warnings
|
||||||
QMAKE_CXXFLAGS += -Wall -Werror=non-virtual-dtor -Woverloaded-virtual
|
QMAKE_CXXFLAGS += -Wall \
|
||||||
|
-Werror=non-virtual-dtor \
|
||||||
|
-Woverloaded-virtual
|
||||||
|
|
||||||
# Other platform specific libraries
|
# Other platform specific libraries
|
||||||
!win32:!fedora-win32-cross {
|
!win32:!fedora-win32-cross {
|
||||||
|
|
Loading…
Reference in New Issue