UpdateDialog::~UpdateDialog(void) { if(m_animator) { m_animator->stop(); } if(m_thread) { if(!m_thread->wait(1000)) { m_thread->terminate(); m_thread->wait(); } } LAMEXP_DELETE(m_thread); LAMEXP_DELETE(m_logFile); LAMEXP_DELETE(m_animator); WinSevenTaskbar::setTaskbarState(this->parentWidget(), WinSevenTaskbar::WinSevenTaskbarNoState); WinSevenTaskbar::setOverlayIcon(this->parentWidget(), NULL); LAMEXP_DELETE(ui); }
extern "C" void _lamexp_global_free_utils(void) { //Delete temporary files const QString &tempFolder = lamexp_temp_folder2(); if(!tempFolder.isEmpty()) { bool success = false; for(int i = 0; i < 100; i++) { if(lamexp_clean_folder(tempFolder)) { success = true; break; } lamexp_sleep(100); } if(!success) { lamexp_system_message(L"Sorry, LameXP was unable to clean up all temporary files. Some residual files in your TEMP directory may require manual deletion!", lamexp_beep_warning); lamexp_exec_shell(NULL, tempFolder, QString(), QString(), true); } } //Free memory LAMEXP_DELETE(g_lamexp_temp_folder.path); LAMEXP_DELETE(g_lamexp_app_icon.appIcon); }
~SettingsCache(void) { flushValues(); LAMEXP_DELETE(m_cache); LAMEXP_DELETE(m_cacheDirty); LAMEXP_DELETE(m_cacheLock); LAMEXP_DELETE(m_configFile); }
extern "C" void _lamexp_global_free_tools(void) { //Free *all* registered translations if(g_lamexp_currentTranslator.instance) { QApplication::removeTranslator(g_lamexp_currentTranslator.instance); LAMEXP_DELETE(g_lamexp_currentTranslator.instance); } LAMEXP_DELETE(g_lamexp_translation.files); LAMEXP_DELETE(g_lamexp_translation.names); LAMEXP_DELETE(g_lamexp_translation.cntry); LAMEXP_DELETE(g_lamexp_translation.sysid); //Free *all* registered tools if(g_lamexp_tools.registry) { QStringList keys = g_lamexp_tools.registry->keys(); for(int i = 0; i < keys.count(); i++) { LockedFile *lf = g_lamexp_tools.registry->take(keys.at(i)); LAMEXP_DELETE(lf); } g_lamexp_tools.registry->clear(); g_lamexp_tools.versions->clear(); g_lamexp_tools.tags->clear(); } LAMEXP_DELETE(g_lamexp_tools.registry); LAMEXP_DELETE(g_lamexp_tools.versions); LAMEXP_DELETE(g_lamexp_tools.tags); }
ArtworkModel::~ArtworkModel(void) { QMutexLocker lock(m_mutex); ArtworkModel_SharedData::detach(&m_data); lock.unlock(); LAMEXP_DELETE(m_mutex); }
void CueSplitter::run() { m_bSuccess = false; m_bAborted = false; m_abortFlag = false; m_nTracksSuccess = 0; m_nTracksSkipped = 0; m_decompressedFiles.clear(); m_activeFile.clear(); if(!QDir(m_outputDir).exists()) { qWarning("Output directory \"%s\" does not exist!", QUTF8(m_outputDir)); return; } QStringList inputFileList = m_inputFilesInfo.keys(); int nInputFiles = inputFileList.count(); emit progressMaxChanged(nInputFiles); emit progressValChanged(0); //Decompress all input files for(int i = 0; i < nInputFiles; i++) { const AudioFileModel_TechInfo &inputFileInfo = m_inputFilesInfo[inputFileList.at(i)].techInfo(); if(inputFileInfo.containerType().compare("Wave", Qt::CaseInsensitive) || inputFileInfo.audioType().compare("PCM", Qt::CaseInsensitive)) { AbstractDecoder *decoder = DecoderRegistry::lookup(inputFileInfo.containerType(), inputFileInfo.containerProfile(), inputFileInfo.audioType(), inputFileInfo.audioProfile(), inputFileInfo.audioVersion()); if(decoder) { m_activeFile = shortName(QFileInfo(inputFileList.at(i)).fileName()); emit fileSelected(m_activeFile); emit progressValChanged(i+1); QString tempFile = QString("%1/~%2.wav").arg(m_outputDir, lamexp_rand_str()); connect(decoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection); if(decoder->decode(inputFileList.at(i), tempFile, &m_abortFlag)) { m_decompressedFiles.insert(inputFileList.at(i), tempFile); m_tempFiles.append(tempFile); } else { qWarning("Failed to decompress file: <%s>", inputFileList.at(i).toLatin1().constData()); lamexp_remove_file(tempFile); } m_activeFile.clear(); LAMEXP_DELETE(decoder); } else { qWarning("Unsupported input file: <%s>", inputFileList.at(i).toLatin1().constData()); } }
AboutDialog::~AboutDialog(void) { if(m_disque) { m_disque->close(); LAMEXP_DELETE(m_disque); } if(m_disqueTimer) { m_disqueTimer->stop(); LAMEXP_DELETE(m_disqueTimer); } for(int i = 0; i < 4; i++) { LAMEXP_DELETE(m_cartoon[i]); } }
void ProcessThread::processFile() { m_aborted = false; bool bSuccess = true; qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData()); emit processStateInitialized(m_jobId, QFileInfo(m_audioFile.filePath()).fileName(), tr("Starting..."), ProgressModel::JobRunning); handleMessage(QString().sprintf("LameXP v%u.%02u (Build #%u), compiled on %s at %s", lamexp_version_major(), lamexp_version_minor(), lamexp_version_build(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), lamexp_version_time())); handleMessage("\n-------------------------------\n"); //Generate output file name QString outFileName = generateOutFileName(); if(outFileName.isEmpty()) { emit processStateChanged(m_jobId, tr("Not found!"), ProgressModel::JobFailed); emit processStateFinished(m_jobId, outFileName, false); return; } //Do we need to take care of downsampling the input? if(m_encoder->requiresDownsample()) { insertDownsampleFilter(); } //Do we need Stereo downmix? if(m_encoder->requiresDownmix()) { insertDownmixFilter(); } QString sourceFile = m_audioFile.filePath(); //Decode source file if(!m_filters.isEmpty() || !m_encoder->isFormatSupported(m_audioFile.formatContainerType(), m_audioFile.formatContainerProfile(), m_audioFile.formatAudioType(), m_audioFile.formatAudioProfile(), m_audioFile.formatAudioVersion())) { m_currentStep = DecodingStep; AbstractDecoder *decoder = DecoderRegistry::lookup(m_audioFile.formatContainerType(), m_audioFile.formatContainerProfile(), m_audioFile.formatAudioType(), m_audioFile.formatAudioProfile(), m_audioFile.formatAudioVersion()); if(decoder) { QString tempFile = generateTempFileName(); connect(decoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection); connect(decoder, SIGNAL(messageLogged(QString)), this, SLOT(handleMessage(QString)), Qt::DirectConnection); bSuccess = decoder->decode(sourceFile, tempFile, &m_aborted); LAMEXP_DELETE(decoder); if(bSuccess) { sourceFile = tempFile; handleMessage("\n-------------------------------\n"); } } else {
FileAnalyzer::~FileAnalyzer(void) { if(m_templateFile) { QString templatePath = m_templateFile->filePath(); LAMEXP_DELETE(m_templateFile); if(QFile::exists(templatePath)) QFile::remove(templatePath); } AnalyzeTask::reset(); }
~ArtworkModel_SharedData(void) { if(m_fileHandle) { if(m_isOwner) { m_fileHandle->remove(); } m_fileHandle->close(); LAMEXP_DELETE(m_fileHandle); } }
/* * Destructor */ AbstractTool::~AbstractTool(void) { QMutexLocker lock(&s_mutex_startProcess); if(s_jobObjRefCount >= 1U) { s_jobObjRefCount--; if(s_jobObjRefCount < 1U) { LAMEXP_DELETE(s_jobObject); } } }
ProcessThread::~ProcessThread(void) { while(!m_tempFiles.isEmpty()) { lamexp_remove_file(m_tempFiles.takeFirst()); } while(!m_filters.isEmpty()) { delete m_filters.takeFirst(); } LAMEXP_DELETE(m_encoder); }
int MetaInfoDialog::exec(AudioFileModel &audioFile, bool allowUp, bool allowDown) { MetaInfoModel *model = new MetaInfoModel(&audioFile); tableView->setModel(model); tableView->show(); frameArtwork->hide(); setWindowTitle(tr("Meta Information: %1").arg(QFileInfo(audioFile.filePath()).fileName())); editButton->setEnabled(true); upButton->setEnabled(allowUp); downButton->setEnabled(allowDown); buttonArtwork->setChecked(false); if(!audioFile.fileCover().isEmpty()) { QImage artwork; if(artwork.load(audioFile.fileCover())) { if((artwork.width() > 256) || (artwork.height() > 256)) { artwork = artwork.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation); } labelArtwork->setPixmap(QPixmap::fromImage(artwork)); } else { qWarning("Error: Failed to load cover art!"); labelArtwork->setPixmap(QPixmap::fromImage(QImage(":/images/CD.png"))); } } else { labelArtwork->setPixmap(QPixmap::fromImage(QImage(":/images/CD.png"))); } int iResult = QDialog::exec(); tableView->setModel(NULL); LAMEXP_DELETE(model); return iResult; }
ArtworkModel_SharedData(const QString &filePath, const bool isOwner) : m_isOwner(isOwner), m_filePath(filePath), m_fileHandle(NULL) { m_referenceCounter = 1; if(!m_filePath.isEmpty()) { QFile *file = new QFile(m_filePath); if(file->open(QIODevice::ReadOnly)) { m_fileHandle = file; } else { qWarning("[ArtworkModel] Failed to open artwork file!"); LAMEXP_DELETE(file); } } }
void ArtworkModel:: clear(void) { if(!m_filePath.isEmpty()) { QMutexLocker lock(&m_mutex); if(m_refCount.contains(m_filePath)) { if(--m_refCount[m_filePath] < 1) { m_refCount.remove(m_filePath); if(m_fileHandle.contains(m_filePath)) { if(QFile *fileHandle = m_fileHandle.take(m_filePath)) { if(m_isOwner) { fileHandle->remove(); } else { fileHandle->close(); } LAMEXP_DELETE(fileHandle); } } if(m_isOwner) { QFile::remove(m_filePath); } } } m_filePath.clear(); } }
SettingsModel::~SettingsModel(void) { LAMEXP_DELETE(m_configCache); LAMEXP_DELETE(m_defaultLanguage); }
MetaInfoDialog::~MetaInfoDialog(void) { LAMEXP_DELETE(m_contextMenuInfo); LAMEXP_DELETE(m_contextMenuArtwork); }
void FileAnalyzer::run() { m_abortFlag = false; m_bAborted = false; m_bSuccess = false; int nFiles = m_inputFiles.count(); emit progressMaxChanged(nFiles); emit progressValChanged(0); lamexp_natural_string_sort(m_inputFiles, true); //.sort(); if(!m_templateFile) { if(!createTemplate()) { qWarning("Failed to create template file!"); return; } } AnalyzeTask::reset(); QThreadPool *pool = new QThreadPool(); QThread::msleep(333); pool->setMaxThreadCount(qBound(2, ((QThread::idealThreadCount() * 3) / 2), 12)); while(!(m_inputFiles.isEmpty() || m_bAborted)) { while(!(m_inputFiles.isEmpty() || m_bAborted)) { if(!AnalyzeTask::waitForFreeSlot(&m_abortFlag)) { qWarning("Timeout in AnalyzeTask::waitForFreeSlot() !!!"); } if(m_abortFlag) { MessageBeep(MB_ICONERROR); m_bAborted = true; break; } if(!m_bAborted) { const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst()); AnalyzeTask *task = new AnalyzeTask(currentFile, m_templateFile->filePath(), &m_abortFlag); connect(task, SIGNAL(fileSelected(QString)), this, SIGNAL(fileSelected(QString)), Qt::DirectConnection); connect(task, SIGNAL(progressValChanged(unsigned int)), this, SIGNAL(progressValChanged(unsigned int)), Qt::DirectConnection); connect(task, SIGNAL(progressMaxChanged(unsigned int)), this, SIGNAL(progressMaxChanged(unsigned int)), Qt::DirectConnection); connect(task, SIGNAL(fileAnalyzed(AudioFileModel)), this, SIGNAL(fileAnalyzed(AudioFileModel)), Qt::DirectConnection); pool->start(task); if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles)) { emit progressMaxChanged(nFiles += count); } } } //One of the Analyze tasks may have gathered additional files from a playlist! if(!m_bAborted) { pool->waitForDone(); if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles)) { emit progressMaxChanged(nFiles += count); } } } pool->waitForDone(); LAMEXP_DELETE(pool); if(m_bAborted) { qWarning("Operation cancelled by user!"); return; } qDebug("All files added.\n"); m_bSuccess = true; }
int FileListModel::importFromCsv(QWidget *parent, const QString &inFile) { QFile file(inFile); if(!file.open(QIODevice::ReadOnly)) { return CsvError_FileOpen; } QTextCodec *codec = NULL; QByteArray bomCheck = file.peek(16); if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xef\xbb\xbf")) { codec = QTextCodec::codecForName("UTF-8"); } else if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xff\xfe")) { codec = QTextCodec::codecForName("UTF-16LE"); } else if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xfe\xff")) { codec = QTextCodec::codecForName("UTF-16BE"); } else { const QString systemDefault = tr("(System Default)"); QStringList codecList; codecList.append(systemDefault); codecList.append(lamexp_available_codepages()); QInputDialog *input = new QInputDialog(parent); input->setLabelText(EXPAND(tr("Select ANSI Codepage for CSV file:"))); input->setOkButtonText(tr("OK")); input->setCancelButtonText(tr("Cancel")); input->setTextEchoMode(QLineEdit::Normal); input->setComboBoxItems(codecList); if(input->exec() < 1) { LAMEXP_DELETE(input); return CsvError_Aborted; } if(input->textValue().compare(systemDefault, Qt::CaseInsensitive)) { qDebug("User-selected codec is: %s", input->textValue().toLatin1().constData()); codec = QTextCodec::codecForName(input->textValue().toLatin1().constData()); } else { qDebug("Going to use the system's default codec!"); codec = QTextCodec::codecForName("System"); } LAMEXP_DELETE(input); } bomCheck.clear(); //----------------------// QTextStream stream(&file); stream.setAutoDetectUnicode(false); stream.setCodec(codec); QString headerLine = stream.readLine().simplified(); while(headerLine.isEmpty()) { if(stream.atEnd()) { qWarning("The file appears to be empty!"); return CsvError_FileRead; } qWarning("Skipping a blank line at beginning of CSV file!"); headerLine = stream.readLine().simplified(); } QStringList header = headerLine.split(";", QString::KeepEmptyParts); const int nCols = header.count(); const int nFiles = m_fileList.count(); if(nCols < 1) { qWarning("Header appears to be empty!"); return CsvError_FileRead; } bool *ignore = new bool[nCols]; memset(ignore, 0, sizeof(bool) * nCols); for(int i = 0; i < nCols; i++) { if((header[i] = header[i].trimmed()).isEmpty()) { ignore[i] = true; } } //----------------------// for(int i = 0; i < nFiles; i++) { if(stream.atEnd()) { LAMEXP_DELETE_ARRAY(ignore); return CsvError_Incomplete; } QString line = stream.readLine().simplified(); if(line.isEmpty()) { qWarning("Skipping a blank line in CSV file!"); continue; } QStringList data = line.split(";", QString::KeepEmptyParts); if(data.count() < header.count()) { qWarning("Skipping an incomplete line in CSV file!"); continue; } const QString key = m_fileList[i]; for(int j = 0; j < nCols; j++) { if(ignore[j]) { continue; } else if(CHECK_HDR(header.at(j), "POSITION")) { bool ok = false; unsigned int temp = data.at(j).trimmed().toUInt(&ok); if(ok) m_fileStore[key].metaInfo().setPosition(temp); } else if(CHECK_HDR(header.at(j), "TITLE")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setTitle(temp); } else if(CHECK_HDR(header.at(j), "ARTIST")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setArtist(temp); } else if(CHECK_HDR(header.at(j), "ALBUM")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setAlbum(temp); } else if(CHECK_HDR(header.at(j), "GENRE")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setGenre(temp); } else if(CHECK_HDR(header.at(j), "YEAR")) { bool ok = false; unsigned int temp = data.at(j).trimmed().toUInt(&ok); if(ok) m_fileStore[key].metaInfo().setYear(temp); } else if(CHECK_HDR(header.at(j), "COMMENT")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setComment(temp); } else { qWarning("Unkonw field '%s' will be ignored!", QUTF8(header.at(j))); ignore[j] = true; if(!checkArray(ignore, false, nCols)) { qWarning("No known fields left, aborting!"); return CsvError_NoTags; } } } } //----------------------// LAMEXP_DELETE_ARRAY(ignore); return CsvError_OK; }
ProcessingDialog::~ProcessingDialog(void) { ui->view_log->setModel(NULL); if(m_progressIndicator) { m_progressIndicator->stop(); } if(m_diskObserver) { m_diskObserver->stop(); if(!m_diskObserver->wait(15000)) { m_diskObserver->terminate(); m_diskObserver->wait(); } } if(m_cpuObserver) { m_cpuObserver->stop(); if(!m_cpuObserver->wait(15000)) { m_cpuObserver->terminate(); m_cpuObserver->wait(); } } if(m_ramObserver) { m_ramObserver->stop(); if(!m_ramObserver->wait(15000)) { m_ramObserver->terminate(); m_ramObserver->wait(); } } while(!m_threadList.isEmpty()) { ProcessThread *thread = m_threadList.takeFirst(); thread->terminate(); thread->wait(15000); delete thread; } LAMEXP_DELETE(m_progressIndicator); LAMEXP_DELETE(m_systemTray); LAMEXP_DELETE(m_diskObserver); LAMEXP_DELETE(m_cpuObserver); LAMEXP_DELETE(m_ramObserver); LAMEXP_DELETE(m_progressViewFilterGroup); LAMEXP_DELETE(m_filterInfoLabel); LAMEXP_DELETE(m_filterInfoLabelIcon); LAMEXP_DELETE(m_contextMenu); LAMEXP_DELETE(m_progressModel); WinSevenTaskbar::setOverlayIcon(this, NULL); WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarNoState); LAMEXP_DELETE(ui); }
ProcessingDialog::~ProcessingDialog(void) { ui->view_log->setModel(NULL); if(m_progressIndicator) { m_progressIndicator->stop(); } if(m_diskObserver) { m_diskObserver->stop(); if(!m_diskObserver->wait(15000)) { m_diskObserver->terminate(); m_diskObserver->wait(); } } if(m_cpuObserver) { m_cpuObserver->stop(); if(!m_cpuObserver->wait(15000)) { m_cpuObserver->terminate(); m_cpuObserver->wait(); } } if(m_ramObserver) { m_ramObserver->stop(); if(!m_ramObserver->wait(15000)) { m_ramObserver->terminate(); m_ramObserver->wait(); } } if(m_threadPool) { if(!m_threadPool->waitForDone(100)) { emit abortRunningTasks(); m_threadPool->waitForDone(); } } LAMEXP_DELETE(m_progressIndicator); LAMEXP_DELETE(m_systemTray); LAMEXP_DELETE(m_diskObserver); LAMEXP_DELETE(m_cpuObserver); LAMEXP_DELETE(m_ramObserver); LAMEXP_DELETE(m_progressViewFilterGroup); LAMEXP_DELETE(m_filterInfoLabel); LAMEXP_DELETE(m_filterInfoLabelIcon); LAMEXP_DELETE(m_contextMenu); LAMEXP_DELETE(m_progressModel); LAMEXP_DELETE(m_threadPool); WinSevenTaskbar::setOverlayIcon(this, NULL); WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarNoState); if(m_windowIcon) { lamexp_free_window_icon(m_windowIcon); m_windowIcon = NULL; } LAMEXP_DELETE(ui); }
void SplashScreen::showSplash(QThread *thread) { double opacity = OPACITY_DELTA; const int opacitySteps = qRound(1.0 / OPACITY_DELTA); SplashScreen *splashScreen = new SplashScreen(); bool bTaskBar = false; //Show splash splashScreen->m_canClose = false; splashScreen->setWindowOpacity(opacity); splashScreen->setFixedSize(splashScreen->size()); splashScreen->show(); //Wait for window to show QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); splashScreen->repaint(); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); //Setup the event loop QEventLoop *loop = new QEventLoop(splashScreen); connect(thread, SIGNAL(terminated()), loop, SLOT(quit()), Qt::QueuedConnection); connect(thread, SIGNAL(finished()), loop, SLOT(quit()), Qt::QueuedConnection); //Create timer QTimer *timer = new QTimer(); connect(timer, SIGNAL(timeout()), loop, SLOT(quit())); //Start thread QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); thread->start(); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); //Init taskbar SET_TASKBAR_STATE(true); //Fade in for(int i = 1; i <= opacitySteps; i++) { opacity = (i < opacitySteps) ? (OPACITY_DELTA * static_cast<double>(i)) : 1.0; splashScreen->setWindowOpacity(opacity); splashScreen->update(); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY); SET_TASKBAR_STATE(true); Sleep(FADE_DELAY); } //Start the timer timer->start(30720); //Loop while thread is still running if(bool bIsRunning = THREAD_RUNNING(thread)) { int deadlockCounter = 0; while(bIsRunning) { loop->exec(); if(bIsRunning = THREAD_RUNNING(thread)) { qWarning("Potential deadlock in initialization thread!"); if(++deadlockCounter >= 10) qFatal("Deadlock in initialization thread!"); } } } //Stop the timer timer->stop(); //Fade out for(int i = opacitySteps; i >= 0; i--) { opacity = OPACITY_DELTA * static_cast<double>(i); splashScreen->setWindowOpacity(opacity); splashScreen->update(); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY); Sleep(FADE_DELAY); } //Restore taskbar SET_TASKBAR_STATE(false); //Hide splash splashScreen->m_canClose = true; splashScreen->close(); //Free LAMEXP_DELETE(loop); LAMEXP_DELETE(timer); LAMEXP_DELETE(splashScreen); }
int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplication *application, const QTextCodec *codec) { cueFile.reset(); qDebug("\n[Cue Sheet Import]"); bool bForceLatin1 = false; //Reject very large files, as parsing might take until forever if(cueFile.size() >= 10485760i64) { qWarning("File is very big. Probably not a Cue Sheet. Rejecting..."); return 2; } //Test selected Codepage for decoding errors qDebug("Character encoding is: %s.", codec->name().constData()); const QString replacementSymbol = QString(QChar(QChar::ReplacementCharacter)); QByteArray testData = cueFile.peek(1048576); if((!testData.isEmpty()) && codec->toUnicode(testData.constData(), testData.size()).contains(replacementSymbol)) { qWarning("Decoding error using selected codepage (%s). Enforcing Latin-1.", codec->name().constData()); bForceLatin1 = true; } testData.clear(); //Init text stream QTextStream cueStream(&cueFile); cueStream.setAutoDetectUnicode(false); cueStream.setCodec(bForceLatin1 ? "latin1" : codec->name()); cueStream.seek(0i64); //Create regular expressions QRegExp rxFile("^FILE\\s+(\"[^\"]+\"|\\S+)\\s+(\\w+)$", Qt::CaseInsensitive); QRegExp rxTrack("^TRACK\\s+(\\d+)\\s(\\w+)$", Qt::CaseInsensitive); QRegExp rxIndex("^INDEX\\s+(\\d+)\\s+([0-9:]+)$", Qt::CaseInsensitive); QRegExp rxTitle("^TITLE\\s+(\"[^\"]+\"|\\S+)$", Qt::CaseInsensitive); QRegExp rxPerformer("^PERFORMER\\s+(\"[^\"]+\"|\\S+)$", Qt::CaseInsensitive); QRegExp rxGenre("^REM\\s+GENRE\\s+(\"[^\"]+\"|\\S+)$", Qt::CaseInsensitive); QRegExp rxYear("^REM\\s+DATE\\s+(\\d+)$", Qt::CaseInsensitive); bool bPreamble = true; bool bUnsupportedTrack = false; CueSheetFile *currentFile = NULL; CueSheetTrack *currentTrack = NULL; m_albumTitle.clear(); m_albumPerformer.clear(); m_albumGenre.clear(); m_albumYear = 0; //Loop over the Cue Sheet until all lines were processed for(int lines = 0; lines < INT_MAX; lines++) { if(application) { application->processEvents(); if(lines < 128) Sleep(10); } if(cueStream.atEnd()) { qDebug("End of Cue Sheet file."); break; } QString line = cueStream.readLine().trimmed(); /* --- FILE --- */ if(rxFile.indexIn(line) >= 0) { qDebug("%03d File: <%s> <%s>", lines, rxFile.cap(1).toUtf8().constData(), rxFile.cap(2).toUtf8().constData()); if(currentFile) { if(currentTrack) { if(currentTrack->isValid()) { currentFile->addTrack(currentTrack); currentTrack = NULL; } else { LAMEXP_DELETE(currentTrack); } } if(currentFile->isValid()) { m_files.append(currentFile); currentFile = NULL; } else { LAMEXP_DELETE(currentFile); } } else { LAMEXP_DELETE(currentTrack); } 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(baseDir.absoluteFilePath(UNQUOTE(rxFile.cap(1)))); qDebug("%03d File path: <%s>", lines, currentFile->fileName().toUtf8().constData()); } else { bUnsupportedTrack = true; qWarning("%03d Skipping unsupported file of type '%s'.", lines, rxFile.cap(2).toUtf8().constData()); currentFile = NULL; } bPreamble = false; currentTrack = NULL; continue; } /* --- TRACK --- */ if(rxTrack.indexIn(line) >= 0) { if(currentFile) { qDebug("%03d Track: <%s> <%s>", lines, rxTrack.cap(1).toUtf8().constData(), rxTrack.cap(2).toUtf8().constData()); if(currentTrack) { if(currentTrack->isValid()) { currentFile->addTrack(currentTrack); currentTrack = NULL; } else { LAMEXP_DELETE(currentTrack); } } if(!rxTrack.cap(2).compare("AUDIO", Qt::CaseInsensitive)) { currentTrack = new CueSheetTrack(currentFile, rxTrack.cap(1).toInt()); } else { bUnsupportedTrack = true; qWarning("%03d Skipping unsupported track of type '%s'.", lines, rxTrack.cap(2).toUtf8().constData()); currentTrack = NULL; } } else { LAMEXP_DELETE(currentTrack); } bPreamble = false; continue; } /* --- INDEX --- */ if(rxIndex.indexIn(line) >= 0) { if(currentFile && currentTrack) { qDebug("%03d Index: <%s> <%s>", lines, rxIndex.cap(1).toUtf8().constData(), rxIndex.cap(2).toUtf8().constData()); if(rxIndex.cap(1).toInt() == 1) { currentTrack->setStartIndex(parseTimeIndex(rxIndex.cap(2))); } } continue; } /* --- TITLE --- */ if(rxTitle.indexIn(line) >= 0) { if(bPreamble) { m_albumTitle = UNQUOTE(rxTitle.cap(1)).simplified(); } else if(currentFile && currentTrack) { qDebug("%03d Title: <%s>", lines, rxTitle.cap(1).toUtf8().constData()); currentTrack->setTitle(UNQUOTE(rxTitle.cap(1)).simplified()); } continue; } /* --- PERFORMER --- */ if(rxPerformer.indexIn(line) >= 0) { if(bPreamble) { m_albumPerformer = UNQUOTE(rxPerformer.cap(1)).simplified(); } else if(currentFile && currentTrack) { qDebug("%03d Title: <%s>", lines, rxPerformer.cap(1).toUtf8().constData()); currentTrack->setPerformer(UNQUOTE(rxPerformer.cap(1)).simplified()); } continue; } /* --- GENRE --- */ if(rxGenre.indexIn(line) >= 0) { if(bPreamble) { QString temp = UNQUOTE(rxGenre.cap(1)).simplified(); for(int i = 0; g_lamexp_generes[i]; i++) { if(temp.compare(g_lamexp_generes[i], Qt::CaseInsensitive) == 0) { m_albumGenre = QString(g_lamexp_generes[i]); break; } } } else if(currentFile && currentTrack) { qDebug("%03d Genre: <%s>", lines, rxGenre.cap(1).toUtf8().constData()); QString temp = UNQUOTE(rxGenre.cap(1).simplified()); for(int i = 0; g_lamexp_generes[i]; i++) { if(temp.compare(g_lamexp_generes[i], Qt::CaseInsensitive) == 0) { currentTrack->setGenre(QString(g_lamexp_generes[i])); break; } } } continue; } /* --- YEAR --- */ if(rxYear.indexIn(line) >= 0) { if(bPreamble) { bool ok = false; unsigned int temp = rxYear.cap(1).toUInt(&ok); if(ok) m_albumYear = temp; } else if(currentFile && currentTrack) { qDebug("%03d Year: <%s>", lines, rxPerformer.cap(1).toUtf8().constData()); bool ok = false; unsigned int temp = rxYear.cap(1).toUInt(&ok); if(ok) currentTrack->setYear(temp); } continue; } } //Append the very last track/file that is still pending if(currentFile) { if(currentTrack) { if(currentTrack->isValid()) { currentFile->addTrack(currentTrack); currentTrack = NULL; } else { LAMEXP_DELETE(currentTrack); } } if(currentFile->isValid()) { m_files.append(currentFile); currentFile = NULL; } else { LAMEXP_DELETE(currentFile); } } //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(qMax(0.0, duration)); } } } //Sanity check of track numbers if(nFiles > 0) { bool hasTracks = false; int previousTrackNo = -1; 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 = 0; 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(currentTrackNo <= previousTrackNo) { qWarning("Non-increasing track numbers (%02d -> %02d), Cue Sheet is inconsistent!", previousTrackNo, currentTrackNo); return ErrorInconsistent; } if(trackNo[currentTrackNo]) { qWarning("Track #%02d exists multiple times, Cue Sheet is inconsistent!", currentTrackNo); return ErrorInconsistent; } trackNo[currentTrackNo] = true; previousTrackNo = currentTrackNo; hasTracks = true; } } } if(!hasTracks) { qWarning("Could not find at least one valid track in the Cue Sheet!"); return ErrorInconsistent; } return ErrorSuccess; } else { qWarning("Could not find at least one valid input file in the Cue Sheet!"); return bUnsupportedTrack ? ErrorUnsupported : ErrorBadFile; } }
QFileSystemModelEx::~QFileSystemModelEx() { removeAllFromCache(); LAMEXP_DELETE(m_myIconProvider); }