mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-27 17:49:19 +01:00
Store the device's transcode preference in the database
This commit is contained in:
parent
ae47b271f3
commit
d8ea4660e7
@ -262,5 +262,6 @@
|
||||
<file>icons/32x32/ipodtouchicon.png</file>
|
||||
<file>icons/48x48/ipodtouchicon.png</file>
|
||||
<file>icons/32x32/wiimotedev.png</file>
|
||||
<file>schema-17.sql</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
6
data/schema-17.sql
Normal file
6
data/schema-17.sql
Normal file
@ -0,0 +1,6 @@
|
||||
ALTER TABLE devices ADD COLUMN transcode_mode NOT NULL DEFAULT 3;
|
||||
|
||||
ALTER TABLE devices ADD COLUMN transcode_format NOT NULL DEFAULT 5;
|
||||
|
||||
UPDATE schema_version SET version=17;
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <QVariant>
|
||||
|
||||
const char* Database::kDatabaseFilename = "clementine.db";
|
||||
const int Database::kSchemaVersion = 16;
|
||||
const int Database::kSchemaVersion = 17;
|
||||
|
||||
int Database::sNextConnectionId = 1;
|
||||
QMutex Database::sNextConnectionIdMutex;
|
||||
|
@ -39,7 +39,8 @@ DeviceDatabaseBackend::DeviceList DeviceDatabaseBackend::GetAllDevices() {
|
||||
|
||||
DeviceList ret;
|
||||
|
||||
QSqlQuery q("SELECT ROWID, unique_id, friendly_name, size, icon"
|
||||
QSqlQuery q("SELECT ROWID, unique_id, friendly_name, size, icon,"
|
||||
" transcode_mode, transcode_format"
|
||||
" FROM devices", db);
|
||||
q.exec();
|
||||
if (db_->CheckErrors(q.lastError())) return ret;
|
||||
@ -51,24 +52,31 @@ DeviceDatabaseBackend::DeviceList DeviceDatabaseBackend::GetAllDevices() {
|
||||
dev.friendly_name_ = q.value(2).toString();
|
||||
dev.size_ = q.value(3).toLongLong();
|
||||
dev.icon_name_ = q.value(4).toString();
|
||||
dev.transcode_mode_ = TranscodeMode(q.value(5).toInt());
|
||||
dev.transcode_format_ = Song::FileType(q.value(6).toInt());
|
||||
ret << dev;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DeviceDatabaseBackend::AddDevice(const Device &device) {
|
||||
int DeviceDatabaseBackend::AddDevice(const Device& device) {
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
ScopedTransaction t(&db);
|
||||
|
||||
// Insert the device into the devices table
|
||||
QSqlQuery q("INSERT INTO devices (unique_id, friendly_name, size, icon)"
|
||||
" VALUES (:unique_id, :friendly_name, :size, :icon)", db);
|
||||
QSqlQuery q("INSERT INTO devices ("
|
||||
" unique_id, friendly_name, size, icon,"
|
||||
" transcode_mode, transcode_format)"
|
||||
" VALUES (:unique_id, :friendly_name, :size, :icon,"
|
||||
" :transcode_mode, :transcode_format)", db);
|
||||
q.bindValue(":unique_id", device.unique_id_);
|
||||
q.bindValue(":friendly_name", device.friendly_name_);
|
||||
q.bindValue(":size", device.size_);
|
||||
q.bindValue(":icon", device.icon_name_);
|
||||
q.bindValue(":transcode_mode", device.transcode_mode_);
|
||||
q.bindValue(":transcode_format", device.transcode_format_);
|
||||
q.exec();
|
||||
if (db_->CheckErrors(q.lastError())) return -1;
|
||||
int id = q.lastInsertId().toInt();
|
||||
@ -108,17 +116,22 @@ void DeviceDatabaseBackend::RemoveDevice(int id) {
|
||||
t.Commit();
|
||||
}
|
||||
|
||||
void DeviceDatabaseBackend::SetDeviceIdentity(int id, const QString &friendly_name,
|
||||
const QString &icon_name) {
|
||||
void DeviceDatabaseBackend::SetDeviceOptions(int id,
|
||||
const QString &friendly_name, const QString &icon_name,
|
||||
TranscodeMode mode, Song::FileType format) {
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
QSqlQuery q("UPDATE devices"
|
||||
" SET friendly_name=:friendly_name,"
|
||||
" icon=:icon_name"
|
||||
" icon=:icon_name,"
|
||||
" transcode_mode=:transcode_mode,"
|
||||
" transcode_format=:transcode_format"
|
||||
" WHERE ROWID=:id", db);
|
||||
q.bindValue(":friendly_name", friendly_name);
|
||||
q.bindValue(":icon_name", icon_name);
|
||||
q.bindValue(":transcode_mode", mode);
|
||||
q.bindValue(":transcode_format", format);
|
||||
q.bindValue(":id", id);
|
||||
q.exec();
|
||||
db_->CheckErrors(q.lastError());
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "core/song.h"
|
||||
|
||||
class Database;
|
||||
|
||||
class DeviceDatabaseBackend : public QObject {
|
||||
@ -29,6 +31,13 @@ class DeviceDatabaseBackend : public QObject {
|
||||
public:
|
||||
Q_INVOKABLE DeviceDatabaseBackend(QObject* parent = 0);
|
||||
|
||||
// Values are saved in the database - don't change
|
||||
enum TranscodeMode {
|
||||
Transcode_Always = 1,
|
||||
Transcode_Never = 2,
|
||||
Transcode_Unsupported = 3,
|
||||
};
|
||||
|
||||
struct Device {
|
||||
Device() : id_(-1) {}
|
||||
|
||||
@ -37,6 +46,9 @@ public:
|
||||
QString friendly_name_;
|
||||
quint64 size_;
|
||||
QString icon_name_;
|
||||
|
||||
TranscodeMode transcode_mode_;
|
||||
Song::FileType transcode_format_;
|
||||
};
|
||||
typedef QList<Device> DeviceList;
|
||||
|
||||
@ -49,8 +61,9 @@ public:
|
||||
int AddDevice(const Device& device);
|
||||
void RemoveDevice(int id);
|
||||
|
||||
void SetDeviceIdentity(int id, const QString& friendly_name,
|
||||
const QString& icon_name);
|
||||
void SetDeviceOptions(int id,
|
||||
const QString& friendly_name, const QString& icon_name,
|
||||
TranscodeMode mode, Song::FileType format);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<Database> db_;
|
||||
|
@ -60,6 +60,8 @@ const int DeviceManager::kDeviceIconOverlaySize = 16;
|
||||
|
||||
DeviceManager::DeviceInfo::DeviceInfo()
|
||||
: database_id_(-1),
|
||||
transcode_mode_(DeviceDatabaseBackend::Transcode_Unsupported),
|
||||
transcode_format_(Song::Type_Mpeg),
|
||||
task_percentage_(-1)
|
||||
{
|
||||
}
|
||||
@ -70,6 +72,8 @@ DeviceDatabaseBackend::Device DeviceManager::DeviceInfo::SaveToDb() const {
|
||||
ret.size_ = size_;
|
||||
ret.id_ = database_id_;
|
||||
ret.icon_name_ = icon_name_;
|
||||
ret.transcode_mode_ = transcode_mode_;
|
||||
ret.transcode_format_ = transcode_format_;
|
||||
|
||||
QStringList unique_ids;
|
||||
foreach (const Backend& backend, backends_) {
|
||||
@ -80,10 +84,12 @@ DeviceDatabaseBackend::Device DeviceManager::DeviceInfo::SaveToDb() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DeviceManager::DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device &dev) {
|
||||
void DeviceManager::DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device& dev) {
|
||||
database_id_ = dev.id_;
|
||||
friendly_name_ = dev.friendly_name_;
|
||||
size_ = dev.size_;
|
||||
transcode_mode_ = dev.transcode_mode_;
|
||||
transcode_format_ = dev.transcode_format_;
|
||||
|
||||
QStringList icon_names = dev.icon_name_.split(',');
|
||||
QVariantList icons;
|
||||
@ -321,6 +327,12 @@ QVariant DeviceManager::data(const QModelIndex& index, int role) const {
|
||||
return QDir::toNativeSeparators(ret);
|
||||
}
|
||||
|
||||
case Role_TranscodeMode:
|
||||
return info.transcode_mode_;
|
||||
|
||||
case Role_TranscodeFormat:
|
||||
return info.transcode_format_;
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@ -604,16 +616,20 @@ void DeviceManager::Forget(int row) {
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::SetDeviceIdentity(int row, const QString &friendly_name,
|
||||
const QString &icon_name) {
|
||||
void DeviceManager::SetDeviceOptions(int row,
|
||||
const QString& friendly_name, const QString& icon_name,
|
||||
DeviceDatabaseBackend::TranscodeMode mode, Song::FileType format) {
|
||||
DeviceInfo& info = devices_[row];
|
||||
info.friendly_name_ = friendly_name;
|
||||
info.LoadIcon(QVariantList() << icon_name, friendly_name);
|
||||
info.transcode_mode_ = mode;
|
||||
info.transcode_format_ = format;
|
||||
|
||||
emit dataChanged(index(row, 0), index(row, 0));
|
||||
|
||||
if (info.database_id_ != -1)
|
||||
backend_->SetDeviceIdentity(info.database_id_, friendly_name, icon_name);
|
||||
backend_->SetDeviceOptions(info.database_id_, friendly_name, icon_name,
|
||||
mode, format);
|
||||
}
|
||||
|
||||
void DeviceManager::DeviceTaskStarted(int id) {
|
||||
|
@ -49,6 +49,8 @@ public:
|
||||
Role_IconName,
|
||||
Role_UpdatingPercentage,
|
||||
Role_MountPath,
|
||||
Role_TranscodeMode,
|
||||
Role_TranscodeFormat,
|
||||
|
||||
LastRole,
|
||||
};
|
||||
@ -81,8 +83,9 @@ public:
|
||||
void Forget(int row);
|
||||
void UnmountAsync(int row);
|
||||
|
||||
void SetDeviceIdentity(int row, const QString& friendly_name,
|
||||
const QString& icon_name);
|
||||
void SetDeviceOptions(int row,
|
||||
const QString& friendly_name, const QString& icon_name,
|
||||
DeviceDatabaseBackend::TranscodeMode mode, Song::FileType format);
|
||||
|
||||
// QAbstractListModel
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
@ -148,6 +151,9 @@ private:
|
||||
QString icon_name_;
|
||||
QIcon icon_;
|
||||
|
||||
DeviceDatabaseBackend::TranscodeMode transcode_mode_;
|
||||
Song::FileType transcode_format_;
|
||||
|
||||
int task_percentage_;
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "deviceproperties.h"
|
||||
#include "ui_deviceproperties.h"
|
||||
#include "core/utilities.h"
|
||||
#include "transcoder/transcoder.h"
|
||||
#include "ui/iconloader.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
@ -56,8 +57,8 @@ void DeviceProperties::SetDeviceManager(DeviceManager *manager) {
|
||||
}
|
||||
|
||||
void DeviceProperties::ShowDevice(int row) {
|
||||
// Only load the icons the first time the dialog is shown
|
||||
if (ui_->icon->count() == 0) {
|
||||
// Only load the icons the first time the dialog is shown
|
||||
QStringList icon_names = QStringList()
|
||||
<< "drive-removable-media-usb-pendrive"
|
||||
<< "multimedia-player-ipod-mini-blue"
|
||||
@ -85,6 +86,12 @@ void DeviceProperties::ShowDevice(int row) {
|
||||
IconLoader::Load(icon_name), QString(), ui_->icon);
|
||||
item->setData(Qt::UserRole, icon_name);
|
||||
}
|
||||
|
||||
// Load the transcode formats the first time the dialog is shown
|
||||
foreach (const TranscoderPreset& preset, Transcoder::GetAllPresets()) {
|
||||
ui_->transcode_format->addItem(preset.name_, preset.type_);
|
||||
}
|
||||
ui_->transcode_format->model()->sort(0);
|
||||
}
|
||||
|
||||
index_ = manager_->index(row);
|
||||
@ -179,6 +186,29 @@ void DeviceProperties::UpdateFormats() {
|
||||
boost::shared_ptr<ConnectedDevice> device =
|
||||
manager_->GetConnectedDevice(index_.row());
|
||||
|
||||
// Transcode mode
|
||||
DeviceDatabaseBackend::TranscodeMode mode = DeviceDatabaseBackend::TranscodeMode(
|
||||
index_.data(DeviceManager::Role_TranscodeMode).toInt());
|
||||
switch (mode) {
|
||||
case DeviceDatabaseBackend::Transcode_Always:
|
||||
ui_->transcode_all->setChecked(true);
|
||||
break;
|
||||
|
||||
case DeviceDatabaseBackend::Transcode_Never:
|
||||
ui_->transcode_off->setChecked(true);
|
||||
break;
|
||||
|
||||
case DeviceDatabaseBackend::Transcode_Unsupported:
|
||||
default:
|
||||
ui_->transcode_unsupported->setChecked(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Transcode format
|
||||
TranscoderPreset preset = Transcoder::PresetForFileType(Song::FileType(
|
||||
index_.data(DeviceManager::Role_TranscodeFormat).toInt()));
|
||||
ui_->transcode_format->setCurrentIndex(ui_->transcode_format->findText(preset.name_));
|
||||
|
||||
// If there's no lister then the device is physically disconnected
|
||||
if (!lister) {
|
||||
ui_->formats_stack->setCurrentWidget(ui_->formats_page_not_connected);
|
||||
@ -212,8 +242,22 @@ void DeviceProperties::UpdateFormats() {
|
||||
void DeviceProperties::accept() {
|
||||
QDialog::accept();
|
||||
|
||||
manager_->SetDeviceIdentity(index_.row(), ui_->name->text(),
|
||||
ui_->icon->currentItem()->data(Qt::UserRole).toString());
|
||||
// Transcode mode
|
||||
DeviceDatabaseBackend::TranscodeMode mode = DeviceDatabaseBackend::Transcode_Unsupported;
|
||||
if (ui_->transcode_all->isChecked())
|
||||
mode = DeviceDatabaseBackend::Transcode_Always;
|
||||
else if (ui_->transcode_off->isChecked())
|
||||
mode = DeviceDatabaseBackend::Transcode_Never;
|
||||
else if (ui_->transcode_unsupported->isChecked())
|
||||
mode = DeviceDatabaseBackend::Transcode_Unsupported;
|
||||
|
||||
// Transcode format
|
||||
Song::FileType format = Song::FileType(ui_->transcode_format->itemData(
|
||||
ui_->transcode_format->currentIndex()).toInt());
|
||||
|
||||
manager_->SetDeviceOptions(index_.row(),
|
||||
ui_->name->text(), ui_->icon->currentItem()->data(Qt::UserRole).toString(),
|
||||
mode, format);
|
||||
}
|
||||
|
||||
void DeviceProperties::OpenDevice() {
|
||||
@ -231,6 +275,10 @@ void DeviceProperties::UpdateFormatsFinished() {
|
||||
ui_->supported_formats_container->setVisible(!list.isEmpty());
|
||||
ui_->transcode_unsupported->setEnabled(!list.isEmpty());
|
||||
|
||||
if (ui_->transcode_unsupported->isChecked() && list.isEmpty()) {
|
||||
ui_->transcode_off->setChecked(true);
|
||||
}
|
||||
|
||||
// Populate supported types list
|
||||
ui_->supported_formats->clear();
|
||||
foreach (Song::FileType type, list) {
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <QDialog>
|
||||
#include <QPersistentModelIndex>
|
||||
|
||||
#include "core/song.h"
|
||||
|
||||
class DeviceManager;
|
||||
class Ui_DeviceProperties;
|
||||
|
||||
|
@ -54,7 +54,7 @@ TranscodeDialog::TranscodeDialog(QWidget *parent)
|
||||
log_ui_->setupUi(log_dialog_);
|
||||
|
||||
// Get presets
|
||||
QList<TranscoderPreset> presets = transcoder_->presets();
|
||||
QList<TranscoderPreset> presets = Transcoder::GetAllPresets();
|
||||
qSort(presets.begin(), presets.end(), ComparePresetsByName);
|
||||
foreach (const TranscoderPreset& preset, presets) {
|
||||
ui_->format->addItem(
|
||||
|
@ -29,11 +29,13 @@ int Transcoder::JobFinishedEvent::sEventType = -1;
|
||||
|
||||
|
||||
TranscoderPreset::TranscoderPreset(
|
||||
Song::FileType type,
|
||||
const QString& name,
|
||||
const QString& extension,
|
||||
const QString& codec_mimetype,
|
||||
const QString& muxer_mimetype)
|
||||
: name_(name),
|
||||
: type_(type),
|
||||
name_(name),
|
||||
extension_(extension),
|
||||
codec_mimetype_(codec_mimetype),
|
||||
muxer_mimetype_(muxer_mimetype)
|
||||
@ -165,36 +167,39 @@ Transcoder::Transcoder(QObject* parent)
|
||||
{
|
||||
if (JobFinishedEvent::sEventType == -1)
|
||||
JobFinishedEvent::sEventType = QEvent::registerEventType();
|
||||
}
|
||||
|
||||
presets_ << PresetForFileType(Song::Type_Flac);
|
||||
presets_ << PresetForFileType(Song::Type_Mp4);
|
||||
presets_ << PresetForFileType(Song::Type_Mpeg);
|
||||
presets_ << PresetForFileType(Song::Type_OggVorbis);
|
||||
presets_ << PresetForFileType(Song::Type_OggFlac);
|
||||
presets_ << PresetForFileType(Song::Type_OggSpeex);
|
||||
presets_ << PresetForFileType(Song::Type_Asf);
|
||||
presets_ << PresetForFileType(Song::Type_Wav);
|
||||
presets_ << TranscoderPreset("3GP AAC", "3gp", "audio/mpeg, mpegversion=(int)4", "application/x-3gp");
|
||||
QList<TranscoderPreset> Transcoder::GetAllPresets() {
|
||||
QList<TranscoderPreset> ret;
|
||||
ret << PresetForFileType(Song::Type_Flac);
|
||||
ret << PresetForFileType(Song::Type_Mp4);
|
||||
ret << PresetForFileType(Song::Type_Mpeg);
|
||||
ret << PresetForFileType(Song::Type_OggVorbis);
|
||||
ret << PresetForFileType(Song::Type_OggFlac);
|
||||
ret << PresetForFileType(Song::Type_OggSpeex);
|
||||
ret << PresetForFileType(Song::Type_Asf);
|
||||
ret << PresetForFileType(Song::Type_Wav);
|
||||
return ret;
|
||||
}
|
||||
|
||||
TranscoderPreset Transcoder::PresetForFileType(Song::FileType type) {
|
||||
switch (type) {
|
||||
case Song::Type_Flac:
|
||||
return TranscoderPreset("FLAC", "flac", "audio/x-flac");
|
||||
return TranscoderPreset(type, "FLAC", "flac", "audio/x-flac");
|
||||
case Song::Type_Mp4:
|
||||
return TranscoderPreset("M4A AAC", "mp4", "audio/mpeg, mpegversion=(int)4", "audio/mp4");
|
||||
return TranscoderPreset(type, "M4A AAC", "mp4", "audio/mpeg, mpegversion=(int)4", "audio/mp4");
|
||||
case Song::Type_Mpeg:
|
||||
return TranscoderPreset("MP3", "mp3", "audio/mpeg, mpegversion=(int)1, layer=(int)3");
|
||||
return TranscoderPreset(type, "MP3", "mp3", "audio/mpeg, mpegversion=(int)1, layer=(int)3");
|
||||
case Song::Type_OggVorbis:
|
||||
return TranscoderPreset("Ogg Vorbis", "ogg", "audio/x-vorbis", "application/ogg");
|
||||
return TranscoderPreset(type, "Ogg Vorbis", "ogg", "audio/x-vorbis", "application/ogg");
|
||||
case Song::Type_OggFlac:
|
||||
return TranscoderPreset("Ogg Flac", "ogg", "audio/x-flac", "application/ogg");
|
||||
return TranscoderPreset(type, "Ogg Flac", "ogg", "audio/x-flac", "application/ogg");
|
||||
case Song::Type_OggSpeex:
|
||||
return TranscoderPreset("Ogg Speex", "spx", "audio/x-speex", "application/ogg");
|
||||
return TranscoderPreset(type, "Ogg Speex", "spx", "audio/x-speex", "application/ogg");
|
||||
case Song::Type_Asf:
|
||||
return TranscoderPreset("Windows Media audio", "wma", "audio/x-wma", "video/x-ms-asf");
|
||||
return TranscoderPreset(type, "Windows Media audio", "wma", "audio/x-wma", "video/x-ms-asf");
|
||||
case Song::Type_Wav:
|
||||
return TranscoderPreset("Wav", "wav", QString(), "audio/x-wav");
|
||||
return TranscoderPreset(type, "Wav", "wav", QString(), "audio/x-wav");
|
||||
default:
|
||||
qWarning() << "Unsupported format in Transcoder::PresetForFileType:" << type;
|
||||
return TranscoderPreset();
|
||||
|
@ -31,12 +31,14 @@
|
||||
|
||||
|
||||
struct TranscoderPreset {
|
||||
TranscoderPreset() {}
|
||||
TranscoderPreset(const QString& name,
|
||||
TranscoderPreset() : type_(Song::Type_Unknown) {}
|
||||
TranscoderPreset(Song::FileType type,
|
||||
const QString& name,
|
||||
const QString& extension,
|
||||
const QString& codec_mimetype,
|
||||
const QString& muxer_mimetype_ = QString());
|
||||
|
||||
Song::FileType type_;
|
||||
QString name_;
|
||||
QString extension_;
|
||||
QString codec_mimetype_;
|
||||
@ -52,8 +54,8 @@ class Transcoder : public QObject {
|
||||
Transcoder(QObject* parent = 0);
|
||||
|
||||
static TranscoderPreset PresetForFileType(Song::FileType type);
|
||||
static QList<TranscoderPreset> GetAllPresets();
|
||||
|
||||
QList<TranscoderPreset> presets() const { return presets_; }
|
||||
int max_threads() const { return max_threads_; }
|
||||
|
||||
void set_max_threads(int count) { max_threads_ = count; }
|
||||
@ -132,7 +134,6 @@ class Transcoder : public QObject {
|
||||
typedef QList<boost::shared_ptr<JobState> > JobStateList;
|
||||
|
||||
int max_threads_;
|
||||
QList<TranscoderPreset> presets_;
|
||||
QList<Job> queued_jobs_;
|
||||
JobStateList current_jobs_;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user