diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts index 2259d1bb..e8277f34 100644 --- a/etc/Translation/Blank.ts +++ b/etc/Translation/Blank.ts @@ -239,6 +239,95 @@ + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + + + + Discard + + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1376,6 +1465,18 @@ The LameXP shell integration has been re-enabled. + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_DE.ts b/etc/Translation/LameXP_DE.ts index 76e118cf..591f21d5 100644 --- a/etc/Translation/LameXP_DE.ts +++ b/etc/Translation/LameXP_DE.ts @@ -239,6 +239,95 @@ Version + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + Durchsuchen... + + + Discard + Schließen + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1377,6 +1466,18 @@ Don't Show Again Nicht mehr anzeigen + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_ES.ts b/etc/Translation/LameXP_ES.ts index 9e8ea6cb..09e9db73 100644 --- a/etc/Translation/LameXP_ES.ts +++ b/etc/Translation/LameXP_ES.ts @@ -239,6 +239,95 @@ Versión + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + Navegar... + + + Discard + + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1376,6 +1465,18 @@ Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_FR.ts b/etc/Translation/LameXP_FR.ts index f9eba950..52cd9c84 100644 --- a/etc/Translation/LameXP_FR.ts +++ b/etc/Translation/LameXP_FR.ts @@ -243,6 +243,95 @@ Version + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + Explorer... + + + Discard + Abandonner + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1386,6 +1475,18 @@ Ouvrir le dossier récursivement... Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_IT.ts b/etc/Translation/LameXP_IT.ts index 6d9d6d06..e70a9081 100644 --- a/etc/Translation/LameXP_IT.ts +++ b/etc/Translation/LameXP_IT.ts @@ -239,6 +239,95 @@ + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + + + + Discard + Annulla + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1377,6 +1466,18 @@ Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_KR.ts b/etc/Translation/LameXP_KR.ts index 3a887a38..6a6b3080 100644 --- a/etc/Translation/LameXP_KR.ts +++ b/etc/Translation/LameXP_KR.ts @@ -239,6 +239,95 @@ 버전 + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + 찾아보기... + + + Discard + 닫기 + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1376,6 +1465,18 @@ Don't Show Again 다시 표시하지 않음 + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_RU.ts b/etc/Translation/LameXP_RU.ts index 6ef9bb0e..d8d96de5 100644 --- a/etc/Translation/LameXP_RU.ts +++ b/etc/Translation/LameXP_RU.ts @@ -239,6 +239,95 @@ Версия + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + Выбрать... + + + Discard + Отменить + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1378,6 +1467,18 @@ Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_UK.ts b/etc/Translation/LameXP_UK.ts index 217dd0e1..620abed1 100644 --- a/etc/Translation/LameXP_UK.ts +++ b/etc/Translation/LameXP_UK.ts @@ -239,6 +239,95 @@ Версія + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + + + + Discard + Відмінити + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1376,6 +1465,18 @@ Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/gui/CueSheetImport.ui b/gui/CueSheetImport.ui index 9c86aa7d..7ed6d920 100644 --- a/gui/CueSheetImport.ui +++ b/gui/CueSheetImport.ui @@ -219,6 +219,9 @@ :/icons/folder_explore.png:/icons/folder_explore.png + + false + @@ -272,9 +275,6 @@ 16 - - false - @@ -312,8 +312,10 @@ - abortButton imprtButton + abortButton + editOutputDir + browseButton treeView @@ -347,6 +349,8 @@ + + @@ -356,8 +360,8 @@ close() - 609 - 408 + 688 + 451 310 diff --git a/res/localization/LameXP_DE.qm b/res/localization/LameXP_DE.qm index c7f40f2d..fb7d81fc 100644 Binary files a/res/localization/LameXP_DE.qm and b/res/localization/LameXP_DE.qm differ diff --git a/res/localization/LameXP_ES.qm b/res/localization/LameXP_ES.qm index 18feb6cf..0ab8505b 100644 Binary files a/res/localization/LameXP_ES.qm and b/res/localization/LameXP_ES.qm differ diff --git a/res/localization/LameXP_FR.qm b/res/localization/LameXP_FR.qm index fb5753ba..f2d4b746 100644 Binary files a/res/localization/LameXP_FR.qm and b/res/localization/LameXP_FR.qm differ diff --git a/res/localization/LameXP_IT.qm b/res/localization/LameXP_IT.qm index 373a3f2e..651f2f86 100644 Binary files a/res/localization/LameXP_IT.qm and b/res/localization/LameXP_IT.qm differ diff --git a/res/localization/LameXP_KR.qm b/res/localization/LameXP_KR.qm index 72a00e18..80ef04e7 100644 Binary files a/res/localization/LameXP_KR.qm and b/res/localization/LameXP_KR.qm differ diff --git a/res/localization/LameXP_RU.qm b/res/localization/LameXP_RU.qm index a3b7020b..6eadece4 100644 Binary files a/res/localization/LameXP_RU.qm and b/res/localization/LameXP_RU.qm differ diff --git a/res/localization/LameXP_UK.qm b/res/localization/LameXP_UK.qm index ca60b842..4217f36b 100644 Binary files a/res/localization/LameXP_UK.qm and b/res/localization/LameXP_UK.qm differ diff --git a/src/Config.h b/src/Config.h index 42ff735b..07f69e0f 100644 --- a/src/Config.h +++ b/src/Config.h @@ -30,7 +30,7 @@ #define VER_LAMEXP_MINOR_LO 2 #define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_PATCH 14 -#define VER_LAMEXP_BUILD 509 +#define VER_LAMEXP_BUILD 513 /////////////////////////////////////////////////////////////////////////////// // Tools versions diff --git a/src/Dialog_CueImport.cpp b/src/Dialog_CueImport.cpp index 73b5a18b..9df31e2c 100644 --- a/src/Dialog_CueImport.cpp +++ b/src/Dialog_CueImport.cpp @@ -63,7 +63,7 @@ CueImportDialog::CueImportDialog(QWidget *parent) //Enable up/down button connect(imprtButton, SIGNAL(clicked()), this, SLOT(importButtonClicked())); - connect(browseButton, SIGNAL(clicked()), this, SLOT(importButtonClicked())); + connect(browseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked())); //Translate labelHeaderText->setText(QString("%1
%2").arg(tr("Import Cue Sheet"), tr("The following Cue Sheet will be split and imported into LameXP."))); @@ -92,38 +92,66 @@ int CueImportDialog::exec(const QString &cueFile) { WorkingBanner *progress = new WorkingBanner(dynamic_cast(parent())); progress->show(tr("Loading Cue Sheet file, please be patient...")); - int iResult = m_model->loadCueSheet(cueFile, QApplication::instance()); - progress->close(); - LAMEXP_DELETE(progress); - if(iResult) + QFileInfo cueFileInfo(cueFile); + m_outputDir = QFileInfo(cueFile).canonicalPath(); + + if(!cueFileInfo.exists() || !cueFileInfo.isFile() || m_outputDir.isEmpty()) + { + QString text = QString("%1
%2

%3").arg(tr("Failed to load the Cue Sheet file:"), QDir::toNativeSeparators(cueFile), tr("The specified file could not be found!")).replace("-", "−"); + QMessageBox::warning(progress, tr("Cue Sheet Error"), text); + progress->close(); + LAMEXP_DELETE(progress); + return CueSheetModel::ErrorIOFailure; + } + + int iResult = m_model->loadCueSheet(cueFile, QApplication::instance()); + if(iResult != CueSheetModel::ErrorSuccess) { QString errorMsg = tr("An unknown error has occured!"); switch(iResult) { - case 1: - errorMsg = tr("The file could not be opened for reading!"); + case CueSheetModel::ErrorIOFailure: + errorMsg = tr("The file could not be opened for reading. Make sure you have the required rights!"); break; - case 2: - errorMsg = tr("The file does not look like a valid Cue Sheet disc image file!"); + case CueSheetModel::ErrorBadFile: + errorMsg = tr("The provided file does not look like a valid Cue Sheet disc image file!"); break; - case 3: - errorMsg = tr("Could not find a supported audio track in the Cue Sheet!"); + case CueSheetModel::ErrorUnsupported: + errorMsg = QString("%1
%2").arg(tr("Could not find any supported audio track in the Cue Sheet image!"), tr("Note that LameXP can not handle \"binary\" Cue Sheet images.")); + break; + case CueSheetModel::ErrorInconsistent: + errorMsg = tr("The selected Cue Sheet file contains inconsistent information. Take care!"); break; } - QString text = QString("%1
%2

%3").arg(tr("Failed to load the Cue Sheet file:"), cueFile, errorMsg).replace("-", "−"); - QMessageBox::warning(dynamic_cast(parent()), tr("Cue Sheet Error"), text); + QString text = QString("%1
%2

%3").arg(tr("Failed to load the Cue Sheet file:"), QDir::toNativeSeparators(cueFile), errorMsg).replace("-", "−"); + QMessageBox::warning(progress, tr("Cue Sheet Error"), text); + progress->close(); + LAMEXP_DELETE(progress); return iResult; } - + + progress->close(); + LAMEXP_DELETE(progress); return QDialog::exec(); } void CueImportDialog::modelChanged(void) { treeView->expandAll(); + editOutputDir->setText(QDir::toNativeSeparators(m_outputDir)); +} + +void CueImportDialog::browseButtonClicked(void) +{ + QString newOutDir = QFileDialog::getExistingDirectory(this, tr("Choose Output Directory")); + if(!newOutDir.isEmpty()) + { + m_outputDir = newOutDir; + modelChanged(); + } } void CueImportDialog::importButtonClicked(void) diff --git a/src/Dialog_CueImport.h b/src/Dialog_CueImport.h index b9180559..2b35f035 100644 --- a/src/Dialog_CueImport.h +++ b/src/Dialog_CueImport.h @@ -42,9 +42,11 @@ protected: void CueImportDialog::showEvent(QShowEvent *event); private slots: + void browseButtonClicked(void); void importButtonClicked(void); void modelChanged(void); private: CueSheetModel *m_model; + QString m_outputDir; }; diff --git a/src/Model_CueSheet.cpp b/src/Model_CueSheet.cpp index 30b52e79..0a0c2a8d 100644 --- a/src/Model_CueSheet.cpp +++ b/src/Model_CueSheet.cpp @@ -24,9 +24,9 @@ #include "Genres.h" #include -#include -#include +#include #include +#include #include #include @@ -39,6 +39,7 @@ class CueSheetItem { public: virtual const char* type(void) = 0; + virtual bool isValid(void) { return false; } }; class CueSheetTrack : public CueSheetItem @@ -50,20 +51,24 @@ public: m_trackNo(trackNo) { m_startIndex = std::numeric_limits::quiet_NaN(); + m_duration = std::numeric_limits::infinity(); } int trackNo(void) { return m_trackNo; } double startIndex(void) { return m_startIndex; } + double duration(void) { return m_duration; } QString title(void) { return m_title; } QString performer(void) { return m_performer; } CueSheetFile *parent(void) { return m_parent; } void setStartIndex(double startIndex) { m_startIndex = startIndex; } - void setTitle(const QString &title) { m_title = title; } - void setPerformer(const QString &performer) { m_performer = performer; } - bool isValid(void) { return !(_isnan(m_startIndex) || (m_trackNo < 0)); } + void setDuration(double duration) { m_duration = duration; } + void setTitle(const QString &title, bool update = false) { if(!update || (m_title.isEmpty() && !title.isEmpty())) m_title = title; } + void setPerformer(const QString &performer, bool update = false) { if(!update || (m_performer.isEmpty() && !performer.isEmpty())) m_performer = performer; } + virtual bool isValid(void) { return !(_isnan(m_startIndex) || (m_trackNo < 0)); } virtual const char* type(void) { return "CueSheetTrack"; } private: int m_trackNo; double m_startIndex; + double m_duration; QString m_title; QString m_performer; CueSheetFile *m_parent; @@ -79,6 +84,7 @@ public: void clearTracks(void) { while(!m_tracks.isEmpty()) delete m_tracks.takeLast(); } CueSheetTrack *track(int index) { return m_tracks.at(index); } int trackCount(void) { return m_tracks.count(); } + virtual bool isValid(void) { return m_tracks.count() > 0; } virtual const char* type(void) { return "CueSheetFile"; } private: const QString m_fileName; @@ -134,7 +140,7 @@ QModelIndex CueSheetModel::index(int row, int column, const QModelIndex &parent) int CueSheetModel::columnCount(const QModelIndex &parent) const { - return 3; + return 4; } int CueSheetModel::rowCount(const QModelIndex &parent) const @@ -182,6 +188,9 @@ QVariant CueSheetModel::headerData (int section, Qt::Orientation orientation, in case 2: return tr("Index"); break; + case 3: + return tr("Duration"); + break; default: return QVariant(); break; @@ -207,7 +216,7 @@ QVariant CueSheetModel::data(const QModelIndex &index, int role) const return tr("File %1").arg(QString().sprintf("%02d", index.row() + 1)).append(" "); break; case 1: - return QString("[%1]").arg(QFileInfo(filePtr->fileName()).fileName()); + return QFileInfo(filePtr->fileName()).fileName(); break; default: return QVariant(); @@ -242,12 +251,48 @@ QVariant CueSheetModel::data(const QModelIndex &index, int role) const case 2: return indexToString(trackPtr->startIndex()); break; + case 3: + return indexToString(trackPtr->duration()); + break; default: return QVariant(); break; } } } + else if(role == Qt::FontRole) + { + QFont font("Monospace"); + font.setStyleHint(QFont::TypeWriter); + if((index.column() == 1)) + { + CueSheetItem *item = reinterpret_cast(index.internalPointer()); + font.setBold(dynamic_cast(item) != NULL); + } + return font; + } + else if(role == Qt::ForegroundRole) + { + if((index.column() == 1)) + { + CueSheetItem *item = reinterpret_cast(index.internalPointer()); + if(CueSheetFile *filePtr = dynamic_cast(item)) + { + return QFileInfo(filePtr->fileName()).exists() ? QColor("mediumblue") : QColor("darkred"); + } + } + else if((index.column() == 3)) + { + CueSheetItem *item = reinterpret_cast(index.internalPointer()); + if(CueSheetTrack *trackPtr = dynamic_cast(item)) + { + if(trackPtr->duration() == std::numeric_limits::infinity()) + { + return QColor("dimgrey"); + } + } + } + } return QVariant(); } @@ -268,19 +313,19 @@ int CueSheetModel::loadCueSheet(const QString &cueFileName, QCoreApplication *ap QFile cueFile(cueFileName); if(!cueFile.open(QIODevice::ReadOnly)) { - return 1; + return ErrorIOFailure; } clearData(); beginResetModel(); - int iResult = parseCueFile(cueFile, application); + int iResult = parseCueFile(cueFile, QDir(QFileInfo(cueFile).canonicalPath()), application); endResetModel(); return iResult; } -int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) +int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplication *application) { cueFile.seek(0); qDebug("\n[Cue Sheet Import]"); @@ -319,7 +364,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) if(application) { application->processEvents(); - Sleep(25); + Sleep(10); } QByteArray lineData = cueFile.readLine(); @@ -341,14 +386,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) { if(currentTrack->isValid()) { - if(currentTrack->title().isEmpty() && !albumTitle.isEmpty()) - { - currentTrack->setTitle(albumTitle); - } - if(currentTrack->performer().isEmpty() && !albumPerformer.isEmpty()) - { - currentTrack->setPerformer(albumPerformer); - } + currentTrack->setTitle(albumTitle, true); + currentTrack->setPerformer(albumPerformer, true); currentFile->addTrack(currentTrack); currentTrack = NULL; } @@ -357,7 +396,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) LAMEXP_DELETE(currentTrack); } } - if(currentFile->trackCount() > 0) + if(currentFile->isValid()) { m_files.append(currentFile); currentFile = NULL; @@ -373,7 +412,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) } if(!rxFile.cap(2).compare("WAVE", Qt::CaseInsensitive) || !rxFile.cap(2).compare("MP3", Qt::CaseInsensitive) || !rxFile.cap(2).compare("AIFF", Qt::CaseInsensitive)) { - currentFile = new CueSheetFile(rxFile.cap(1)); + currentFile = new CueSheetFile(baseDir.absoluteFilePath(rxFile.cap(1))); + qDebug("File path: <%s>", currentFile->fileName().toUtf8().constData()); } else { @@ -396,14 +436,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) { if(currentTrack->isValid()) { - if(currentTrack->title().isEmpty() && !albumTitle.isEmpty()) - { - currentTrack->setTitle(albumTitle); - } - if(currentTrack->performer().isEmpty() && !albumPerformer.isEmpty()) - { - currentTrack->setPerformer(albumPerformer); - } + currentTrack->setTitle(albumTitle, true); + currentTrack->setPerformer(albumPerformer, true); currentFile->addTrack(currentTrack); currentTrack = NULL; } @@ -476,21 +510,15 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) } } - //Finally append the very last track/file + //Append the very last track/file that is still pending if(currentFile) { if(currentTrack) { if(currentTrack->isValid()) { - if(currentTrack->title().isEmpty() && !albumTitle.isEmpty()) - { - currentTrack->setTitle(albumTitle); - } - if(currentTrack->performer().isEmpty() && !albumPerformer.isEmpty()) - { - currentTrack->setPerformer(albumPerformer); - } + currentTrack->setTitle(albumTitle, true); + currentTrack->setPerformer(albumPerformer, true); currentFile->addTrack(currentTrack); currentTrack = NULL; } @@ -499,7 +527,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) LAMEXP_DELETE(currentTrack); } } - if(currentFile->trackCount() > 0) + if(currentFile->isValid()) { m_files.append(currentFile); currentFile = NULL; @@ -510,7 +538,72 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) } } - return (m_files.count() > 0) ? 0 : (bUnsupportedTrack ? 3 : 2); + //Finally calculate duration of each track + int nFiles = m_files.count(); + for(int i = 0; i < nFiles; i++) + { + if(application) + { + application->processEvents(); + Sleep(10); + } + + CueSheetFile *currentFile = m_files.at(i); + int nTracks = currentFile->trackCount(); + if(nTracks > 1) + { + for(int j = 1; j < nTracks; j++) + { + CueSheetTrack *currentTrack = currentFile->track(j); + CueSheetTrack *previousTrack = currentFile->track(j-1); + double duration = currentTrack->startIndex() - previousTrack->startIndex(); + previousTrack->setDuration(max(0.0, duration)); + } + } + } + + //Sanity check of track numbers + if(nFiles > 0) + { + bool trackNo[100]; + for(int i = 0; i < 100; i++) + { + trackNo[i] = false; + } + for(int i = 0; i < nFiles; i++) + { + if(application) + { + application->processEvents(); + Sleep(10); + } + CueSheetFile *currentFile = m_files.at(i); + int nTracks = currentFile->trackCount(); + if(nTracks > 1) + { + for(int j = 1; j < nTracks; j++) + { + int currentTrackNo = currentFile->track(j)->trackNo(); + if(currentTrackNo > 99) + { + qWarning("Track #%02d is invalid (maximum is 99), Cue Sheet is inconsistent!", currentTrackNo); + return ErrorInconsistent; + } + if(trackNo[currentTrackNo]) + { + qWarning("Track #%02d exists multiple times, Cue Sheet is inconsistent!", currentTrackNo); + return ErrorInconsistent; + } + trackNo[currentTrackNo] = true; + } + } + } + return ErrorSuccess; + } + else + { + return bUnsupportedTrack ? ErrorUnsupported : ErrorBadFile; + } } double CueSheetModel::parseTimeIndex(const QString &index) @@ -538,10 +631,21 @@ double CueSheetModel::parseTimeIndex(const QString &index) QString CueSheetModel::indexToString(const double index) const { - int temp = static_cast(index * 100.0); + if(index == std::numeric_limits::quiet_NaN()) + { + return QString("<-NaN!->"); + } + else if(index == std::numeric_limits::infinity() || index < 0.0) + { + return QString("??:??.??"); + } + else + { + int temp = static_cast(index * 100.0); - int msec = temp % 100; - int secs = temp / 100; + int msec = temp % 100; + int secs = temp / 100; - return QString().sprintf("%02d:%02d.%02d", (secs / 60), (secs % 60), msec); + return QString().sprintf("%02d:%02d.%02d", min(99, secs / 60), min(99, secs % 60), min(99, msec)); + } } diff --git a/src/Model_CueSheet.h b/src/Model_CueSheet.h index 5baeb26c..acb66df2 100644 --- a/src/Model_CueSheet.h +++ b/src/Model_CueSheet.h @@ -27,6 +27,7 @@ class CueSheetFile; class QApplication; +class QDir; class CueSheetModel : public QAbstractItemModel { @@ -36,6 +37,17 @@ public: CueSheetModel(); ~CueSheetModel(void); + //Error codes + enum ErrorCode + { + ErrorSuccess = 0, + ErrorIOFailure = 1, + ErrorBadFile = 2, + ErrorUnsupported = 3, + ErrorInconsistent = 4, + ErrorUnknown = 9 + }; + //Model functions QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; @@ -49,7 +61,7 @@ public: int loadCueSheet(const QString &cueFile, QCoreApplication *application = NULL); private: - int parseCueFile(QFile &cueFile, QCoreApplication *application); + int parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplication *application); double parseTimeIndex(const QString &index); QString indexToString(const double index) const; QList m_files;