OSDN Git Service

Set creation/modified time of the encoded file the same value as the original file...
[lamexp/LameXP.git] / src / Dialog_CueImport.cpp
index 6e8367d..81d6694 100644 (file)
@@ -1,11 +1,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 // LameXP - Audio Encoder Front-End
-// Copyright (C) 2004-2012 LoRd_MuldeR <MuldeR2@GMX.de>
+// Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
+// (at your option) any later version, but always including the *additional*
+// restrictions defined in the "License.txt" file.
 //
 // This program is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 #include "Dialog_CueImport.h"
 
+//UIC includes
+#include "UIC_CueSheetImport.h"
+
+//LameXP includes
 #include "Global.h"
 #include "Model_CueSheet.h"
 #include "Model_AudioFile.h"
 #include "Dialog_WorkingBanner.h"
 #include "Thread_FileAnalyzer.h"
 #include "Thread_CueSplitter.h"
+#include "Registry_Decoder.h"
 #include "LockedFile.h"
 
+//MUtils
+#include <MUtils/Global.h>
+#include <MUtils/OSSupport.h>
+#include <MUtils/GUI.h>
+
+//Qt includes
 #include <QFileInfo>
 #include <QMessageBox>
 #include <QTimer>
 // Constructor & Destructor
 ////////////////////////////////////////////////////////////
 
-CueImportDialog::CueImportDialog(QWidget *parent, FileListModel *fileList, const QString &cueFile)
+CueImportDialog::CueImportDialog(QWidget *parent, FileListModel *fileList, const QString &cueFile, const SettingsModel *settings)
 :
        QDialog(parent),
+       ui(new Ui::CueSheetImport),
+       m_fileList(fileList),
        m_cueFileName(cueFile),
-       m_fileList(fileList)
+       m_settings(settings)
 {
        //Init the dialog, from the .ui file
-       setupUi(this);
+       ui->setupUi(this);
 
        //Fix size
        setMinimumSize(this->size());
@@ -64,25 +78,26 @@ CueImportDialog::CueImportDialog(QWidget *parent, FileListModel *fileList, const
        connect(m_model, SIGNAL(modelReset()), this, SLOT(modelChanged()));
        
        //Setup table view
-       treeView->setModel(m_model);
-       treeView->header()->setStretchLastSection(false);
-       treeView->header()->setResizeMode(QHeaderView::ResizeToContents);
-       treeView->header()->setResizeMode(1, QHeaderView::Stretch);
-       treeView->header()->setMovable(false);
-       treeView->setItemsExpandable(false);
+       ui->treeView->setModel(m_model);
+       ui->treeView->header()->setStretchLastSection(false);
+       ui->treeView->header()->setResizeMode(QHeaderView::ResizeToContents);
+       ui->treeView->header()->setResizeMode(1, QHeaderView::Stretch);
+       ui->treeView->header()->setMovable(false);
+       ui->treeView->setItemsExpandable(false);
 
        //Enable up/down button
-       connect(imprtButton, SIGNAL(clicked()), this, SLOT(importButtonClicked()));
-       connect(browseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
-       connect(loadOtherButton, SIGNAL(clicked()), this, SLOT(loadOtherButtonClicked()));
+       connect(ui->imprtButton, SIGNAL(clicked()), this, SLOT(importButtonClicked()));
+       connect(ui->browseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
+       connect(ui->loadOtherButton, SIGNAL(clicked()), this, SLOT(loadOtherButtonClicked()));
 
        //Translate
-       labelHeaderText->setText(QString("<b>%1</b><br>%2").arg(tr("Import Cue Sheet"), tr("The following Cue Sheet will be split and imported into LameXP.")));
+       ui->labelHeaderText->setText(QString("<b>%1</b><br>%2").arg(tr("Import Cue Sheet"), tr("The following Cue Sheet will be split and imported into LameXP.")));
 }
 
 CueImportDialog::~CueImportDialog(void)
 {
-       LAMEXP_DELETE(m_model);
+       MUTILS_DELETE(m_model);
+       MUTILS_DELETE(ui);
 }
 
 ////////////////////////////////////////////////////////////
@@ -110,7 +125,7 @@ int CueImportDialog::exec(void)
                QString text = QString("<nobr>%1</nobr><br><nobr>%2</nobr><br><br><nobr>%3</nobr>").arg(tr("Failed to load the Cue Sheet file:"), QDir::toNativeSeparators(m_cueFileName), tr("The specified file could not be found!")).replace("-", "&minus;");
                QMessageBox::warning(progress, tr("Cue Sheet Error"), text);
                progress->close();
-               LAMEXP_DELETE(progress);
+               MUTILS_DELETE(progress);
                return CueSheetModel::ErrorIOFailure;
        }
 
@@ -140,7 +155,7 @@ int CueImportDialog::exec(void)
 
                QStringList codecList;
                codecList.append(systemDefault);
-               codecList.append(lamexp_available_codepages());
+               codecList.append(MUtils::available_codepages());
 
                QInputDialog *input = new QInputDialog(progress);
                input->setLabelText(EXPAND(tr("Select ANSI Codepage for Cue Sheet file:")));
@@ -152,8 +167,8 @@ int CueImportDialog::exec(void)
                if(input->exec() < 1)
                {
                        progress->close();
-                       LAMEXP_DELETE(input);
-                       LAMEXP_DELETE(progress);
+                       MUTILS_DELETE(input);
+                       MUTILS_DELETE(progress);
                        return Rejected;
                }
        
@@ -168,17 +183,21 @@ int CueImportDialog::exec(void)
                        codec = QTextCodec::codecForName("System");
                }
 
-               LAMEXP_DELETE(input);
+               MUTILS_DELETE(input);
        }
 
        bomCheck.clear();
 
        //----------------------//
 
-       m_outputDir = QString("%1/%2").arg(cueFileInfo.canonicalPath(), cueFileInfo.completeBaseName());
-       for(int n = 2; QDir(m_outputDir).exists(); n++)
+       QString baseName = cueFileInfo.completeBaseName().simplified();
+       while(baseName.endsWith(".") || baseName.endsWith(" ")) baseName.chop(1);
+       if(baseName.isEmpty()) baseName = tr("New Folder");
+
+       m_outputDir = QString("%1/%2").arg(cueFileInfo.canonicalPath(), baseName);
+       for(int n = 2; QDir(m_outputDir).exists() || QFileInfo(m_outputDir).exists(); n++)
        {
-               m_outputDir = QString("%1/%2 (%3)").arg(cueFileInfo.canonicalPath(), cueFileInfo.completeBaseName(), QString::number(n));
+               m_outputDir = QString("%1/%2 (%3)").arg(cueFileInfo.canonicalPath(), baseName, QString::number(n));
        }
 
        setWindowTitle(QString("%1: %2").arg(windowTitle().split(":", QString::SkipEmptyParts).first().trimmed(), cueFileInfo.fileName()));
@@ -207,34 +226,42 @@ int CueImportDialog::exec(void)
                QString text = QString("<nobr>%1</nobr><br><nobr>%2</nobr><br><br><nobr>%3</nobr>").arg(tr("Failed to load the Cue Sheet file:"), QDir::toNativeSeparators(m_cueFileName), errorMsg).replace("-", "&minus;");
                QMessageBox::warning(progress, tr("Cue Sheet Error"), text);
                progress->close();
-               LAMEXP_DELETE(progress);
+               MUTILS_DELETE(progress);
                return iResult;
        }
        
        progress->close();
-       LAMEXP_DELETE(progress);
+       MUTILS_DELETE(progress);
        return QDialog::exec();
 }
 
 void CueImportDialog::modelChanged(void)
 {
-       treeView->expandAll();
-       editOutputDir->setText(QDir::toNativeSeparators(m_outputDir));
-       labelArtist->setText(m_model->getAlbumPerformer().isEmpty() ? tr("Unknown Artist") : m_model->getAlbumPerformer());
-       labelAlbum->setText(m_model->getAlbumTitle().isEmpty() ? tr("Unknown Album") : m_model->getAlbumTitle());
+       ui->treeView->expandAll();
+       ui->editOutputDir->setText(QDir::toNativeSeparators(m_outputDir));
+       if(const AudioFileModel_MetaInfo *albumInfo = m_model->getAlbumInfo())
+       {
+               ui->labelArtist->setText(albumInfo->artist().isEmpty() ? tr("Unknown Artist") : albumInfo->artist());
+               ui->labelAlbum->setText(albumInfo->album().isEmpty() ? tr("Unknown Album") : albumInfo->album());
+       }
 }
 
 void CueImportDialog::browseButtonClicked(void)
 {
-       QString newOutDir, currentDir = m_outputDir;
-       
-       while(QDir(currentDir).exists())
+       QString currentDir = QDir::fromNativeSeparators(m_outputDir);
+       while(!QDir(currentDir).exists())
        {
-               int pos = qMax(currentDir.lastIndexOf(QChar('\\')), currentDir.lastIndexOf(QChar('/')));
-               if(pos > 0) currentDir.left(pos - 1); else break;
+               const int pos = currentDir.lastIndexOf(QChar('/'));
+               if(pos > 2)
+               {
+                       currentDir = currentDir.left(pos);
+                       continue;
+               }
+               break;
        }
 
-       if(lamexp_themes_enabled() || ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) < QSysInfo::WV_XP))
+       QString newOutDir;
+       if(MUtils::GUI::themes_enabled())
        {
                newOutDir = QFileDialog::getExistingDirectory(this, tr("Choose Output Directory"), currentDir);
        }
@@ -270,7 +297,7 @@ void CueImportDialog::importButtonClicked(void)
                return;
        }
 
-       QFile writeTest(QString("%1/~%2.txt").arg(m_outputDir, lamexp_rand_str()));
+       QFile writeTest(QString("%1/~%2.txt").arg(m_outputDir, MUtils::rand_str()));
        if(!(writeTest.open(QIODevice::ReadWrite) && (writeTest.write(writeTestBuffer) == strlen(writeTestBuffer))))
        {
                QMessageBox::warning(this, tr("LameXP"), QString("<nobr>%2</nobr>").arg(tr("Error: The selected output directory is not writable!")));
@@ -282,13 +309,14 @@ void CueImportDialog::importButtonClicked(void)
                writeTest.remove();
        }
 
-       bool ok = false;
-       unsigned __int64 currentFreeDiskspace = lamexp_free_diskspace(m_outputDir, &ok);
-
-       if(ok && (currentFreeDiskspace < (oneGigabyte * minimumFreeDiskspaceMultiplier)))
+       quint64 currentFreeDiskspace = 0;
+       if(MUtils::OS::free_diskspace(m_outputDir, currentFreeDiskspace))
        {
-               QMessageBox::warning(this, tr("Low Diskspace Warning"), QString("<nobr>%1</nobr><br><nobr>%2</nobr>").arg(tr("There are less than %1 GB of free diskspace available in the selected output directory.").arg(QString::number(minimumFreeDiskspaceMultiplier)), tr("It is highly recommend to free up more diskspace before proceeding with the import!")));
-               return;
+               if(currentFreeDiskspace < (oneGigabyte * minimumFreeDiskspaceMultiplier))
+               {
+                       QMessageBox::warning(this, tr("Low Diskspace Warning"), QString("<nobr>%1</nobr><br><nobr>%2</nobr>").arg(tr("There are less than %1 GB of free diskspace available in the selected output directory.").arg(QString::number(minimumFreeDiskspaceMultiplier)), tr("It is highly recommend to free up more diskspace before proceeding with the import!")));
+                       return;
+               }
        }
 
        importCueSheet();
@@ -302,7 +330,7 @@ void CueImportDialog::loadOtherButtonClicked(void)
 
 void CueImportDialog::analyzedFile(const AudioFileModel &file)
 {
-       qDebug("Received result: <%s> <%s/%s>", file.filePath().toLatin1().constData(), file.formatContainerType().toLatin1().constData(), file.formatAudioType().toLatin1().constData());
+       qDebug("Received result: <%s> <%s/%s>", file.filePath().toLatin1().constData(), file.techInfo().containerType().toLatin1().constData(), file.techInfo().audioType().toLatin1().constData());
        m_fileInfo << file;
 }
 
@@ -313,35 +341,52 @@ void CueImportDialog::analyzedFile(const AudioFileModel &file)
 void CueImportDialog::importCueSheet(void)
 {
        QStringList files;
+       QList<LockedFile*> locks;
 
        //Fetch all files that are referenced in the Cue Sheet and lock them
        int nFiles = m_model->getFileCount();
        for(int i = 0; i < nFiles; i++)
        {
-               QString temp = m_model->getFileName(i);
                try
                {
-                       m_locks << new LockedFile(temp);
+                       LockedFile *temp = new LockedFile(m_model->getFileName(i));
+                       locks << temp;
+                       files << temp->filePath();
                }
-               catch(char *err)
+               catch(const std::exception &error)
                {
-                       qWarning("Failed to lock file: %s", err);
-                       continue;
+                       qWarning("Failed to lock file:\n%s\n", error.what());
+               }
+               catch(...)
+               {
+                       qWarning("Failed to lock file!");
                }
-               files << temp;
        }
-       
-       //Analyze all source files first
-       if(analyzeFiles(files))
+
+       //Check if all files could be locked
+       if(files.count() < m_model->getFileCount())
        {
-               //Now split files according to Cue Sheet
-               splitFiles();
+               if(QMessageBox::warning(this, tr("Cue Sheet Error"), tr("Warning: Some of the required input files could not be found!"), tr("Continue Anyway"), tr("Abort")) == 1)
+               {
+                       files.clear();
+               }
+       }
+
+       //Process all avialble input files
+       if(files.count() > 0)
+       {
+               //Analyze all source files first
+               if(analyzeFiles(files))
+               {
+                       //Now split files according to Cue Sheet
+                       splitFiles();
+               }
        }
        
        //Release locks
-       while(!m_locks.isEmpty())
+       while(!locks.isEmpty())
        {
-               delete m_locks.takeFirst();
+               delete locks.takeFirst();
        }
 }
 
@@ -368,8 +413,8 @@ bool CueImportDialog::analyzeFiles(QStringList &files)
                }
        }
 
-       LAMEXP_DELETE(progress);
-       LAMEXP_DELETE(analyzer);
+       MUTILS_DELETE(progress);
+       MUTILS_DELETE(analyzer);
 
        return bSuccess;
 }
@@ -387,12 +432,14 @@ void CueImportDialog::splitFiles(void)
        connect(splitter, SIGNAL(progressMaxChanged(unsigned int)), progress, SLOT(setProgressMax(unsigned int)), Qt::QueuedConnection);
        connect(progress, SIGNAL(userAbort()), splitter, SLOT(abortProcess()), Qt::DirectConnection);
 
+       DecoderRegistry::configureDecoders(m_settings);
+
        progress->show(tr("Splitting file(s), please wait..."), splitter);
        progress->close();
 
-       if(splitter->getAborted())      
+       if(splitter->getAborted())
        {
-               QMessageBox::warning(this, tr("Cue Sheet Error"), tr("Process was aborted by the user after %1 track(s)!").arg(QString::number(splitter->getTracksSuccess())));
+               QMessageBox::warning(this, tr("Cue Sheet Error"), tr("Process was aborted by the user after %n track(s)!", "", splitter->getTracksSuccess()));
        }
        else if(!splitter->getSuccess())
        {
@@ -400,10 +447,10 @@ void CueImportDialog::splitFiles(void)
        }
        else
        {
-               QString text = QString("<nobr>%1</nobr>").arg(tr("Imported %1 track(s) from the Cue Sheet and skipped %2 track(s).").arg(QString::number(splitter->getTracksSuccess()), QString::number(splitter->getTracksSkipped() /*+ nTracksSkipped*/)));
+               QString text = QString("<nobr>%1 %2</nobr>").arg(tr("Imported %n track(s) from the Cue Sheet.", "", splitter->getTracksSuccess()), tr("Skipped %n track(s).", "", splitter->getTracksSkipped()));
                QMessageBox::information(this, tr("Cue Sheet Completed"), text);
        }
 
-       LAMEXP_DELETE(splitter);
-       LAMEXP_DELETE(progress);
+       MUTILS_DELETE(splitter);
+       MUTILS_DELETE(progress);
 }