Add tidal support
This commit is contained in:
parent
26062bd07b
commit
820124f9e1
@ -1,6 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>schema/schema.sql</file>
|
||||
<file>schema/schema-1.sql</file>
|
||||
<file>schema/device-schema.sql</file>
|
||||
<file>style/mainwindow.css</file>
|
||||
<file>style/statusview.css</file>
|
||||
@ -113,6 +114,7 @@
|
||||
<file>icons/128x128/xine.png</file>
|
||||
<file>icons/128x128/zoom-in.png</file>
|
||||
<file>icons/128x128/zoom-out.png</file>
|
||||
<file>icons/128x128/tidal.png</file>
|
||||
<file>icons/64x64/albums.png</file>
|
||||
<file>icons/64x64/alsa.png</file>
|
||||
<file>icons/64x64/application-exit.png</file>
|
||||
@ -201,6 +203,7 @@
|
||||
<file>icons/64x64/xine.png</file>
|
||||
<file>icons/64x64/zoom-in.png</file>
|
||||
<file>icons/64x64/zoom-out.png</file>
|
||||
<file>icons/64x64/tidal.png</file>
|
||||
<file>icons/48x48/albums.png</file>
|
||||
<file>icons/48x48/alsa.png</file>
|
||||
<file>icons/48x48/application-exit.png</file>
|
||||
@ -292,6 +295,7 @@
|
||||
<file>icons/48x48/xine.png</file>
|
||||
<file>icons/48x48/zoom-in.png</file>
|
||||
<file>icons/48x48/zoom-out.png</file>
|
||||
<file>icons/48x48/tidal.png</file>
|
||||
<file>icons/32x32/albums.png</file>
|
||||
<file>icons/32x32/alsa.png</file>
|
||||
<file>icons/32x32/application-exit.png</file>
|
||||
@ -384,6 +388,7 @@
|
||||
<file>icons/32x32/xine.png</file>
|
||||
<file>icons/32x32/zoom-in.png</file>
|
||||
<file>icons/32x32/zoom-out.png</file>
|
||||
<file>icons/32x32/tidal.png</file>
|
||||
<file>icons/22x22/albums.png</file>
|
||||
<file>icons/22x22/alsa.png</file>
|
||||
<file>icons/22x22/application-exit.png</file>
|
||||
@ -476,5 +481,6 @@
|
||||
<file>icons/22x22/xine.png</file>
|
||||
<file>icons/22x22/zoom-in.png</file>
|
||||
<file>icons/22x22/zoom-out.png</file>
|
||||
<file>icons/22x22/tidal.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
BIN
data/icons/128x128/tidal.png
Normal file
BIN
data/icons/128x128/tidal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
data/icons/22x22/tidal.png
Normal file
BIN
data/icons/22x22/tidal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 933 B |
BIN
data/icons/32x32/tidal.png
Normal file
BIN
data/icons/32x32/tidal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
data/icons/48x48/tidal.png
Normal file
BIN
data/icons/48x48/tidal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
data/icons/64x64/tidal.png
Normal file
BIN
data/icons/64x64/tidal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
data/icons/full/tidal.png
Normal file
BIN
data/icons/full/tidal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
3
data/schema/schema-1.sql
Normal file
3
data/schema/schema-1.sql
Normal file
@ -0,0 +1,3 @@
|
||||
ALTER TABLE playlist_items ADD COLUMN internet_service TEXT;
|
||||
|
||||
UPDATE schema_version SET version=1;
|
@ -1,21 +1,21 @@
|
||||
CREATE TABLE schema_version (
|
||||
CREATE TABLE IF NOT EXISTS schema_version (
|
||||
version INTEGER NOT NULL
|
||||
);
|
||||
DELETE FROM schema_version;
|
||||
REPLACE INTO schema_version (version) VALUES (1);
|
||||
|
||||
INSERT INTO schema_version (version) VALUES (0);
|
||||
|
||||
CREATE TABLE directories (
|
||||
CREATE TABLE IF NOT EXISTS directories (
|
||||
path TEXT NOT NULL,
|
||||
subdirs INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE subdirectories (
|
||||
CREATE TABLE IF NOT EXISTS subdirectories (
|
||||
directory_id INTEGER NOT NULL,
|
||||
path TEXT NOT NULL,
|
||||
mtime INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE songs (
|
||||
CREATE TABLE IF NOT EXISTS songs (
|
||||
|
||||
/* Metadata from taglib */
|
||||
|
||||
@ -67,12 +67,12 @@ CREATE TABLE songs (
|
||||
|
||||
effective_albumartist TEXT,
|
||||
effective_originalyear INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
|
||||
cue_path TEXT
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE playlists (
|
||||
CREATE TABLE IF NOT EXISTS playlists (
|
||||
|
||||
name TEXT NOT NULL,
|
||||
last_played INTEGER NOT NULL DEFAULT -1,
|
||||
@ -83,11 +83,12 @@ CREATE TABLE playlists (
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE playlist_items (
|
||||
CREATE TABLE IF NOT EXISTS playlist_items (
|
||||
|
||||
playlist INTEGER NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
collection_id INTEGER,
|
||||
internet_service TEXT,
|
||||
url TEXT,
|
||||
|
||||
/* Metadata from taglib */
|
||||
@ -145,7 +146,7 @@ CREATE TABLE playlist_items (
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE devices (
|
||||
CREATE TABLE IF NOT EXISTS devices (
|
||||
unique_id TEXT NOT NULL,
|
||||
friendly_name TEXT,
|
||||
size INTEGER,
|
||||
@ -155,17 +156,17 @@ CREATE TABLE devices (
|
||||
transcode_format NOT NULL DEFAULT 5
|
||||
);
|
||||
|
||||
CREATE INDEX idx_filename ON songs (filename);
|
||||
CREATE INDEX IF NOT EXISTS idx_filename ON songs (filename);
|
||||
|
||||
CREATE INDEX idx_comp_artist ON songs (compilation_effective, artist);
|
||||
CREATE INDEX IF NOT EXISTS idx_comp_artist ON songs (compilation_effective, artist);
|
||||
|
||||
CREATE INDEX idx_album ON songs (album);
|
||||
CREATE INDEX IF NOT EXISTS idx_album ON songs (album);
|
||||
|
||||
CREATE INDEX idx_title ON songs (title);
|
||||
CREATE INDEX IF NOT EXISTS idx_title ON songs (title);
|
||||
|
||||
CREATE VIEW duplicated_songs as select artist dup_artist, album dup_album, title dup_title from songs as inner_songs where artist != '' and album != '' and title != '' and unavailable = 0 group by artist, album , title having count(*) > 1;
|
||||
CREATE VIEW IF NOT EXISTS duplicated_songs as select artist dup_artist, album dup_album, title dup_title from songs as inner_songs where artist != '' and album != '' and title != '' and unavailable = 0 group by artist, album , title having count(*) > 1;
|
||||
|
||||
CREATE VIRTUAL TABLE songs_fts USING fts3(
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS songs_fts USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
@ -180,7 +181,7 @@ CREATE VIRTUAL TABLE songs_fts USING fts3(
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE playlist_items_fts_ USING fts3(
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS playlist_items_fts_ USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
@ -195,7 +196,7 @@ CREATE VIRTUAL TABLE playlist_items_fts_ USING fts3(
|
||||
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE %allsongstables_fts USING fts3(
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS %allsongstables_fts USING fts3(
|
||||
|
||||
ftstitle,
|
||||
ftsalbum,
|
||||
@ -211,7 +212,7 @@ CREATE VIRTUAL TABLE %allsongstables_fts USING fts3(
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO songs_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
|
||||
INSERT INTO songs_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
|
||||
SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment FROM songs;
|
||||
|
||||
INSERT INTO %allsongstables_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
|
||||
|
@ -207,6 +207,7 @@ set(SOURCES
|
||||
settings/shortcutssettingspage.cpp
|
||||
settings/appearancesettingspage.cpp
|
||||
settings/notificationssettingspage.cpp
|
||||
settings/tidalsettingspage.cpp
|
||||
|
||||
dialogs/about.cpp
|
||||
dialogs/console.cpp
|
||||
@ -246,6 +247,7 @@ set(SOURCES
|
||||
widgets/tracksliderpopup.cpp
|
||||
widgets/tracksliderslider.cpp
|
||||
widgets/widgetfadehelper.cpp
|
||||
widgets/loginstatewidget.cpp
|
||||
|
||||
musicbrainz/acoustidclient.cpp
|
||||
musicbrainz/musicbrainzclient.cpp
|
||||
@ -266,6 +268,16 @@ set(SOURCES
|
||||
device/deviceviewcontainer.cpp
|
||||
device/filesystemdevice.cpp
|
||||
|
||||
internet/internetmodel.cpp
|
||||
internet/internetservice.cpp
|
||||
internet/internetplaylistitem.cpp
|
||||
tidal/tidalservice.cpp
|
||||
tidal/tidalsearch.cpp
|
||||
tidal/tidalsearchview.cpp
|
||||
tidal/tidalsearchmodel.cpp
|
||||
tidal/tidalsearchsortmodel.cpp
|
||||
tidal/tidalsearchitemdelegate.cpp
|
||||
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
@ -356,7 +368,7 @@ set(HEADERS
|
||||
covermanager/amazoncoverprovider.h
|
||||
covermanager/musicbrainzcoverprovider.h
|
||||
covermanager/discogscoverprovider.h
|
||||
|
||||
|
||||
settings/settingsdialog.h
|
||||
settings/settingspage.h
|
||||
settings/behavioursettingspage.h
|
||||
@ -368,7 +380,8 @@ set(HEADERS
|
||||
settings/shortcutssettingspage.h
|
||||
settings/appearancesettingspage.h
|
||||
settings/notificationssettingspage.h
|
||||
|
||||
settings/tidalsettingspage.h
|
||||
|
||||
dialogs/about.h
|
||||
dialogs/errordialog.h
|
||||
dialogs/console.h
|
||||
@ -405,6 +418,7 @@ set(HEADERS
|
||||
widgets/tracksliderpopup.h
|
||||
widgets/tracksliderslider.h
|
||||
widgets/widgetfadehelper.h
|
||||
widgets/loginstatewidget.h
|
||||
|
||||
musicbrainz/acoustidclient.h
|
||||
musicbrainz/musicbrainzclient.h
|
||||
@ -424,6 +438,16 @@ set(HEADERS
|
||||
device/deviceview.h
|
||||
device/filesystemdevice.h
|
||||
|
||||
internet/internetmodel.h
|
||||
internet/internetservice.h
|
||||
internet/internetmimedata.h
|
||||
internet/internetsongmimedata.h
|
||||
|
||||
tidal/tidalservice.h
|
||||
tidal/tidalsearch.h
|
||||
tidal/tidalsearchview.h
|
||||
tidal/tidalsearchmodel.h
|
||||
|
||||
)
|
||||
|
||||
set(UI
|
||||
@ -457,6 +481,7 @@ set(UI
|
||||
settings/shortcutssettingspage.ui
|
||||
settings/appearancesettingspage.ui
|
||||
settings/notificationssettingspage.ui
|
||||
settings/tidalsettingspage.ui
|
||||
|
||||
equalizer/equalizer.ui
|
||||
equalizer/equalizerslider.ui
|
||||
@ -470,12 +495,15 @@ set(UI
|
||||
widgets/trackslider.ui
|
||||
widgets/osdpretty.ui
|
||||
widgets/fileview.ui
|
||||
|
||||
widgets/loginstatewidget.ui
|
||||
|
||||
device/deviceproperties.ui
|
||||
device/deviceviewcontainer.ui
|
||||
|
||||
globalshortcuts/globalshortcutgrabber.ui
|
||||
|
||||
tidal/tidalsearchview.ui
|
||||
|
||||
)
|
||||
|
||||
set(RESOURCES ../data/data.qrc)
|
||||
|
@ -789,7 +789,7 @@ void CollectionBackend::UpdateCompilations() {
|
||||
info.artists.insert(artist);
|
||||
info.directories.insert(filename.left(last_separator));
|
||||
if (compilation_detected) info.has_compilation_detected = true;
|
||||
else info.has_not_compilation_detected = true;
|
||||
else info.has_not_compilation_detected = true;
|
||||
}
|
||||
|
||||
// Now mark the songs that we think are in compilations
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -52,6 +52,9 @@
|
||||
#include "covermanager/discogscoverprovider.h"
|
||||
#include "covermanager/musicbrainzcoverprovider.h"
|
||||
|
||||
#include "internet/internetmodel.h"
|
||||
#include "tidal/tidalsearch.h"
|
||||
|
||||
bool Application::kIsPortable = false;
|
||||
|
||||
class ApplicationImpl {
|
||||
@ -97,7 +100,9 @@ class ApplicationImpl {
|
||||
app->MoveToNewThread(loader);
|
||||
return loader;
|
||||
}),
|
||||
current_art_loader_([=]() { return new CurrentArtLoader(app, app); })
|
||||
current_art_loader_([=]() { return new CurrentArtLoader(app, app); }),
|
||||
internet_model_([=]() { return new InternetModel(app, app); }),
|
||||
tidal_search_([=]() { return new TidalSearch(app, app); })
|
||||
{ }
|
||||
|
||||
Lazy<TagReaderClient> tag_reader_client_;
|
||||
@ -113,6 +118,8 @@ class ApplicationImpl {
|
||||
Lazy<CoverProviders> cover_providers_;
|
||||
Lazy<AlbumCoverLoader> album_cover_loader_;
|
||||
Lazy<CurrentArtLoader> current_art_loader_;
|
||||
Lazy<InternetModel> internet_model_;
|
||||
Lazy<TidalSearch> tidal_search_;
|
||||
|
||||
};
|
||||
|
||||
@ -210,6 +217,13 @@ TaskManager *Application::task_manager() const {
|
||||
}
|
||||
|
||||
EngineDevice *Application::enginedevice() const {
|
||||
//qLog(Debug) << __PRETTY_FUNCTION__;
|
||||
return p_->enginedevice_.get();
|
||||
}
|
||||
|
||||
InternetModel* Application::internet_model() const {
|
||||
return p_->internet_model_.get();
|
||||
}
|
||||
|
||||
TidalSearch* Application::tidal_search() const {
|
||||
return p_->tidal_search_.get();
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef APPLICATION_H_
|
||||
@ -49,6 +49,8 @@ class DeviceManager;
|
||||
class CoverProviders;
|
||||
class AlbumCoverLoader;
|
||||
class CurrentArtLoader;
|
||||
class InternetModel;
|
||||
class TidalSearch;
|
||||
|
||||
class Application : public QObject {
|
||||
Q_OBJECT
|
||||
@ -79,6 +81,9 @@ class Application : public QObject {
|
||||
CollectionBackend *collection_backend() const;
|
||||
CollectionModel *collection_model() const;
|
||||
|
||||
InternetModel *internet_model() const;
|
||||
TidalSearch *tidal_search() const;
|
||||
|
||||
void MoveToNewThread(QObject *object);
|
||||
void MoveToThread(QObject *object, QThread *thread);
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
#include "scopedtransaction.h"
|
||||
|
||||
const char *Database::kDatabaseFilename = "strawberry.db";
|
||||
const int Database::kSchemaVersion = 0;
|
||||
const int Database::kSchemaVersion = 1;
|
||||
const char *Database::kMagicAllSongsTables = "%allsongstables";
|
||||
|
||||
int Database::sNextConnectionId = 1;
|
||||
|
@ -126,6 +126,8 @@
|
||||
#include "settings/playlistsettingspage.h"
|
||||
#include "settings/settingsdialog.h"
|
||||
|
||||
#include "tidal/tidalsearchview.h"
|
||||
|
||||
#if defined(HAVE_GSTREAMER) && defined(HAVE_CHROMAPRINT)
|
||||
# include "musicbrainz/tagfetcher.h"
|
||||
#endif
|
||||
@ -186,6 +188,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
manager->SetPlaylistManager(app->playlist_manager());
|
||||
return manager;
|
||||
}),
|
||||
tidal_search_view_(new TidalSearchView(app_, this)),
|
||||
playlist_menu_(new QMenu(this)),
|
||||
playlist_add_to_another_(nullptr),
|
||||
playlistitem_actions_separator_(nullptr),
|
||||
@ -218,7 +221,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
ui_->volume->setValue(volume);
|
||||
VolumeChanged(volume);
|
||||
|
||||
// Initialise the global search widget
|
||||
// Initialise the tidal search widget
|
||||
StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker());
|
||||
|
||||
// Add tabs to the fancy tab widget
|
||||
@ -227,6 +230,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
ui_->tabs->addTab(file_view_, IconLoader::Load("document-open"), tr("Files"));
|
||||
ui_->tabs->addTab(playlist_list_, IconLoader::Load("view-media-playlist"), tr("Playlists"));
|
||||
ui_->tabs->addTab(device_view_, IconLoader::Load("device"), tr("Devices"));
|
||||
ui_->tabs->addTab(tidal_search_view_, IconLoader::Load("tidal"), tr("Tidal", "Tidal"));
|
||||
//ui_->tabs->AddSpacer();
|
||||
|
||||
// Add the now playing widget to the fancy tab widget
|
||||
@ -475,6 +479,9 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
collection_view_->filter()->AddMenuAction(separator);
|
||||
collection_view_->filter()->AddMenuAction(collection_config_action);
|
||||
|
||||
// Tidal
|
||||
connect(tidal_search_view_, SIGNAL(AddToPlaylist(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
|
||||
// Playlist menu
|
||||
playlist_play_pause_ = playlist_menu_->addAction(tr("Play"), this, SLOT(PlaylistPlay()));
|
||||
playlist_menu_->addAction(ui_->action_stop);
|
||||
@ -657,6 +664,12 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
|
||||
ReloadSettings();
|
||||
|
||||
// Tidal search shortcut
|
||||
QAction *tidal_search_action = new QAction(this);
|
||||
tidal_search_action->setShortcuts(QList<QKeySequence>() << QKeySequence("Ctrl+F") << QKeySequence("Ctrl+L"));
|
||||
addAction(tidal_search_action);
|
||||
connect(tidal_search_action, SIGNAL(triggered()), SLOT(FocusTidalSearchField()));
|
||||
|
||||
// Reload pretty OSD to avoid issues with fonts
|
||||
osd_->ReloadPrettyOSDSettings();
|
||||
|
||||
@ -745,6 +758,7 @@ void MainWindow::ReloadAllSettings() {
|
||||
osd_->ReloadSettings();
|
||||
collection_view_->ReloadSettings();
|
||||
ui_->playlist->view()->ReloadSettings();
|
||||
tidal_search_view_->ReloadSettings();
|
||||
|
||||
}
|
||||
|
||||
@ -787,7 +801,7 @@ void MainWindow::MediaPaused() {
|
||||
}
|
||||
|
||||
void MainWindow::MediaPlaying() {
|
||||
|
||||
|
||||
ui_->action_stop->setEnabled(true);
|
||||
ui_->action_stop_after_this_track->setEnabled(true);
|
||||
ui_->action_play_pause->setIcon(IconLoader::Load("media-pause"));
|
||||
@ -1789,7 +1803,7 @@ void MainWindow::EditFileTags(const QList<QUrl> &urls) {
|
||||
Song song;
|
||||
song.set_url(url);
|
||||
song.set_valid(true);
|
||||
song.set_filetype(Song::Type_Mpeg);
|
||||
song.set_filetype(Song::Type_MPEG);
|
||||
songs << song;
|
||||
}
|
||||
|
||||
@ -2261,3 +2275,37 @@ void MainWindow::keyPressEvent(QKeyEvent *event) {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::FocusTidalSearchField() {
|
||||
ui_->tabs->setCurrentWidget(tidal_search_view_);
|
||||
tidal_search_view_->FocusSearchField();
|
||||
}
|
||||
|
||||
void MainWindow::DoTidalSearch(const QString& query) {
|
||||
FocusTidalSearchField();
|
||||
tidal_search_view_->StartSearch(query);
|
||||
}
|
||||
|
||||
void MainWindow::SearchForArtist() {
|
||||
|
||||
PlaylistItemPtr item(app_->playlist_manager()->current()->item_at(playlist_menu_index_.row()));
|
||||
Song song = item->Metadata();
|
||||
if (!song.albumartist().isEmpty()) {
|
||||
DoTidalSearch(song.albumartist().simplified());
|
||||
}
|
||||
else if (!song.artist().isEmpty()) {
|
||||
DoTidalSearch(song.artist().simplified());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::SearchForAlbum() {
|
||||
|
||||
PlaylistItemPtr item(app_->playlist_manager()->current()->item_at(playlist_menu_index_.row()));
|
||||
Song song = item->Metadata();
|
||||
if (!song.album().isEmpty()) {
|
||||
DoTidalSearch(song.album().simplified());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -84,6 +84,7 @@ class TranscodeDialog;
|
||||
#endif
|
||||
class Ui_MainWindow;
|
||||
class Windows7ThumbBar;
|
||||
class TidalSearchView;
|
||||
|
||||
class MainWindow : public QMainWindow, public PlatformInterface {
|
||||
Q_OBJECT
|
||||
@ -263,6 +264,11 @@ signals:
|
||||
|
||||
void ShowConsole();
|
||||
|
||||
void FocusTidalSearchField();
|
||||
void DoTidalSearch(const QString& query);
|
||||
void SearchForArtist();
|
||||
void SearchForAlbum();
|
||||
|
||||
private:
|
||||
void ConnectStatusView(StatusView *statusview);
|
||||
|
||||
@ -313,6 +319,8 @@ signals:
|
||||
PlaylistItemList autocomplete_tag_items_;
|
||||
#endif
|
||||
|
||||
TidalSearchView *tidal_search_view_;
|
||||
|
||||
QAction *collection_show_all_;
|
||||
QAction *collection_show_duplicates_;
|
||||
QAction *collection_show_untagged_;
|
||||
@ -335,6 +343,9 @@ signals:
|
||||
QAction *playlist_add_to_another_;
|
||||
QList<QAction*> playlistitem_actions_;
|
||||
QAction *playlistitem_actions_separator_;
|
||||
QAction *search_for_artist_;
|
||||
QAction *search_for_album_;
|
||||
|
||||
QModelIndex playlist_menu_index_;
|
||||
|
||||
QSortFilterProxyModel *collection_sort_model_;
|
||||
|
@ -60,6 +60,8 @@
|
||||
# include "dbus/metatypes.h"
|
||||
#endif
|
||||
|
||||
#include "tidal/tidalsearch.h"
|
||||
|
||||
void RegisterMetaTypes() {
|
||||
|
||||
qRegisterMetaType<const char*>("const char*");
|
||||
@ -113,4 +115,7 @@ void RegisterMetaTypes() {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
qRegisterMetaType<TidalSearch::ResultList>("TidalSearch::ResultList");
|
||||
qRegisterMetaType<TidalSearch::Result>("TidalSearch::Result");
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MIMEDATA_H
|
||||
@ -52,6 +52,9 @@ class MimeData : public QMimeData {
|
||||
|
||||
// If this is set then the items are added to the queue after being inserted.
|
||||
bool enqueue_now_;
|
||||
|
||||
// If this is set then the items are added to the beginning of the queue after being inserted.
|
||||
bool enqueue_next_now_;
|
||||
|
||||
// If this is set then the items are inserted into a newly created playlist.
|
||||
bool open_in_new_playlist_;
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -393,7 +393,7 @@ bool Mpris2::CanPause() const {
|
||||
bool Mpris2::CanSeek() const { return CanSeek(app_->player()->GetState()); }
|
||||
|
||||
bool Mpris2::CanSeek(Engine::State state) const {
|
||||
return app_->player()->GetCurrentItem() && state != Engine::Empty;
|
||||
return app_->player()->GetCurrentItem() && state != Engine::Empty && !app_->player()->GetCurrentItem()->Metadata().is_stream();
|
||||
}
|
||||
|
||||
bool Mpris2::CanControl() const { return true; }
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@ -287,9 +287,10 @@ uint Song::mtime() const { return d->mtime_; }
|
||||
uint Song::ctime() const { return d->ctime_; }
|
||||
int Song::filesize() const { return d->filesize_; }
|
||||
Song::FileType Song::filetype() const { return d->filetype_; }
|
||||
bool Song::is_cdda() const { return d->filetype_ == Type_Cdda; }
|
||||
bool Song::is_stream() const { return d->filetype_ == Type_Stream; }
|
||||
bool Song::is_cdda() const { return d->filetype_ == Type_CDDA; }
|
||||
bool Song::is_collection_song() const {
|
||||
return !is_cdda() && id() != -1;
|
||||
return !is_cdda() && !is_stream() && id() != -1;
|
||||
}
|
||||
const QString &Song::art_automatic() const { return d->art_automatic_; }
|
||||
const QString &Song::art_manual() const { return d->art_manual_; }
|
||||
@ -329,10 +330,10 @@ void Song::set_bitdepth(int v) { d->bitdepth_ = v; }
|
||||
void Song::set_directory_id(int v) { d->directory_id_ = v; }
|
||||
void Song::set_url(const QUrl &v) {
|
||||
if (Application::kIsPortable) {
|
||||
QUrl base =
|
||||
QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/");
|
||||
QUrl base = QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/");
|
||||
d->url_ = base.resolved(v);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
d->url_ = v;
|
||||
}
|
||||
}
|
||||
@ -364,36 +365,35 @@ QString Song::JoinSpec(const QString &table) {
|
||||
QString Song::TextForFiletype(FileType type) {
|
||||
|
||||
switch (type) {
|
||||
case Song::Type_Wav: return QObject::tr("Wav");
|
||||
case Song::Type_Flac: return QObject::tr("FLAC");
|
||||
case Song::Type_WAV: return QObject::tr("Wav");
|
||||
case Song::Type_FLAC: return QObject::tr("FLAC");
|
||||
case Song::Type_WavPack: return QObject::tr("WavPack");
|
||||
case Song::Type_OggFlac: return QObject::tr("Ogg FLAC");
|
||||
case Song::Type_OggVorbis: return QObject::tr("Ogg Vorbis");
|
||||
case Song::Type_OggOpus: return QObject::tr("Ogg Opus");
|
||||
case Song::Type_OggSpeex: return QObject::tr("Ogg Speex");
|
||||
case Song::Type_Mpeg: return QObject::tr("MP3");
|
||||
case Song::Type_Mp4: return QObject::tr("MP4 AAC");
|
||||
case Song::Type_Asf: return QObject::tr("Windows Media audio");
|
||||
case Song::Type_Aiff: return QObject::tr("AIFF");
|
||||
case Song::Type_Mpc: return QObject::tr("MPC");
|
||||
case Song::Type_MPEG: return QObject::tr("MP3");
|
||||
case Song::Type_MP4: return QObject::tr("MP4 AAC");
|
||||
case Song::Type_ASF: return QObject::tr("Windows Media audio");
|
||||
case Song::Type_AIFF: return QObject::tr("AIFF");
|
||||
case Song::Type_MPC: return QObject::tr("MPC");
|
||||
case Song::Type_TrueAudio: return QObject::tr("TrueAudio");
|
||||
case Song::Type_Cdda: return QObject::tr("CDDA");
|
||||
|
||||
case Song::Type_CDDA: return QObject::tr("CDDA");
|
||||
case Song::Type_Unknown:
|
||||
default:
|
||||
return QObject::tr("Unknown");
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Song::IsFileLossless() const {
|
||||
switch (filetype()) {
|
||||
case Song::Type_Wav:
|
||||
case Song::Type_Flac:
|
||||
case Song::Type_WAV:
|
||||
case Song::Type_FLAC:
|
||||
case Song::Type_OggFlac:
|
||||
case Song::Type_WavPack:
|
||||
case Song::Type_Aiff:
|
||||
case Song::Type_AIFF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -628,7 +628,7 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
|
||||
else if (Song::kColumns.value(i) == "unavailable") {
|
||||
d->unavailable_ = q.value(x).toBool();
|
||||
}
|
||||
|
||||
|
||||
else if (Song::kColumns.value(i) == "playcount") {
|
||||
d->playcount_ = q.value(x).isNull() ? 0 : q.value(x).toInt();
|
||||
}
|
||||
@ -650,7 +650,7 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
|
||||
}
|
||||
else if (Song::kColumns.value(i) == "compilation_effective") {
|
||||
}
|
||||
|
||||
|
||||
else if (Song::kColumns.value(i) == "art_automatic") {
|
||||
d->art_automatic_ = q.value(x).toString();
|
||||
}
|
||||
@ -662,11 +662,11 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
|
||||
}
|
||||
else if (Song::kColumns.value(i) == "effective_originalyear") {
|
||||
}
|
||||
|
||||
|
||||
else if (Song::kColumns.value(i) == "cue_path") {
|
||||
d->cue_path_ = tostr(x);
|
||||
}
|
||||
|
||||
|
||||
else {
|
||||
qLog(Error) << "Forgot to handle" << Song::kColumns.value(i);
|
||||
}
|
||||
@ -752,7 +752,7 @@ void Song::InitFromItdb(const Itdb_Track *track, const QString &prefix) {
|
||||
}
|
||||
d->basefilename_ = QFileInfo(filename).fileName();
|
||||
|
||||
d->filetype_ = track->type2 ? Type_Mpeg : Type_Mp4;
|
||||
d->filetype_ = track->type2 ? Type_MPEG : Type_MP4;
|
||||
d->filesize_ = track->size;
|
||||
d->mtime_ = track->time_modified;
|
||||
d->ctime_ = track->time_added;
|
||||
@ -785,7 +785,7 @@ void Song::ToItdb(Itdb_Track *track) const {
|
||||
//track->bithdepth = d->bithdepth_;
|
||||
|
||||
track->type1 = 0;
|
||||
track->type2 = d->filetype_ == Type_Mp4 ? 0 : 1;
|
||||
track->type2 = d->filetype_ == Type_MP4 ? 0 : 1;
|
||||
track->mediatype = 1; // Audio
|
||||
track->size = d->filesize_;
|
||||
track->time_modified = d->mtime_;
|
||||
@ -825,15 +825,15 @@ void Song::InitFromMTP(const LIBMTP_track_t *track, const QString &host) {
|
||||
d->playcount_ = track->usecount;
|
||||
|
||||
switch (track->filetype) {
|
||||
case LIBMTP_FILETYPE_WAV: d->filetype_ = Type_Wav; break;
|
||||
case LIBMTP_FILETYPE_MP3: d->filetype_ = Type_Mpeg; break;
|
||||
case LIBMTP_FILETYPE_WMA: d->filetype_ = Type_Asf; break;
|
||||
case LIBMTP_FILETYPE_WAV: d->filetype_ = Type_WAV; break;
|
||||
case LIBMTP_FILETYPE_MP3: d->filetype_ = Type_MPEG; break;
|
||||
case LIBMTP_FILETYPE_WMA: d->filetype_ = Type_ASF; break;
|
||||
case LIBMTP_FILETYPE_OGG: d->filetype_ = Type_OggVorbis; break;
|
||||
case LIBMTP_FILETYPE_MP4: d->filetype_ = Type_Mp4; break;
|
||||
case LIBMTP_FILETYPE_AAC: d->filetype_ = Type_Mp4; break;
|
||||
case LIBMTP_FILETYPE_MP4: d->filetype_ = Type_MP4; break;
|
||||
case LIBMTP_FILETYPE_AAC: d->filetype_ = Type_MP4; break;
|
||||
case LIBMTP_FILETYPE_FLAC: d->filetype_ = Type_OggFlac; break;
|
||||
case LIBMTP_FILETYPE_MP2: d->filetype_ = Type_Mpeg; break;
|
||||
case LIBMTP_FILETYPE_M4A: d->filetype_ = Type_Mp4; break;
|
||||
case LIBMTP_FILETYPE_MP2: d->filetype_ = Type_MPEG; break;
|
||||
case LIBMTP_FILETYPE_M4A: d->filetype_ = Type_MP4; break;
|
||||
default: d->filetype_ = Type_Unknown; break;
|
||||
}
|
||||
|
||||
@ -868,14 +868,14 @@ void Song::ToMTP(LIBMTP_track_t *track) const {
|
||||
track->usecount = d->playcount_;
|
||||
|
||||
switch (d->filetype_) {
|
||||
case Type_Asf: track->filetype = LIBMTP_FILETYPE_ASF; break;
|
||||
case Type_Mp4: track->filetype = LIBMTP_FILETYPE_MP4; break;
|
||||
case Type_Mpeg: track->filetype = LIBMTP_FILETYPE_MP3; break;
|
||||
case Type_Flac:
|
||||
case Type_ASF: track->filetype = LIBMTP_FILETYPE_ASF; break;
|
||||
case Type_MP4: track->filetype = LIBMTP_FILETYPE_MP4; break;
|
||||
case Type_MPEG: track->filetype = LIBMTP_FILETYPE_MP3; break;
|
||||
case Type_FLAC:
|
||||
case Type_OggFlac: track->filetype = LIBMTP_FILETYPE_FLAC; break;
|
||||
case Type_OggSpeex:
|
||||
case Type_OggVorbis: track->filetype = LIBMTP_FILETYPE_OGG; break;
|
||||
case Type_Wav: track->filetype = LIBMTP_FILETYPE_WAV; break;
|
||||
case Type_WAV: track->filetype = LIBMTP_FILETYPE_WAV; break;
|
||||
default: track->filetype = LIBMTP_FILETYPE_UNDEF_AUDIO; break;
|
||||
}
|
||||
|
||||
@ -927,7 +927,7 @@ void Song::BindToQuery(QSqlQuery *query) const {
|
||||
query->bindValue(":performer", strval(d->performer_));
|
||||
query->bindValue(":grouping", strval(d->grouping_));
|
||||
query->bindValue(":comment", strval(d->comment_));
|
||||
|
||||
|
||||
query->bindValue(":beginning", d->beginning_);
|
||||
query->bindValue(":length", intval(length_nanosec()));
|
||||
|
||||
@ -1037,7 +1037,8 @@ QString Song::TitleWithCompilationArtist() const {
|
||||
}
|
||||
|
||||
QString Song::SampleRateBitDepthToText() const {
|
||||
|
||||
|
||||
if (d->samplerate_ == -1) return QString("");
|
||||
if (d->bitdepth_ == -1) return QString("%1 hz").arg(d->samplerate_);
|
||||
|
||||
return QString("%1 hz / %2 bit").arg(d->samplerate_).arg(d->bitdepth_);
|
||||
@ -1071,7 +1072,7 @@ bool Song::IsMetadataEqual(const Song &other) const {
|
||||
}
|
||||
|
||||
bool Song::IsEditable() const {
|
||||
return d->valid_ && !d->url_.isEmpty() && d->filetype_ != Type_Unknown && !has_cue();
|
||||
return d->valid_ && !d->url_.isEmpty() && !is_stream() && d->filetype_ != Type_Unknown && !has_cue();
|
||||
}
|
||||
|
||||
bool Song::operator==(const Song &other) const {
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SONG_H
|
||||
@ -58,12 +58,6 @@ struct _Itdb_Track;
|
||||
struct LIBMTP_track_struct;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
namespace lastfm {
|
||||
class Track;
|
||||
}
|
||||
#endif
|
||||
|
||||
class SqlRow;
|
||||
|
||||
class Song {
|
||||
@ -95,20 +89,20 @@ class Song {
|
||||
// If a new lossless file is added, also add it to IsFileLossless().
|
||||
enum FileType {
|
||||
Type_Unknown = 0,
|
||||
Type_Wav = 1,
|
||||
Type_Flac = 2,
|
||||
Type_WAV = 1,
|
||||
Type_FLAC = 2,
|
||||
Type_WavPack = 3,
|
||||
Type_OggFlac = 4,
|
||||
Type_OggVorbis = 5,
|
||||
Type_OggOpus = 6,
|
||||
Type_OggSpeex = 7,
|
||||
Type_Mpeg = 8,
|
||||
Type_Mp4 = 9,
|
||||
Type_Asf = 10,
|
||||
Type_Aiff = 11,
|
||||
Type_Mpc = 12,
|
||||
Type_MPEG = 8,
|
||||
Type_MP4 = 9,
|
||||
Type_ASF = 10,
|
||||
Type_AIFF = 11,
|
||||
Type_MPC = 12,
|
||||
Type_TrueAudio = 13,
|
||||
Type_Cdda = 90,
|
||||
Type_CDDA = 90,
|
||||
Type_Stream = 91,
|
||||
};
|
||||
|
||||
@ -127,9 +121,6 @@ class Song {
|
||||
void InitFromQuery(const SqlRow &query, bool reliable_metadata, int col = 0);
|
||||
void InitFromFilePartial(const QString &filename); // Just store the filename: incomplete but fast
|
||||
void InitArtManual(); // Check if there is already a art in the cache and store the filename in art_manual
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
void InitFromLastFM(const lastfm::Track &track);
|
||||
#endif
|
||||
|
||||
void MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle);
|
||||
|
||||
@ -152,9 +143,6 @@ class Song {
|
||||
// Save
|
||||
void BindToQuery(QSqlQuery *query) const;
|
||||
void BindToFtsQuery(QSqlQuery *query) const;
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
void ToLastFM(lastfm::Track *track, bool prefer_album_artist) const;
|
||||
#endif
|
||||
void ToXesam(QVariantMap *map) const;
|
||||
void ToProtobuf(pb::tagreader::SongMetadata *pb) const;
|
||||
|
||||
@ -210,6 +198,7 @@ class Song {
|
||||
const QString &effective_albumartist() const;
|
||||
|
||||
bool is_collection_song() const;
|
||||
bool is_stream() const;
|
||||
bool is_cdda() const;
|
||||
|
||||
// Playlist views are special because you don't want to fill in album artists automatically for compilations, but you do for normal albums:
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -51,6 +51,8 @@
|
||||
#include "song.h"
|
||||
#include "songloader.h"
|
||||
#include "tagreaderclient.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectionquery.h"
|
||||
#include "collection/sqlrow.h"
|
||||
@ -78,6 +80,7 @@ SongLoader::SongLoader(CollectionBackendInterface *collection, const Player *pla
|
||||
parser_(nullptr),
|
||||
collection_(collection),
|
||||
player_(player) {
|
||||
|
||||
if (sRawUriSchemes.isEmpty()) {
|
||||
sRawUriSchemes << "udp"
|
||||
<< "mms"
|
||||
@ -97,7 +100,7 @@ SongLoader::SongLoader(CollectionBackendInterface *collection, const Player *pla
|
||||
}
|
||||
|
||||
SongLoader::~SongLoader() {
|
||||
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
if (pipeline_) {
|
||||
state_ = Finished;
|
||||
@ -121,24 +124,29 @@ SongLoader::Result SongLoader::Load(const QUrl &url) {
|
||||
return Success;
|
||||
}
|
||||
|
||||
if (player_->engine()->type() == Engine::GStreamer) {
|
||||
#ifdef HAVE_GSTREAMER
|
||||
preload_func_ = std::bind(&SongLoader::LoadRemote, this);
|
||||
preload_func_ = std::bind(&SongLoader::LoadRemote, this);
|
||||
return BlockingLoadRequired;
|
||||
#else
|
||||
return Error;
|
||||
#endif
|
||||
}
|
||||
|
||||
return BlockingLoadRequired;
|
||||
return Success;
|
||||
|
||||
}
|
||||
|
||||
void SongLoader::LoadFilenamesBlocking() {
|
||||
|
||||
|
||||
if (preload_func_) {
|
||||
preload_func_();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) {
|
||||
|
||||
|
||||
qLog(Debug) << "Fast Loading local file" << filename;
|
||||
// First check to see if it's a directory - if so we can load all the songs inside right away.
|
||||
if (QFileInfo(filename).isDir()) {
|
||||
@ -149,7 +157,7 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) {
|
||||
song.InitFromFilePartial(filename);
|
||||
if (song.is_valid()) songs_ << song;
|
||||
return Success;
|
||||
|
||||
|
||||
}
|
||||
|
||||
SongLoader::Result SongLoader::LoadAudioCD() {
|
||||
@ -208,6 +216,7 @@ SongLoader::Result SongLoader::LoadLocal(const QString &filename) {
|
||||
// It's not in the database, load it asynchronously.
|
||||
preload_func_ = std::bind(&SongLoader::LoadLocalAsync, this, filename);
|
||||
return BlockingLoadRequired;
|
||||
|
||||
}
|
||||
|
||||
void SongLoader::LoadLocalAsync(const QString &filename) {
|
||||
@ -253,6 +262,7 @@ void SongLoader::LoadLocalAsync(const QString &filename) {
|
||||
Song song;
|
||||
song.InitFromFilePartial(filename);
|
||||
if (song.is_valid()) songs_ << song;
|
||||
|
||||
}
|
||||
|
||||
void SongLoader::LoadMetadataBlocking() {
|
||||
@ -274,7 +284,8 @@ void SongLoader::EffectiveSongLoad(Song *song) {
|
||||
Song collection_song = collection_->GetSongByUrl(song->url());
|
||||
if (collection_song.is_valid()) {
|
||||
*song = collection_song;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// it's a normal media file
|
||||
QString filename = song->url().toLocalFile();
|
||||
TagReaderClient::Instance()->ReadFileBlocking(filename, song);
|
||||
@ -318,7 +329,15 @@ void SongLoader::LoadLocalDirectory(const QString &filename) {
|
||||
// so if the user has the "Start playing when adding to playlist" preference behaviour set,
|
||||
// it can enjoy the first song being played (seek it, have moodbar, etc.)
|
||||
if (!songs_.isEmpty()) EffectiveSongLoad(&(*songs_.begin()));
|
||||
}
|
||||
|
||||
void SongLoader::AddAsRawStream() {
|
||||
Song song;
|
||||
song.set_valid(true);
|
||||
song.set_filetype(Song::Type_Stream);
|
||||
song.set_url(url_);
|
||||
song.set_title(url_.toString());
|
||||
songs_ << song;
|
||||
}
|
||||
|
||||
void SongLoader::Timeout() {
|
||||
@ -348,10 +367,10 @@ void SongLoader::StopTypefind() {
|
||||
|
||||
}
|
||||
else if (success_) {
|
||||
//qLog(Debug) << "Loading" << url_ << "as raw stream";
|
||||
qLog(Debug) << "Loading" << url_ << "as raw stream";
|
||||
|
||||
// It wasn't a playlist - just put the URL in as a stream
|
||||
//AddAsRawStream();
|
||||
AddAsRawStream();
|
||||
}
|
||||
|
||||
emit LoadRemoteFinished();
|
||||
@ -413,7 +432,7 @@ void SongLoader::LoadRemote() {
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
void SongLoader::TypeFound(GstElement *, uint, GstCaps *caps, void *self) {
|
||||
|
||||
|
||||
SongLoader *instance = static_cast<SongLoader*>(self);
|
||||
|
||||
if (instance->state_ != WaitingForType) return;
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SONGLOADER_H
|
||||