// seratofeature.cpp
// Created 2020-01-31 by Jan Holthuis
#include "library/serato/seratofeature.h"
#include <QMap>
#include <QMessageBox>
#include <QSettings>
#include <QStandardPaths>
#include <QtDebug>
#include "library/dao/trackschema.h"
#include "library/library.h"
#include "library/queryutil.h"
#include "library/trackcollection.h"
#include "library/trackcollectionmanager.h"
#include "library/treeitem.h"
#include "track/beatfactory.h"
#include "track/cue.h"
#include "track/keyfactory.h"
#include "util/assert.h"
#include "util/color/color.h"
#include "util/db/dbconnectionpooled.h"
#include "util/db/dbconnectionpooler.h"
#include "widget/wlibrary.h"
#include "widget/wlibrarytextbrowser.h"
namespace {
// Serato Database Field IDs
// The "magic" value is the short 4 byte ascii code interpreted as quint32, so
// that we can use the value in a switch statement instead of going through
// a strcmp if/else ladder.
enum class FieldId : quint32 {
Version = 0x7672736e, // vrsn
Track = 0x6f74726b, // otrk
FileType = 0x74747970, // ttyp
FilePath = 0x7066696c, // pfil
SongTitle = 0x74736e67, // tsng
Artist = 0x74617274, // tart
Album = 0x74616c62, // talb
Genre = 0x7467656e, // tgen
Comment = 0x74636f6d, // tcom
Grouping = 0x74677270, // tgrp
Label = 0x746c626c, // tlbl
Year = 0x74747972, // ttyr
Length = 0x746c656e, // tlen
Bitrate = 0x74626974, // tbit
SampleRate = 0x74736d70, // tsmp
Bpm = 0x7462706d, // tbpm
DateAddedText = 0x74616464, // tadd
DateAdded = 0x75616464, // uadd
Key = 0x746b6579, // tkey
BeatgridLocked = 0x6262676c, // bbgl
FileTime = 0x75746d65, // utme
Missing = 0x626d6973, // bmis
Sorting = 0x7472736f, // osrt
ReverseOrder = 0x62726576, // brev
ColumnTitle = 0x6f766374, // ovct
ColumnName = 0x7476636e, // tvcn
ColumnWidth = 0x74766377, // tvcw
TrackPath = 0x7074726b, // ptrk
};
struct serato_track_t {
QString filetype;
QString location;
QString title;
QString artist;
QString album;
QString genre;
QString comment;
QString grouping;
QString label;
int year = -1;
int duration = -1;
QString bitrate;
QString samplerate;
double bpm = -1.0;
QString key;
bool beatgridlocked = false;
bool missing = false;
quint32 filetime = 0;
quint32 datetimeadded = 0;
};
const QString kDatabaseDirectory = QStringLiteral("_Serato_");
const QString kDatabaseFilename = QStringLiteral("database V2");
const QString kCrateDirectory = QStringLiteral("Subcrates");
const QString kCrateFilter = QStringLiteral("*.crate");
const QString kSmartCrateDirectory = QStringLiteral("Smart Crates");
const QString kSmartCrateFilter = QStringLiteral("*.scrate");
const QString kSeratoLibraryTable = QStringLiteral("serato_library");
const QString kSeratoPlaylistsTable = QStringLiteral("serato_playlists");
const QString kSeratoPlaylistTracksTable = QStringLiteral("serato_playlist_tracks");
constexpr int