1
0
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:
David Sansome 2010-08-29 15:32:36 +00:00
parent ae47b271f3
commit d8ea4660e7
12 changed files with 153 additions and 42 deletions

View File

@ -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
View 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;

View File

@ -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;

View File

@ -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());

View File

@ -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_;

View File

@ -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) {

View File

@ -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_;
};

View File

@ -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) {

View File

@ -20,6 +20,8 @@
#include <QDialog>
#include <QPersistentModelIndex>
#include "core/song.h"
class DeviceManager;
class Ui_DeviceProperties;

View File

@ -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(

View File

@ -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();

View File

@ -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_;
};