diff --git a/CMakeLists.txt b/CMakeLists.txt index ebb793d4f..06665bb9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -267,6 +267,7 @@ SET( CANTATA_UIS find_package( Cdparanoia ) if (CDPARANOIA_FOUND) find_package( CDDB ) + find_package( MusicBrainz5 ) endif (CDPARANOIA_FOUND) if (ENABLE_TAGLIB) @@ -488,13 +489,21 @@ if (TAGLIB_FOUND) SET( CANTATA_SRCS ${CANTATA_SRCS} devices/mtpdevice.cpp ) SET( CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/mtpdevice.h ) endif (MTP_FOUND) - if (CDDB_FOUND) + if (CDDB_FOUND OR MUSICBRAINZ5_FOUND) + if (CDDB_FOUND) + SET( CANTATA_SRCS ${CANTATA_SRCS} devices/cddb.cpp ) + SET( CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/cddb.h ) + endif (CDDB_FOUND) + if (MUSICBRAINZ5_FOUND) + SET( CANTATA_SRCS ${CANTATA_SRCS} devices/musicbrainz.cpp ) + SET( CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/musicbrainz.h ) + endif (MUSICBRAINZ5_FOUND) SET( CANTATA_SRCS ${CANTATA_SRCS} devices/audiocddevice.cpp devices/cddb.cpp devices/cddbselectiondialog.cpp devices/cdparanoia.cpp devices/audiocdsettings.cpp devices/extractjob.cpp devices/albumdetailsdialog.cpp) SET( CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/audiocddevice.h devices/cddb.h devices/extractjob.h - devices/albumdetailsdialog.h) + devices/albumdetailsdialog.h devices/audiocdsettings.h) SET( CANTATA_UIS ${CANTATA_UIS} devices/albumdetails.ui devices/audiocdsettings.ui) - endif (CDDB_FOUND) + endif (CDDB_FOUND OR MUSICBRAINZ5_FOUND) SET( CANTATA_SRCS ${CANTATA_SRCS} devices/devicespage.cpp devices/filejob.cpp devices/device.cpp devices/fsdevice.cpp devices/umsdevice.cpp @@ -595,10 +604,18 @@ if (NOT WIN32) include_directories(${MTP_INCLUDE_DIR}) endif (MTP_FOUND) - if (CDDB_FOUND) - TARGET_LINK_LIBRARIES(cantata ${CDDB_LIBS} ${CDPARANOIA_LIBRARIES}) - include_directories(${CDDB_INCLUDE_DIR} ${CDPARANOIA_INCLUDE_DIR}) - endif (CDDB_FOUND) + if (CDDB_FOUND OR MUSICBRAINZ5_FOUND) + TARGET_LINK_LIBRARIES(cantata ${CDPARANOIA_LIBRARIES}) + include_directories(${CDPARANOIA_INCLUDE_DIR}) + if (CDDB_FOUND) + TARGET_LINK_LIBRARIES(cantata ${CDDB_LIBS}) + include_directories(${CDDB_INCLUDE_DIR}) + endif (CDDB_FOUND) + if (MUSICBRAINZ5_FOUND) + TARGET_LINK_LIBRARIES(cantata ${MUSICBRAINZ5_LIBRARIES}) + include_directories(${MUSICBRAINZ5_INCLUDE_DIR}) + endif (MUSICBRAINZ5_FOUND) + endif (CDDB_FOUND OR MUSICBRAINZ5_FOUND) endif (NOT WIN32) add_subdirectory(qtiocompressor) @@ -677,7 +694,7 @@ if (TAGLIB_FOUND) message(" - MPD HTTP stream playback") endif (PHONON_FOUND) endif (ENABLE_REMOTE_DEVICES OR PHONON_FOUND) - if (NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT CDDB_FOUND OR (NOT FFMPEG_FOUND AND NOT MPG123_FOUND) OR NOT PHONON_FOUND OR NOT ENABLE_REMOTE_DEVICES) + if (NOT TAGLIB_FOUND OR NOT MTP_FOUND OR (NOT CDDB_FOUND AND NOT MUSICBRAINZ5_FOUND) OR (NOT FFMPEG_FOUND AND NOT MPG123_FOUND) OR NOT PHONON_FOUND OR NOT ENABLE_REMOTE_DEVICES) message(" Disabled features:") if (NOT PHONON_FOUND) message(" - MPD HTTP stream playback (phonon required)") @@ -694,16 +711,16 @@ if (TAGLIB_FOUND) if (NOT MTP_FOUND AND NOT WIN32) message(" - MTP device sync (taglib and libmtp required)") endif (NOT MTP_FOUND AND NOT WIN32) - if (NOT CDDB_FOUND AND NOT WIN32) - message(" - AudioCD (libcdparanoia and libcddb required)") - endif (NOT CDDB_FOUND AND NOT WIN32) + if (NOT CDDB_FOUND AND NOT MUSICBRAINZ5_FOUND AND NOT WIN32) + message(" - AudioCD (libcdparanoia and libcddb/libmusicbrainz5 required)") + endif (NOT CDDB_FOUND AND NOT MUSICBRAINZ5_FOUND AND NOT WIN32) if (NOT ENABLE_REMOTE_DEVICES) message(" - Remote device sync (EXPERIMENTAL)") endif (NOT ENABLE_REMOTE_DEVICES) if(NOT FFMPEG_FOUND AND NOT MPG123_FOUND) message(" - ReplayGain calculation (taglib, and ffmpeg and/or mpg123 required)") endif(NOT FFMPEG_FOUND AND NOT MPG123_FOUND) - endif (NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT CDDB_FOUND OR (NOT FFMPEG_FOUND AND NOT MPG123_FOUND) OR NOT PHONON_FOUND OR NOT ENABLE_REMOTE_DEVICES) + endif (NOT TAGLIB_FOUND OR NOT MTP_FOUND OR (NOT CDDB_FOUND AND NOT MUSICBRAINZ5_FOUND) OR (NOT FFMPEG_FOUND AND NOT MPG123_FOUND) OR NOT PHONON_FOUND OR NOT ENABLE_REMOTE_DEVICES) endif (TAGLIB_FOUND) if (NOT CMAKE_SYSTEM_NAME MATCHES Linux) diff --git a/ChangeLog b/ChangeLog index 82a39196d..544b73e78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -129,6 +129,7 @@ 76. Update copy of Solid to KDE4.10.1 - adds Udisks2 support. 77. Reduce memory usage - by having only Device/OnlineService derive from QObject, as opposed to every artist/album/song! + 0.9.2 ----- 1. (Qt-Only) Dont show clear button for read-only line-edits. diff --git a/README b/README index 3a5a94465..2797b66c2 100644 --- a/README +++ b/README @@ -378,6 +378,7 @@ Cantata contains code/icons from: Musique - Copied code for Gtk theme detection Ayatana Qt - Overlay scrollbar code copied/modified from https://launchpad.net/ayatana-scrollbar-qt Asunder - CDDB code + libkcddb - MusicBrainz code libebur128 - https://github.com/jiixyj/libebur128 (Replay gain calculation) wikipedia icon - Social Media Mini by Paul Robert Lloyd License: Commons diff --git a/cmake/COPYING-CMAKE-SCRIPTS b/cmake/COPYING-CMAKE-SCRIPTS new file mode 100644 index 000000000..d99eefb58 --- /dev/null +++ b/cmake/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,23 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/cmake/FindMusicBrainz5.cmake b/cmake/FindMusicBrainz5.cmake new file mode 100644 index 000000000..6ae7c935a --- /dev/null +++ b/cmake/FindMusicBrainz5.cmake @@ -0,0 +1,26 @@ +# Module to find the musicbrainz-4 library +# +# It defines +# MUSICBRAINZ5_INCLUDE_DIR - the include dir +# MUSICBRAINZ5_LIBRARIES - the required libraries +# MUSICBRAINZ5_FOUND - true if both of the above have been found + +# Copyright (c) 2006,2007 Laurent Montel, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +if(MUSICBRAINZ5_INCLUDE_DIR AND MUSICBRAINZ5_LIBRARIES) + set(MUSICBRAINZ5_FIND_QUIETLY TRUE) +endif(MUSICBRAINZ5_INCLUDE_DIR AND MUSICBRAINZ5_LIBRARIES) + +FIND_PATH(MUSICBRAINZ5_INCLUDE_DIR musicbrainz5/Disc.h) + +FIND_LIBRARY( MUSICBRAINZ5_LIBRARIES NAMES musicbrainz5) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( MUSICBRAINZ5 DEFAULT_MSG + MUSICBRAINZ5_INCLUDE_DIR MUSICBRAINZ5_LIBRARIES) + +MARK_AS_ADVANCED(MUSICBRAINZ5_INCLUDE_DIR MUSICBRAINZ5_LIBRARIES) + diff --git a/config.h.cmake b/config.h.cmake index ce095d7c8..99e00a125 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -26,6 +26,7 @@ #cmakedefine FFMPEG_FOUND 1 #cmakedefine MPG123_FOUND 1 #cmakedefine CDDB_FOUND 1 +#cmakedefine MUSICBRAINZ5_FOUND 1 #cmakedefine USE_SPEEX_RESAMPLER 1 #cmakedefine ENABLE_REPLAYGAIN_SUPPORT 1 #cmakedefine ENABLE_REMOTE_DEVICES 1 diff --git a/devices/albumdetailsdialog.cpp b/devices/albumdetailsdialog.cpp index a6e598830..3bf262664 100644 --- a/devices/albumdetailsdialog.cpp +++ b/devices/albumdetailsdialog.cpp @@ -194,24 +194,24 @@ void AlbumDetailsDialog::slotButtonClicked(int button) case Ok: { Device *dev=DevicesModel::self()->device(udi); if (dev && Device::AudioCd==dev->devType()) { - CddbAlbum cddbAlbum; - cddbAlbum.artist=artist->text().trimmed(); - cddbAlbum.name=title->text().trimmed(); - cddbAlbum.disc=disc->value(); - cddbAlbum.year=year->value(); - cddbAlbum.genre=genre->text().trimmed(); + CdAlbum cdAlbum; + cdAlbum.artist=artist->text().trimmed(); + cdAlbum.name=title->text().trimmed(); + cdAlbum.disc=disc->value(); + cdAlbum.year=year->value(); + cdAlbum.genre=genre->text().trimmed(); QString unknown=i18n("Unknown"); - if (cddbAlbum.artist.isEmpty()) { - cddbAlbum.artist=unknown; + if (cdAlbum.artist.isEmpty()) { + cdAlbum.artist=unknown; } - if (cddbAlbum.name.isEmpty()) { - cddbAlbum.name=unknown; + if (cdAlbum.name.isEmpty()) { + cdAlbum.name=unknown; } for(int i=0; itopLevelItemCount(); ++i) { QTreeWidgetItem *itm=tracks->topLevelItem(i); - cddbAlbum.tracks.append(toSong(itm)); + cdAlbum.tracks.append(toSong(itm)); } - static_cast(dev)->setDetails(cddbAlbum); + static_cast(dev)->setDetails(cdAlbum); } accept(); break; diff --git a/devices/audiocddevice.cpp b/devices/audiocddevice.cpp index 493a52db1..e97391692 100644 --- a/devices/audiocddevice.cpp +++ b/devices/audiocddevice.cpp @@ -23,6 +23,9 @@ #include "audiocddevice.h" #include "cddb.h" +#ifdef MUSICBRAINZ5_FOUND +#include "musicbrainz.h" +#endif #include "localize.h" #include "musiclibraryitemsong.h" #include "musiclibrarymodel.h" @@ -46,7 +49,12 @@ QString AudioCdDevice::coverUrl(QString udi) AudioCdDevice::AudioCdDevice(DevicesModel *m, Solid::Device &dev) : Device(m, dev, false, true) + #ifdef CDDB_FOUND , cddb(0) + #endif + #ifdef MUSICBRAINZ5_FOUND + , mb(0) + #endif , year(0) , disc(0) , time(0xFFFFFFFF) @@ -55,18 +63,20 @@ AudioCdDevice::AudioCdDevice(DevicesModel *m, Solid::Device &dev) drive=dev.parent().as(); block=dev.as(); if (block) { - cddb=new Cddb(block->device()); + static bool registeredTypes=false; + if (!registeredTypes) { + qRegisterMetaType("CdAlbum"); + qRegisterMetaType >("QList"); + registeredTypes=true; + } devPath=QLatin1String("cdda:/")+block->device()+QChar('/'); - connect(cddb, SIGNAL(error(QString)), this, SIGNAL(error(QString))); - connect(cddb, SIGNAL(initialDetails(CddbAlbum)), this, SLOT(setDetails(CddbAlbum))); - connect(this, SIGNAL(lookup()), cddb, SLOT(lookup())); - connect(cddb, SIGNAL(matches(const QList &)), SLOT(cddbMatches(const QList &))); + connectService(); detailsString=i18n("Reading disc"); setStatusMessage(detailsString); lookupInProcess=true; connect(Covers::self(), SIGNAL(cover(const Song &, const QImage &, const QString &)), this, SLOT(setCover(const Song &, const QImage &, const QString &))); - if (Settings::self()->cddbAuto()) { + if (Settings::self()->cdAuto()) { emit lookup(); } } @@ -76,9 +86,52 @@ AudioCdDevice::~AudioCdDevice() { } +void AudioCdDevice::connectService() +{ + #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND + if (cddb && !Settings::self()->useCddb()) { + cddb->deleteLater(); + cddb=0; + } + if (mb && Settings::self()->useCddb()) { + mb->deleteLater(); + mb=0; + } + #endif + + #ifdef CDDB_FOUND + if (!cddb + #ifdef MUSICBRAINZ5_FOUND + && Settings::self()->useCddb() + #endif + ) { + cddb=new Cddb(block->device()); + connect(cddb, SIGNAL(error(QString)), this, SIGNAL(error(QString))); + connect(cddb, SIGNAL(initialDetails(CdAlbum)), this, SLOT(setDetails(CdAlbum))); + connect(cddb, SIGNAL(matches(const QList &)), SLOT(cdMatches(const QList &))); + connect(this, SIGNAL(lookup()), cddb, SLOT(lookup())); + } + #endif + + #ifdef MUSICBRAINZ5_FOUND + if (!mb + #ifdef CDDB_FOUND + && !Settings::self()->useCddb() + #endif + ) { + mb=new MusicBrainz(block->device()); + connect(mb, SIGNAL(error(QString)), this, SIGNAL(error(QString))); + connect(mb, SIGNAL(initialDetails(CdAlbum)), this, SLOT(setDetails(CdAlbum))); + connect(mb, SIGNAL(matches(const QList &)), SLOT(cdMatches(const QList &))); + connect(this, SIGNAL(lookup()), mb, SLOT(lookup())); + } + #endif +} + void AudioCdDevice::rescan(bool) { - if (cddb) { + if (block) { + connectService(); lookupInProcess=true; emit lookup(); } @@ -194,7 +247,7 @@ void AudioCdDevice::copySongToResult(int status) } } -void AudioCdDevice::setDetails(const CddbAlbum &a) +void AudioCdDevice::setDetails(const CdAlbum &a) { bool differentAlbum=album!=a.name || artist!=a.artist; lookupInProcess=false; @@ -226,7 +279,7 @@ void AudioCdDevice::setDetails(const CddbAlbum &a) } } -void AudioCdDevice::cddbMatches(const QList &albums) +void AudioCdDevice::cdMatches(const QList &albums) { lookupInProcess=false; if (1==albums.count()) { diff --git a/devices/audiocddevice.h b/devices/audiocddevice.h index 32f277fc3..b3917992b 100644 --- a/devices/audiocddevice.h +++ b/devices/audiocddevice.h @@ -36,13 +36,20 @@ #include class Cddb; -class CddbAlbum; +class MusicBrainz; +class CdAlbum; class AudioCdDevice : public Device { Q_OBJECT public: + enum Service { + SrvNone, + SrvCddb, + SrvMusicBrainz + }; + static QString coverUrl(QString udi); AudioCdDevice(DevicesModel *m, Solid::Device &dev); @@ -80,19 +87,28 @@ public: Q_SIGNALS: void lookup(); - void matches(const QString &u, const QList &); + void matches(const QString &u, const QList &); public Q_SLOTS: void percent(int pc); void copySongToResult(int status); - void setDetails(const CddbAlbum &a); - void cddbMatches(const QList &albums); + void setDetails(const CdAlbum &a); + void cdMatches(const QList &albums); void setCover(const Song &song, const QImage &img, const QString &file); private: + void connectService(); + +private: + Service srv; Solid::OpticalDrive *drive; Solid::Block *block; + #ifdef CDDB_FOUND Cddb *cddb; + #endif + #ifdef MUSICBRAINZ5_FOUND + MusicBrainz *mb; + #endif QString detailsString; QString album; QString artist; diff --git a/devices/audiocdsettings.cpp b/devices/audiocdsettings.cpp index 1db147cc8..77b0fff60 100644 --- a/devices/audiocdsettings.cpp +++ b/devices/audiocdsettings.cpp @@ -23,27 +23,72 @@ #include "audiocdsettings.h" #include "settings.h" +#include "localize.h" + +#define REMOVE(w) \ + w->setVisible(false); \ + w->deleteLater(); \ + w=0; AudioCdSettings::AudioCdSettings(QWidget *p) : QWidget(p) { setupUi(this); + #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND + cdLookup->addItem(i18n("CDDB"), true); + cdLookup->addItem(i18n("MusicBrainz"), false); + connect(cdLookup, SIGNAL(currentIndexChanged(int)), SLOT(controlCddb())); + #else + REMOVE(cdLookup) + REMOVE(cdLookupLabel) + #endif } void AudioCdSettings::load() { - cddbAuto->setChecked(Settings::self()->cddbAuto()); + cdAuto->setChecked(Settings::self()->cdAuto()); + #if defined CDDB_FOUND cddbHost->setText(Settings::self()->cddbHost()); cddbPort->setValue(Settings::self()->cddbPort()); + #else + REMOVE(cddbHost) + REMOVE(cddbHostLabel) + REMOVE(cddbPort) + REMOVE(cddbPortLabel) + #endif paranoiaFull->setChecked(Settings::self()->paranoiaFull()); paranoiaNeverSkip->setChecked(Settings::self()->paranoiaNeverSkip()); + #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND + for (int i=0; icount(); ++i) { + if (cdLookup->itemData(i).toBool()==Settings::self()->useCddb()) { + cdLookup->setCurrentIndex(i); + break; + } + } + #endif } void AudioCdSettings::save() { - Settings::self()->saveCddbAuto(cddbAuto->isChecked()); + Settings::self()->saveCdAuto(cdAuto->isChecked()); + #if defined CDDB_FOUND Settings::self()->saveCddbHost(cddbHost->text().trimmed()); Settings::self()->saveCddbPort(cddbPort->value()); + #endif Settings::self()->saveParanoiaFull(paranoiaFull->isChecked()); Settings::self()->saveParanoiaNeverSkip(paranoiaNeverSkip->isChecked()); + #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND + Settings::self()->saveUseCddb(cdLookup->itemData(cdLookup->currentIndex()).toBool()); + #endif +} + +void AudioCdSettings::controlCddb() +{ + #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND + bool enable=cdLookup->itemData(cdLookup->currentIndex()).toBool(); + cddbHost->setEnabled(enable); + cddbHostLabel->setEnabled(enable); + cddbPort->setEnabled(enable); + cddbPortLabel->setEnabled(enable); + #endif } diff --git a/devices/audiocdsettings.h b/devices/audiocdsettings.h index 7100af500..9cdd5126b 100644 --- a/devices/audiocdsettings.h +++ b/devices/audiocdsettings.h @@ -28,12 +28,17 @@ class AudioCdSettings : public QWidget, private Ui::AudioCdSettings { + Q_OBJECT + public: AudioCdSettings(QWidget *p); virtual ~AudioCdSettings() { } void load(); void save(); + +private Q_SLOTS: + void controlCddb(); }; #endif diff --git a/devices/audiocdsettings.ui b/devices/audiocdsettings.ui index 5fe041280..7f15fe714 100644 --- a/devices/audiocdsettings.ui +++ b/devices/audiocdsettings.ui @@ -20,46 +20,59 @@ - CDDB Settings + Album and Track Information Retrieval - Lookup CD details automatically: + Automatically lookup: - cddbAuto + cdAuto - + - + - Host: + Look up via: + + + cdAuto + + + + + + + + + + CDDB Host: cddbHost - + - - + + - Port: + CDDB Port: cddbPort - + 1 @@ -75,7 +88,7 @@ - Ripper + Audio Extraction @@ -145,7 +158,7 @@ - cddbAuto + cdAuto cddbHost cddbPort paranoiaFull diff --git a/devices/cddb.cpp b/devices/cddb.cpp index 122819b4c..4ed7a05b0 100644 --- a/devices/cddb.cpp +++ b/devices/cddb.cpp @@ -48,13 +48,6 @@ Cddb::Cddb(const QString &device) : dev(device) , disc(0) { - static bool registeredTypes=false; - if (!registeredTypes) { - qRegisterMetaType("CddbAlbum"); - qRegisterMetaType >("QList"); - registeredTypes=true; - } - thread=new QThread(); moveToThread(thread); thread->start(); @@ -68,9 +61,9 @@ Cddb::~Cddb() } } -static CddbAlbum toAlbum(cddb_disc_t *disc) +static CdAlbum toAlbum(cddb_disc_t *disc) { - CddbAlbum album; + CdAlbum album; album.name=QString::fromUtf8(cddb_disc_get_title(disc)); album.artist=QString::fromUtf8(cddb_disc_get_artist(disc)); album.genre=QString::fromUtf8(cddb_disc_get_genre(disc)); @@ -93,7 +86,14 @@ static CddbAlbum toAlbum(cddb_disc_t *disc) track.time=cddb_track_get_length(trk); track.file=QString("%1.wav").arg(track.track); track.year=album.year; - if (Cddb::dataTrack()!=track.title) { + if (Cddb::dataTrack()==track.title) { + // Adjust last track length... + if (album.tracks.count()) { + Song last=album.tracks.takeLast(); + last.time-=FRAMES_TO_SECONDS(11400); + album.tracks.append(last); + } + } else { album.tracks.append(track); } } @@ -179,7 +179,7 @@ void Cddb::readDisc() te.cdte_format = CDROM_LBA; for (int i=th.cdth_trk0; i<=th.cdth_trk1; i++) { te.cdte_track = i; - if (ioctl(fd, CDROMREADTOCENTRY, &te) == 0) { + if (0==ioctl(fd, CDROMREADTOCENTRY, &te)) { cddb_track_t *track = cddb_track_new(); if (!track) { cddb_disc_destroy(disc); @@ -254,7 +254,7 @@ void Cddb::lookup() return; } - QList m; + QList m; for (int i = 0; i < numMatches; i++) { cddb_disc_t *possible = cddb_disc_clone(disc); if (!cddb_read(connection, possible)) { @@ -268,7 +268,7 @@ void Cddb::lookup() continue; } - CddbAlbum album=toAlbum(possible); + CdAlbum album=toAlbum(possible); if (!album.tracks.isEmpty()) { m.append(album); } diff --git a/devices/cddb.h b/devices/cddb.h index 8b6ea98d1..d5b587191 100644 --- a/devices/cddb.h +++ b/devices/cddb.h @@ -29,7 +29,8 @@ #include "song.h" #include "config.h" -struct CddbAlbum { +struct CdAlbum { + CdAlbum() : year(0), disc(0) { } QString name; QString artist; QString genre; @@ -58,8 +59,8 @@ public Q_SLOTS: Q_SIGNALS: void error(const QString &error); - void initialDetails(const CddbAlbum &); - void matches(const QList &); + void initialDetails(const CdAlbum &); + void matches(const QList &); private: QThread *thread; diff --git a/devices/cddbselectiondialog.cpp b/devices/cddbselectiondialog.cpp index 6903eeb19..31e7404d9 100644 --- a/devices/cddbselectiondialog.cpp +++ b/devices/cddbselectiondialog.cpp @@ -46,10 +46,10 @@ CddbSelectionDialog::CddbSelectionDialog(QWidget *parent) setButtons(Ok); } -int CddbSelectionDialog::select(const QList &albums) +int CddbSelectionDialog::select(const QList &albums) { combo->clear(); - foreach (const CddbAlbum &a, albums) { + foreach (const CdAlbum &a, albums) { if (a.disc>0) { combo->addItem(QString("%1 -%2 %3 (%4)").arg(a.artist).arg(a.name).arg(i18n("Disc %1").arg(a.disc)).arg(a.year)); } else { diff --git a/devices/cddbselectiondialog.h b/devices/cddbselectiondialog.h index 5f32e045b..636e6ce86 100644 --- a/devices/cddbselectiondialog.h +++ b/devices/cddbselectiondialog.h @@ -35,7 +35,7 @@ class CddbSelectionDialog : public Dialog public: CddbSelectionDialog(QWidget *parent); - int select(const QList &albums); + int select(const QList &albums); private: QComboBox *combo; }; diff --git a/devices/device.cpp b/devices/device.cpp index c84564cd0..cb81258a6 100644 --- a/devices/device.cpp +++ b/devices/device.cpp @@ -35,9 +35,9 @@ #ifdef MTP_FOUND #include "mtpdevice.h" #endif // MTP_FOUND -#ifdef CDDB_FOUND +#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND #include "audiocddevice.h" -#endif // CDDB_FOUND +#endif // defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND #include "encoders.h" #include "tags.h" #include "song.h" @@ -145,7 +145,7 @@ Device * Device::create(DevicesModel *m, const QString &udi) Solid::Device device=Solid::Device(udi); if (device.is()) { - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND return Encoders::getAvailable().isEmpty() ? 0 : new AudioCdDevice(m, device); #endif } else if (device.is()) { diff --git a/devices/devicespage.cpp b/devices/devicespage.cpp index 6bdf108ea..4dd236c82 100644 --- a/devices/devicespage.cpp +++ b/devices/devicespage.cpp @@ -51,7 +51,7 @@ #include "trackorganiser.h" #include "preferencesdialog.h" #include "coverdialog.h" -#ifdef CDDB_FOUND +#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND #include "audiocddevice.h" #include "albumdetailsdialog.h" #include "cddbselectiondialog.h" @@ -100,10 +100,10 @@ DevicesPage::DevicesPage(QWidget *p) connect(copyAction, SIGNAL(triggered()), this, SLOT(copyToLibrary())); connect(DevicesModel::self()->configureAct(), SIGNAL(triggered()), this, SLOT(configureDevice())); connect(DevicesModel::self()->refreshAct(), SIGNAL(triggered()), this, SLOT(refreshDevice())); - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND connect(DevicesModel::self()->editAct(), SIGNAL(triggered()), this, SLOT(editDetails())); - connect(DevicesModel::self(), SIGNAL(matches(const QString &, const QList &)), - SLOT(cddbMatches(const QString &, const QList &))); + connect(DevicesModel::self(), SIGNAL(matches(const QString &, const QList &)), + SLOT(cdMatches(const QString &, const QList &))); #endif QMenu *menu=new QMenu(this); #ifdef ENABLE_REMOTE_DEVICES @@ -340,7 +340,7 @@ void DevicesPage::controlActions() #ifdef ENABLE_REMOTE_DEVICES forgetDeviceAction->setEnabled(singleUdi && remoteDev); #endif - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND DevicesModel::self()->editAct()->setEnabled(!AlbumDetailsDialog::instanceCount() && !busyDevice && 1==selected.count() && audioCd && haveTracks && deviceSelected); #endif menuButton->controlState(); @@ -410,7 +410,15 @@ void DevicesPage::refreshDevice() bool full=true; if (Device::AudioCd==dev->devType()) { - if (MessageBox::No==MessageBox::questionYesNo(this, i18n("Perform CDDB lookup?"))) { + if (MessageBox::No==MessageBox::questionYesNo(this, i18n("Lookup album and track details via %1?") + #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND + .arg(Settings::self()->useCddb() ? i18n("CDDB") : i18n("MusicBrainz")) + #elif defined MUSICBRAINZ5_FOUND + .arg(i18n("MusicBrainz")) + #else + .arg(i18n("CDDB")) + #endif + )) { return; } } else { @@ -575,9 +583,9 @@ void DevicesPage::updated(const QModelIndex &idx) view->setExpanded(proxy.mapFromSource(idx)); } -void DevicesPage::cddbMatches(const QString &udi, const QList &albums) +void DevicesPage::cdMatches(const QString &udi, const QList &albums) { - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND int chosen=0; Device *dev=DevicesModel::self()->device(udi); if (dev && Device::AudioCd==dev->devType()) { @@ -605,7 +613,7 @@ void DevicesPage::cddbMatches(const QString &udi, const QList &albums void DevicesPage::editDetails() { - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND if (AlbumDetailsDialog::instanceCount()) { return; } diff --git a/devices/devicespage.h b/devices/devicespage.h index 46d7c63af..1adc7ae0a 100644 --- a/devices/devicespage.h +++ b/devices/devicespage.h @@ -66,7 +66,7 @@ public Q_SLOTS: void sync(); void updateGenres(const QModelIndex &); void updated(const QModelIndex &idx); - void cddbMatches(const QString &udi, const QList &albums); + void cdMatches(const QString &udi, const QList &albums); void editDetails(); private: diff --git a/devices/musicbrainz.cpp b/devices/musicbrainz.cpp new file mode 100644 index 000000000..7a00e364b --- /dev/null +++ b/devices/musicbrainz.cpp @@ -0,0 +1,389 @@ +/* + * Cantata + * + * Copyright (c) 2011-2013 Craig Drummond + * + */ +/* + Copyright (C) 2005-2007 Richard Lärkäng + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "musicbrainz.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "utils.h" +#include "localize.h" +#include +#include +#include +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include +#elif defined(__linux__) +#include +#endif + +#include +#define DBUG qDebug() + +static const int constFramesPerSecond=75; +static const int constDataTrackAdjust=11400; + +static inline int secondsToFrames(int s) { + return constFramesPerSecond *s; +} + +static inline int framesToSeconds(int f) { + return (f/(constFramesPerSecond*1.0))+0.5; +} + +struct Track { + Track(int o=0, bool d=false) : offset(o), isData(d) {} + int offset; + bool isData; +}; + +static QString calculateDiscId(const QList &tracks) +{ + // Code based on libmusicbrainz/lib/diskid.cpp + int numTracks = tracks.count()-1; + QCryptographicHash sha(QCryptographicHash::Sha1); + char temp[9]; + + // FIXME How do I check that? + int firstTrack = 1; + int lastTrack = numTracks; + + sprintf(temp, "%02X", firstTrack); + sha.addData(temp, strlen(temp)); + + sprintf(temp, "%02X", lastTrack); + sha.addData(temp, strlen(temp)); + + for(int i = 0; i < 100; i++) { + long offset; + if (0==i) { + offset = tracks[numTracks].offset; + } else if (i <= numTracks) { + offset = tracks[i-1].offset; + } else { + offset = 0; + } + + sprintf(temp, "%08lX", offset); + sha.addData(temp, strlen(temp)); + } + + QByteArray base64 = sha.result().toBase64(); + // '/' '+' and '=' replaced for MusicBrainz + return QString::fromLatin1(base64).replace(QLatin1Char( '/' ), QLatin1String( "_" )) + .replace(QLatin1Char( '+' ), QLatin1String( "." )) + .replace(QLatin1Char( '=' ), QLatin1String( "-" )); +} + +static QString artistFromCreditList(MusicBrainz5::CArtistCredit *artistCredit ) +{ + QString artistName; + MusicBrainz5::CNameCreditList *artistList=artistCredit->NameCreditList(); + + if (artistList) { + for (int i=0; i < artistList->NumItems(); i++) { + MusicBrainz5::CNameCredit* name=artistList->Item(i); + MusicBrainz5::CArtist* artist = name->Artist(); + + if (!name->Name().empty()) { + artistName += QString::fromUtf8(name->Name().c_str()); + } else { + artistName += QString::fromUtf8(artist->Name().c_str()); + } + artistName += QString::fromUtf8(name->JoinPhrase().c_str()); + } + } + + return artistName; +} + +MusicBrainz::MusicBrainz(const QString &device) + : dev(device) +{ + thread=new QThread(); + moveToThread(thread); + thread->start(); +} + +MusicBrainz::~MusicBrainz() +{ + Utils::stopThread(thread); +} + +void MusicBrainz::readDisc() +{ + QList tracks; + int fd=-1; + int status=-1; + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + struct ioc_toc_header th; + struct ioc_read_toc_single_entry te; + struct ioc_read_subchannel cdsc; + struct cd_sub_channel_info data; + #elif defined(__linux__) + struct cdrom_tochdr th; + struct cdrom_tocentry te; + #endif + + // open the device + fd = open(dev.toLocal8Bit(), O_RDONLY | O_NONBLOCK); + if (fd < 0) { + emit error(i18n("Failed to open CD device")); + return; + } + + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + // read disc status info + bzero(&cdsc,sizeof(cdsc)); + cdsc.data = &data; + cdsc.data_len = sizeof(data); + cdsc.data_format = CD_CURRENT_POSITION; + cdsc.address_format = CD_MSF_FORMAT; + status = ioctl(fd, CDIOCREADSUBCHANNEL, (char *)&cdsc); + if (status >= 0 && 0==ioctl(fd, CDIOREADTOCHEADER, &th)) { + te.address_format = CD_LBA_FORMAT; + for (int i=th.starting_track; i<=th.ending_track; i++) { + te.track = i; + if (0==ioctl(fd, CDIOREADTOCENTRY, &te)) { + tracks.append(Track(te.cdte_addr.lba + secondsToFrames(2), te.cdte_ctrl&CDROM_DATA_TRACK)); + } + } + te.track = 0xAA; + if (0==ioctl(fd, CDIOREADTOCENTRY, &te)) { + tracks.append((ntohl(te.entry.addr.lba)+secondsToFrames(2))/secondsToFrames(1)); + } + } + #elif defined(__linux__) + // read disc status info + status = ioctl(fd, CDROM_DISC_STATUS, CDSL_CURRENT); + if ( (CDS_AUDIO==status || CDS_MIXED==status) && 0==ioctl(fd, CDROMREADTOCHDR, &th)) { + te.cdte_format = CDROM_LBA; + for (int i=th.cdth_trk0; i<=th.cdth_trk1; i++) { + te.cdte_track = i; + if (0==ioctl(fd, CDROMREADTOCENTRY, &te)) { + tracks.append(Track(te.cdte_addr.lba + secondsToFrames(2), te.cdte_ctrl&CDROM_DATA_TRACK)); + } + } + te.cdte_track = CDROM_LEADOUT; + if (0==ioctl(fd, CDROMREADTOCENTRY, &te)) { + tracks.append((te.cdte_addr.lba+secondsToFrames(2))/secondsToFrames(1)); + } + } + #endif + close(fd); + + QString unknown(i18n("Unknown")); + initial.name=unknown; + initial.artist=unknown; + initial.genre=unknown; + + if (tracks.count()>1) { + for (int i=0; i=3 && tracks.at(tracks.count()-2).isData) { + tracks.takeLast(); + Track last=tracks.takeLast(); + last.offset-=constDataTrackAdjust; + tracks.append(last); + } + } + + discId = calculateDiscId(tracks); + emit initialDetails(initial); +} + +void MusicBrainz::lookup() +{ + if (discId.isEmpty()) { + readDisc(); + } + + DBUG << "Should lookup " << discId; + + MusicBrainz5::CQuery Query("cantata-"PACKAGE_VERSION_STRING); + QList m; + + // Code adapted from libmusicbrainz/examples/cdlookup.cc + + try { + MusicBrainz5::CMetadata Metadata=Query.Query("discid",discId.toAscii().constData()); + + if (Metadata.Disc() && Metadata.Disc()->ReleaseList()) { + MusicBrainz5::CReleaseList *releaseList=Metadata.Disc()->ReleaseList(); + DBUG << "Found " << releaseList->NumItems() << " release(s)"; + + for (int i = 0; i < releaseList->NumItems(); i++) { + MusicBrainz5::CRelease* release=releaseList->Item(i); + + //The releases returned from LookupDiscID don't contain full information + + MusicBrainz5::CQuery::tParamMap params; + params["inc"]="artists labels recordings release-groups url-rels discids artist-credits"; + + std::string releaseId=release->ID(); + MusicBrainz5::CMetadata Metadata2=Query.Query("release", releaseId, "", params); + + if (Metadata2.Release()) { + MusicBrainz5::CRelease *fullRelease=Metadata2.Release(); + + //However, these releases will include information for all media in the release + //So we need to filter out the only the media we want. + + MusicBrainz5::CMediumList mediaList=fullRelease->MediaMatchingDiscID(discId.toAscii().constData()); + + if (mediaList.NumItems() > 0) { + DBUG << "Found " << mediaList.NumItems() << " media item(s)"; + + for (int i=0; i < mediaList.NumItems(); i++) { + MusicBrainz5::CMedium* medium= mediaList.Item(i); + + /*DBUG << "Found media: '" << medium.Title() << "', position " << medium.Position();*/ + CdAlbum album; + + album.name=QString::fromUtf8(fullRelease->Title().c_str()); + + if (fullRelease->MediumList()->NumItems() > 1) { + album.name = i18n("%1 (Disc %2)").arg(album.name).arg(medium->Position()); + album.disc=medium->Position(); + } + album.artist=artistFromCreditList(fullRelease->ArtistCredit()); + album.genre=i18n("Unknown"); + + QString date = QString::fromUtf8(fullRelease->Date().c_str()); + QRegExp yearRe("^(\\d{4,4})(-\\d{1,2}-\\d{1,2})?$"); + if (yearRe.indexIn(date) > -1) { + QString yearString = yearRe.cap(1); + bool ok; + album.year=yearString.toInt(&ok); + if (!ok) { + album.year = 0; + } + } + + MusicBrainz5::CTrackList *trackList=medium->TrackList(); + if (trackList) { + for (int i=0; i < trackList->NumItems(); i++) { + // Ensure we have the same number of tracks are read from disc! + if (album.tracks.count()>=initial.tracks.count()) { + break; + } + MusicBrainz5::CTrack *track=trackList->Item(i); + MusicBrainz5::CRecording *recording=track->Recording(); + Song song; + + song.albumartist=album.artist; + song.album=album.name; + song.genre=album.genre; + song.id=song.track=track->Position(); + song.time=track->Length()/1000; + song.disc=album.disc; + + // Prefer title and artist from the track credits, but it appears to be empty if same as in Recording + // Noticable in the musicbrainztest-fulldate test, where the title on the credits of track 18 are + // "Bara om min älskade väntar", but the recording has title "Men bara om min älskade" + if (recording && 0==track->ArtistCredit()) { + song.artist=artistFromCreditList(recording->ArtistCredit()); + } else { + song.artist=artistFromCreditList(track->ArtistCredit()); + } + + if (recording && track->Title().empty()) { + song.title=QString::fromUtf8(recording->Title().c_str()); + } else { + song.title=QString::fromUtf8(track->Title().c_str()); + } + album.tracks.append(song); + } + } + + // Ensure we have the same number of tracks are read from disc! + if (album.tracks.count() + * + */ +/* + Copyright (C) 2005 Richard Lärkäng + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MUSICBRAINZ_H +#define MUSICBRAINZ_H + +#include "cddb.h" +#include + +class QThread; + +class MusicBrainz : public QObject +{ + Q_OBJECT +public: + MusicBrainz(const QString &device); + ~MusicBrainz(); + +public Q_SLOTS: + void readDisc(); + void lookup(); + +Q_SIGNALS: + void error(const QString &error); + void initialDetails(const CdAlbum &); + void matches(const QList &); + +private: + QThread *thread; + QString dev; + QString discId; + CdAlbum initial; +}; +#endif // MUSICBRAINZ_H diff --git a/gui/covers.cpp b/gui/covers.cpp index 602c5e915..ee15db258 100644 --- a/gui/covers.cpp +++ b/gui/covers.cpp @@ -361,6 +361,9 @@ void Covers::stop() disconnect(queue, SIGNAL(download(const Song &)), this, SLOT(download(const Song &))); Utils::stopThread(queueThread); } + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND + cleanCdda(); + #endif } static inline quint32 cacheKey(const Song &song, int size) @@ -687,7 +690,7 @@ void Covers::download(const Song &song) } } -#ifdef CDDB_FOUND +#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND void Covers::cleanCdda() { QString dir = Utils::cacheDir(Covers::constCddaCoverDir, false); diff --git a/gui/covers.h b/gui/covers.h index 8554ba510..a92254b74 100644 --- a/gui/covers.h +++ b/gui/covers.h @@ -125,7 +125,7 @@ public: void setSaveInMpdDir(bool s); void emitCoverUpdated(const Song &song, const QImage &img, const QString &file); - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND void cleanCdda(); #endif diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index d5f967dce..a888a0cca 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -854,9 +854,6 @@ MainWindow::~MainWindow() #ifdef ENABLE_DEVICES_SUPPORT DevicesModel::self()->stop(); #endif - #ifdef CDDB_FOUND - Covers::self()->cleanCdda(); - #endif } void MainWindow::initSizes() diff --git a/gui/preferencesdialog.cpp b/gui/preferencesdialog.cpp index 20923dbf7..21c61c0b5 100644 --- a/gui/preferencesdialog.cpp +++ b/gui/preferencesdialog.cpp @@ -44,7 +44,7 @@ #include "shortcutssettingspage.h" #include "actioncollection.h" #endif -#ifdef CDDB_FOUND +#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND #include "audiocdsettings.h" #endif @@ -87,7 +87,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, LyricsPage *lp) widget->addPage(http, i18n("HTTP Server"), Icon("network-server"), i18n("HTTP Server Settings")); #endif widget->addPage(lyrics, i18n("Lyrics"), Icons::lyricsIcon, i18n("Lyrics Settings")); - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND audiocd = new AudioCdSettings(widget); audiocd->load(); widget->addPage(audiocd, i18n("Audio CD"), Icons::albumIcon, i18n("Audio CD Settings")); @@ -131,7 +131,7 @@ void PreferencesDialog::writeSettings() proxy->save(); shortcuts->save(); #endif - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND audiocd->save(); #endif Settings::self()->saveLyricProviders(lyrics->EnabledProviders()); diff --git a/gui/preferencesdialog.h b/gui/preferencesdialog.h index 3b95dd5d4..a2f80bb99 100644 --- a/gui/preferencesdialog.h +++ b/gui/preferencesdialog.h @@ -43,7 +43,7 @@ class HttpServerSettings; #endif class MPDConnectionDetails; class CacheSettings; -#ifdef CDDB_FOUND +#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND class AudioCdSettings; #endif @@ -83,7 +83,7 @@ private: ShortcutsSettingsPage *shortcuts; #endif CacheSettings *cache; - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND AudioCdSettings *audiocd; #endif }; diff --git a/gui/settings.cpp b/gui/settings.cpp index cc12d54bb..1e929e0cb 100644 --- a/gui/settings.cpp +++ b/gui/settings.cpp @@ -577,12 +577,21 @@ QString Settings::streamUrl() } #endif -#ifdef CDDB_FOUND -bool Settings::cddbAuto() +#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND +bool Settings::cdAuto() { - return GET_BOOL("cddbAuto", true); + return GET_BOOL("cdAuto", true); } +#endif +#if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND +bool Settings::useCddb() +{ + return GET_BOOL("useCddb", true); +} +#endif + +#ifdef CDDB_FOUND QString Settings::cddbHost() { return GET_STRING("cddbHost", QString("freedb.freedb.org")); @@ -939,12 +948,21 @@ void Settings::saveStreamUrl(const QString &v) } #endif -#ifdef CDDB_FOUND -void Settings::saveCddbAuto(bool v) +#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND +void Settings::saveCdAuto(bool v) { - SET_VALUE_MOD(cddbAuto) + SET_VALUE_MOD(cdAuto) } +#endif +#if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND +void Settings::saveUseCddb(bool v) +{ + SET_VALUE_MOD(useCddb) +} +#endif + +#ifdef CDDB_FOUND void Settings::saveCddbHost(const QString &v) { SET_VALUE_MOD(cddbHost) diff --git a/gui/settings.h b/gui/settings.h index 4a15a90a9..b33eb84e2 100644 --- a/gui/settings.h +++ b/gui/settings.h @@ -151,8 +151,13 @@ public: bool playStream(); QString streamUrl(); #endif + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND + bool cdAuto(); + #endif + #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND + bool useCddb(); + #endif #ifdef CDDB_FOUND - bool cddbAuto(); QString cddbHost(); int cddbPort(); bool paranoiaFull(); @@ -220,8 +225,13 @@ public: void savePlayStream(bool v); void saveStreamUrl(const QString &v); #endif + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND + void saveCdAuto(bool v); + #endif + #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND + void saveUseCddb(bool v); + #endif #ifdef CDDB_FOUND - void saveCddbAuto(bool v); void saveCddbHost(const QString &v); void saveCddbPort(int v); void saveParanoiaFull(bool v); diff --git a/http/httpserver.cpp b/http/httpserver.cpp index 69c4276bb..67e527ebc 100644 --- a/http/httpserver.cpp +++ b/http/httpserver.cpp @@ -210,7 +210,7 @@ Song HttpServer::decodeUrl(const QUrl &url) const s.id=q.queryItemValue("id").toInt(); } s.file=url.path(); - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND if (s.file.startsWith("/cdda:/")) { s.file=s.file.mid(1); } diff --git a/models/devicesmodel.cpp b/models/devicesmodel.cpp index 3ebc1ab5b..b098010ae 100644 --- a/models/devicesmodel.cpp +++ b/models/devicesmodel.cpp @@ -38,7 +38,7 @@ #include "mountpoints.h" #include "stdactions.h" #include "actioncollection.h" -#ifdef CDDB_FOUND +#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND #include "audiocddevice.h" #endif #include @@ -107,7 +107,7 @@ DevicesModel::DevicesModel(QObject *parent) refreshAction = ActionCollection::get()->createAction("refreshdevice", i18n("Refresh Device"), "view-refresh"); connectAction = ActionCollection::get()->createAction("connectdevice", i18n("Connect Device"), Icons::connectIcon); disconnectAction = ActionCollection::get()->createAction("disconnectdevice", i18n("Disconnect Device"), Icons::disconnectIcon); - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND editAction = ActionCollection::get()->createAction("editcd", i18n("Edit CD Details"), Icons::editIcon); #endif updateItemMenu(); @@ -185,7 +185,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const case Qt::DecorationRole: switch (item->itemType()) { case MusicLibraryItem::Type_Root: { - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND if (Device::AudioCd==static_cast(item)->devType() && !static_cast(item)->cover().img.isNull()) { return static_cast(item)->cover().img; @@ -228,7 +228,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const case Qt::ToolTipRole: switch (item->itemType()) { case MusicLibraryItem::Type_Root: - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND if (Device::AudioCd==static_cast(item)->devType()) { return 0==item->childCount() ? item->data() @@ -350,7 +350,7 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const if (static_cast(item)->supportsDisconnect()) { actions << (static_cast(item)->isConnected() ? disconnectAction : connectAction); } - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND if (Device::AudioCd==static_cast(item)->devType()) { actions << editAction; } @@ -666,7 +666,7 @@ void DevicesModel::deviceAdded(const QString &udi) Solid::Device device(udi); DBUG << "Solid device added udi:" << device.udi() << "product:" << device.product() << "vendor:" << device.vendor(); Solid::StorageAccess *ssa =0; - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND Solid::OpticalDisc * opt = device.as(); if (opt && (opt->availableContent()&Solid::OpticalDisc::Audio)) { @@ -708,10 +708,10 @@ void DevicesModel::addLocalDevice(const QString &udi) connect(dev, SIGNAL(updating(const QString &, bool)), SLOT(deviceUpdating(const QString &, bool))); connect(dev, SIGNAL(error(const QString &)), SIGNAL(error(const QString &))); connect(dev, SIGNAL(cover(const Song &, const QImage &)), SLOT(setCover(const Song &, const QImage &))); - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND if (Device::AudioCd==dev->devType()) { - connect(static_cast(dev), SIGNAL(matches(const QString &, const QList &)), - SIGNAL(matches(const QString &, const QList &))); + connect(static_cast(dev), SIGNAL(matches(const QString &, const QList &)), + SIGNAL(matches(const QString &, const QList &))); } #endif updateItemMenu(); @@ -898,7 +898,7 @@ void DevicesModel::loadLocal() } } - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND deviceList = Solid::Device::listFromType(Solid::DeviceInterface::OpticalDisc); foreach (const Solid::Device &device, deviceList) { if (existingUdis.contains(device.udi())) { diff --git a/models/devicesmodel.h b/models/devicesmodel.h index b838b5fd5..0cd06443c 100644 --- a/models/devicesmodel.h +++ b/models/devicesmodel.h @@ -73,7 +73,7 @@ public: Action * refreshAct() const { return refreshAction; } Action * connectAct() const { return connectAction; } Action * disconnectAct() const { return disconnectAction; } - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND Action * editAct() const { return editAction; } #endif @@ -107,7 +107,7 @@ Q_SIGNALS: void addToDevice(const QString &udi); void error(const QString &text); void updated(const QModelIndex &idx); - void matches(const QString &udi, const QList &albums); + void matches(const QString &udi, const QList &albums); private: QList devices; @@ -120,7 +120,7 @@ private: Action *refreshAction; Action *connectAction; Action *disconnectAction; - #ifdef CDDB_FOUND + #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND Action *editAction; #endif friend class Device;