Fix setting output/device for Xine and VLC backend
- Fixed setting output and device on Xine and VLC backend - Fixed track slider for Xine, VLC and Phonon - Improved backend settings to better support multiple backends - Added group by samplerate and bitdepth in collection - Fixed crash on exit when existing instance of the application is already runnung caused by NVIDIA driver - Changed Q_OS_MAC to Q_OS_MACOS
This commit is contained in:
@@ -125,21 +125,4 @@ void Collection::CurrentSongChanged(const Song &song) {
|
||||
connect(reply, SIGNAL(Finished(bool)), reply, SLOT(deleteLater()));
|
||||
}
|
||||
|
||||
if (song.filetype() == Song::Type_Asf) {
|
||||
current_wma_song_url_ = song.url();
|
||||
}
|
||||
}
|
||||
|
||||
SongList Collection::FilterCurrentWMASong(SongList songs, Song* queued) {
|
||||
|
||||
for (SongList::iterator it = songs.begin(); it != songs.end(); ) {
|
||||
if (it->url() == current_wma_song_url_) {
|
||||
*queued = *it;
|
||||
it = songs.erase(it);
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
|
||||
@@ -73,9 +73,6 @@ class Collection : public QObject {
|
||||
void CurrentSongChanged(const Song &song);
|
||||
void Stopped();
|
||||
|
||||
private:
|
||||
SongList FilterCurrentWMASong(SongList songs, Song* queued);
|
||||
|
||||
private:
|
||||
Application *app_;
|
||||
CollectionBackend *backend_;
|
||||
@@ -84,10 +81,6 @@ class Collection : public QObject {
|
||||
CollectionWatcher *watcher_;
|
||||
Thread *watcher_thread_;
|
||||
|
||||
// Hack: Gstreamer doesn't cope well with WMA files being rewritten while being played,
|
||||
// so we delay statistics and rating changes until the current song has finished playing.
|
||||
QUrl current_wma_song_url_;
|
||||
|
||||
// DB schema versions which should trigger a full collection rescan (each of those with a short reason why).
|
||||
QHash<int, QString> full_rescan_revisions_;
|
||||
};
|
||||
|
||||
@@ -219,7 +219,8 @@ void CollectionModel::SongsDiscovered(const SongList &songs) {
|
||||
case GroupBy_Genre: key = song.genre(); break;
|
||||
case GroupBy_AlbumArtist: key = song.effective_albumartist(); break;
|
||||
case GroupBy_Year:
|
||||
key = QString::number(qMax(0, song.year())); break;
|
||||
key = QString::number(qMax(0, song.year()));
|
||||
break;
|
||||
case GroupBy_OriginalYear:
|
||||
key = QString::number(qMax(0, song.effective_originalyear()));
|
||||
break;
|
||||
@@ -227,8 +228,7 @@ void CollectionModel::SongsDiscovered(const SongList &songs) {
|
||||
key = PrettyYearAlbum(qMax(0, song.year()), song.album());
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbum:
|
||||
key = PrettyYearAlbum(qMax(0, song.effective_originalyear()),
|
||||
song.album());
|
||||
key = PrettyYearAlbum(qMax(0, song.effective_originalyear()), song.album());
|
||||
break;
|
||||
case GroupBy_FileType:
|
||||
key = song.filetype();
|
||||
@@ -236,6 +236,12 @@ void CollectionModel::SongsDiscovered(const SongList &songs) {
|
||||
case GroupBy_Bitrate:
|
||||
key = song.bitrate();
|
||||
break;
|
||||
case GroupBy_Samplerate:
|
||||
key = song.samplerate();
|
||||
break;
|
||||
case GroupBy_Bitdepth:
|
||||
key = song.bitdepth();
|
||||
break;
|
||||
case GroupBy_None:
|
||||
qLog(Error) << "GroupBy_None";
|
||||
break;
|
||||
@@ -325,6 +331,12 @@ QString CollectionModel::DividerKey(GroupBy type, CollectionItem *item) const {
|
||||
|
||||
case GroupBy_Bitrate:
|
||||
return SortTextForNumber(item->metadata.bitrate());
|
||||
|
||||
case GroupBy_Samplerate:
|
||||
return SortTextForNumber(item->metadata.samplerate());
|
||||
|
||||
case GroupBy_Bitdepth:
|
||||
return SortTextForNumber(item->metadata.bitdepth());
|
||||
|
||||
case GroupBy_None:
|
||||
return QString();
|
||||
@@ -364,6 +376,14 @@ QString CollectionModel::DividerDisplayText(GroupBy type, const QString &key) co
|
||||
case GroupBy_Bitrate:
|
||||
if (key == "000") return tr("Unknown");
|
||||
return QString::number(key.toInt()); // To remove leading 0s
|
||||
|
||||
case GroupBy_Samplerate:
|
||||
if (key == "000") return tr("Unknown");
|
||||
return QString::number(key.toInt()); // To remove leading 0s
|
||||
|
||||
case GroupBy_Bitdepth:
|
||||
if (key == "000") return tr("Unknown");
|
||||
return QString::number(key.toInt()); // To remove leading 0s
|
||||
|
||||
case GroupBy_None:
|
||||
// fallthrough
|
||||
@@ -836,6 +856,12 @@ void CollectionModel::InitQuery(GroupBy type, CollectionQuery *q) {
|
||||
case GroupBy_Bitrate:
|
||||
q->SetColumnSpec("DISTINCT bitrate");
|
||||
break;
|
||||
case GroupBy_Samplerate:
|
||||
q->SetColumnSpec("DISTINCT samplerate");
|
||||
break;
|
||||
case GroupBy_Bitdepth:
|
||||
q->SetColumnSpec("DISTINCT bitdepth");
|
||||
break;
|
||||
case GroupBy_None:
|
||||
q->SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
|
||||
break;
|
||||
@@ -911,6 +937,12 @@ void CollectionModel::FilterQuery(GroupBy type, CollectionItem *item, Collection
|
||||
case GroupBy_Bitrate:
|
||||
q->AddWhere("bitrate", item->key);
|
||||
break;
|
||||
case GroupBy_Samplerate:
|
||||
q->AddWhere("samplerate", item->key);
|
||||
break;
|
||||
case GroupBy_Bitdepth:
|
||||
q->AddWhere("bitdepth", item->key);
|
||||
break;
|
||||
case GroupBy_None:
|
||||
qLog(Error) << "Unknown GroupBy type" << type << "used in filter";
|
||||
break;
|
||||
@@ -936,10 +968,7 @@ CollectionItem *CollectionModel::InitItem(GroupBy type, bool signal, CollectionI
|
||||
CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool create_divider, CollectionItem *parent, const SqlRow &row, int container_level) {
|
||||
|
||||
CollectionItem *item = InitItem(type, signal, parent, container_level);
|
||||
int year = 0;
|
||||
int effective_originalyear = 0;
|
||||
int bitrate = 0;
|
||||
int disc = 0;
|
||||
int year(0), effective_originalyear(0), disc(0), bitrate(0), samplerate(0), bitdepth(0);
|
||||
|
||||
switch (type) {
|
||||
case GroupBy_Artist:
|
||||
@@ -972,13 +1001,11 @@ CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool c
|
||||
item->key = QString::number(year);
|
||||
item->sort_text = SortTextForNumber(year) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_OriginalYear:
|
||||
year = qMax(0, row.value(0).toInt());
|
||||
item->key = QString::number(year);
|
||||
item->sort_text = SortTextForNumber(year) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_Composer:
|
||||
case GroupBy_Performer:
|
||||
case GroupBy_Grouping:
|
||||
@@ -1006,6 +1033,18 @@ CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool c
|
||||
item->key = QString::number(bitrate);
|
||||
item->sort_text = SortTextForNumber(bitrate) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_Samplerate:
|
||||
samplerate = qMax(0, row.value(0).toInt());
|
||||
item->key = QString::number(samplerate);
|
||||
item->sort_text = SortTextForNumber(samplerate) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_Bitdepth:
|
||||
bitdepth = qMax(0, row.value(0).toInt());
|
||||
item->key = QString::number(bitdepth);
|
||||
item->sort_text = SortTextForNumber(bitdepth) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_None:
|
||||
item->metadata.InitFromQuery(row, true);
|
||||
@@ -1024,10 +1063,7 @@ CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool c
|
||||
CollectionItem *CollectionModel::ItemFromSong(GroupBy type, bool signal, bool create_divider, CollectionItem *parent, const Song &s, int container_level) {
|
||||
|
||||
CollectionItem *item = InitItem(type, signal, parent, container_level);
|
||||
int year = 0;
|
||||
int originalyear = 0;
|
||||
int effective_originalyear = 0;
|
||||
int bitrate = 0;
|
||||
int year(0), originalyear(0), effective_originalyear(0), bitrate(0), samplerate(0), bitdepth(0);
|
||||
|
||||
switch (type) {
|
||||
case GroupBy_Artist:
|
||||
@@ -1092,6 +1128,18 @@ CollectionItem *CollectionModel::ItemFromSong(GroupBy type, bool signal, bool cr
|
||||
item->key = QString::number(bitrate);
|
||||
item->sort_text = SortTextForNumber(bitrate) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_Samplerate:
|
||||
samplerate = qMax(0, s.samplerate());
|
||||
item->key = QString::number(samplerate);
|
||||
item->sort_text = SortTextForNumber(samplerate) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_Bitdepth:
|
||||
bitdepth = qMax(0, s.bitdepth());
|
||||
item->key = QString::number(bitdepth);
|
||||
item->sort_text = SortTextForNumber(bitdepth) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_None:
|
||||
item->metadata = s;
|
||||
|
||||
@@ -99,6 +99,8 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
GroupBy_Disc = 12,
|
||||
GroupBy_OriginalYearAlbum = 13,
|
||||
GroupBy_OriginalYear = 14,
|
||||
GroupBy_Samplerate = 15,
|
||||
GroupBy_Bitdepth = 16
|
||||
};
|
||||
|
||||
struct Grouping {
|
||||
|
||||
@@ -230,7 +230,7 @@ void CollectionWatcher::AddDirectory(const Directory &dir, const SubdirectoryLis
|
||||
ScanTransaction transaction(this, dir.id, true);
|
||||
transaction.SetKnownSubdirs(subdirs);
|
||||
transaction.AddToProgressMax(subdirs.count());
|
||||
for (const Subdirectory& subdir : subdirs) {
|
||||
for (const Subdirectory &subdir : subdirs) {
|
||||
if (stop_requested_) return;
|
||||
|
||||
if (scan_on_startup_) ScanSubdirectory(subdir.path, subdir, &transaction);
|
||||
@@ -742,9 +742,9 @@ void CollectionWatcher::ReloadSettings() {
|
||||
}
|
||||
else if (monitor_ && !was_monitoring_before) {
|
||||
// Add all directories to all QFileSystemWatchers again
|
||||
for (const Directory& dir : watched_dirs_.values()) {
|
||||
for (const Directory &dir : watched_dirs_.values()) {
|
||||
SubdirectoryList subdirs = backend_->SubdirsInDirectory(dir.id);
|
||||
for (const Subdirectory& subdir : subdirs) {
|
||||
for (const Subdirectory &subdir : subdirs) {
|
||||
AddWatch(dir, subdir.path);
|
||||
}
|
||||
}
|
||||
@@ -783,12 +783,12 @@ void CollectionWatcher::FullScanNow() { PerformScan(false, true); }
|
||||
|
||||
void CollectionWatcher::PerformScan(bool incremental, bool ignore_mtimes) {
|
||||
|
||||
for (const Directory & dir : watched_dirs_.values()) {
|
||||
for (const Directory &dir : watched_dirs_.values()) {
|
||||
ScanTransaction transaction(this, dir.id, incremental, ignore_mtimes);
|
||||
SubdirectoryList subdirs(transaction.GetAllSubdirs());
|
||||
transaction.AddToProgressMax(subdirs.count());
|
||||
|
||||
for (const Subdirectory & subdir : subdirs) {
|
||||
for (const Subdirectory &subdir : subdirs) {
|
||||
if (stop_requested_) return;
|
||||
|
||||
ScanSubdirectory(subdir.path, subdir, &transaction);
|
||||
|
||||
@@ -96,11 +96,13 @@ GroupByDialog::GroupByDialog(QWidget *parent) : QDialog(parent), ui_(new Ui_Grou
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_YearAlbum, 9));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYearAlbum, 10));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitrate, 11));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Disc, 12));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Performer, 13));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Grouping, 14));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Samplerate, 12));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitdepth, 13));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Disc, 14));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Performer, 15));
|
||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Grouping, 16));
|
||||
|
||||
connect(ui_->button_box->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(Reset()));
|
||||
connect(ui_->buttonbox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(Reset()));
|
||||
|
||||
resize(sizeHint());
|
||||
}
|
||||
@@ -108,23 +110,23 @@ GroupByDialog::GroupByDialog(QWidget *parent) : QDialog(parent), ui_(new Ui_Grou
|
||||
GroupByDialog::~GroupByDialog() {}
|
||||
|
||||
void GroupByDialog::Reset() {
|
||||
ui_->first->setCurrentIndex(2); // Artist
|
||||
ui_->second->setCurrentIndex(1); // Album
|
||||
ui_->third->setCurrentIndex(0); // None
|
||||
ui_->combobox_first->setCurrentIndex(2); // Artist
|
||||
ui_->combobox_second->setCurrentIndex(1); // Album
|
||||
ui_->combobox_third->setCurrentIndex(0); // None
|
||||
}
|
||||
|
||||
void GroupByDialog::accept() {
|
||||
emit Accepted(CollectionModel::Grouping(
|
||||
p_->mapping_.get<tag_index>().find(ui_->first->currentIndex())->group_by,
|
||||
p_->mapping_.get<tag_index>().find(ui_->second->currentIndex())->group_by,
|
||||
p_->mapping_.get<tag_index>().find(ui_->third->currentIndex())->group_by)
|
||||
p_->mapping_.get<tag_index>().find(ui_->combobox_first->currentIndex())->group_by,
|
||||
p_->mapping_.get<tag_index>().find(ui_->combobox_second->currentIndex())->group_by,
|
||||
p_->mapping_.get<tag_index>().find(ui_->combobox_third->currentIndex())->group_by)
|
||||
);
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void GroupByDialog::CollectionGroupingChanged(const CollectionModel::Grouping &g) {
|
||||
ui_->first->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[0])->combo_box_index);
|
||||
ui_->second->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[1])->combo_box_index);
|
||||
ui_->third->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[2])->combo_box_index);
|
||||
ui_->combobox_first->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[0])->combo_box_index);
|
||||
ui_->combobox_second->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[1])->combo_box_index);
|
||||
ui_->combobox_third->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[2])->combo_box_index);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>354</width>
|
||||
<height>236</height>
|
||||
<height>246</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -19,7 +19,7 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>You can change the way the songs in the collection are organised.</string>
|
||||
</property>
|
||||
@@ -35,14 +35,14 @@
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<widget class="QLabel" name="label_first">
|
||||
<property name="text">
|
||||
<string>First level</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="first">
|
||||
<widget class="QComboBox" name="combobox_first">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
@@ -103,6 +103,16 @@
|
||||
<string>Bitrate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Sample rate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bit depth</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disc</string>
|
||||
@@ -121,14 +131,14 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<widget class="QLabel" name="label_second">
|
||||
<property name="text">
|
||||
<string>Second level</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="second">
|
||||
<widget class="QComboBox" name="combobox_second">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
@@ -189,6 +199,16 @@
|
||||
<string>Bitrate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Sample rate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bit depth</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disc</string>
|
||||
@@ -207,14 +227,14 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<widget class="QLabel" name="label_third">
|
||||
<property name="text">
|
||||
<string>Third level</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="third">
|
||||
<widget class="QComboBox" name="combobox_third">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
@@ -275,6 +295,16 @@
|
||||
<string>Bitrate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Sample rate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bit depth</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disc</string>
|
||||
@@ -309,7 +339,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="button_box">
|
||||
<widget class="QDialogButtonBox" name="buttonbox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@@ -321,17 +351,17 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>first</tabstop>
|
||||
<tabstop>second</tabstop>
|
||||
<tabstop>third</tabstop>
|
||||
<tabstop>button_box</tabstop>
|
||||
<tabstop>combobox_first</tabstop>
|
||||
<tabstop>combobox_second</tabstop>
|
||||
<tabstop>combobox_third</tabstop>
|
||||
<tabstop>buttonbox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../data/data.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>button_box</sender>
|
||||
<sender>buttonbox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>GroupByDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
@@ -347,7 +377,7 @@
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>button_box</sender>
|
||||
<sender>buttonbox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>GroupByDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
|
||||
@@ -110,6 +110,12 @@ QString SavedGroupingManager::GroupByToString(const CollectionModel::GroupBy &g)
|
||||
case CollectionModel::GroupBy_Bitrate: {
|
||||
return tr("Bitrate");
|
||||
}
|
||||
case CollectionModel::GroupBy_Samplerate: {
|
||||
return tr("Sample rate");
|
||||
}
|
||||
case CollectionModel::GroupBy_Bitdepth: {
|
||||
return tr("Bit depth");
|
||||
}
|
||||
case CollectionModel::GroupBy_Disc: {
|
||||
return tr("Disc");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user