diff --git a/Windows/Batch Processor/abort.ui b/Windows/Batch Processor/abort.ui new file mode 100644 index 0000000..6a341ff --- /dev/null +++ b/Windows/Batch Processor/abort.ui @@ -0,0 +1,78 @@ + + + Abort + + + + 0 + 0 + 400 + 113 + + + + Abort Confirmation + + + + + + + + Are you sure you want to abort? + + + Qt::AlignCenter + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::No|QDialogButtonBox::Yes + + + + + + + + + buttonBox + accepted() + Abort + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Abort + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Windows/Batch Processor/main.cpp b/Windows/Batch Processor/main.cpp new file mode 100644 index 0000000..b48f94e --- /dev/null +++ b/Windows/Batch Processor/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/Windows/Batch Processor/mainwindow.cpp b/Windows/Batch Processor/mainwindow.cpp new file mode 100644 index 0000000..03c4163 --- /dev/null +++ b/Windows/Batch Processor/mainwindow.cpp @@ -0,0 +1,373 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "ui_abort.h" + +Abort::Abort(QWidget *parent) : + QDialog(parent), + ui(new Ui::Abort) +{ + ui->setupUi(this); +} + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + model = new QStandardItemModel; + ui->inView->setModel(model); + model2 = new QStandardItemModel; + process = new QProcess(this); + process->setProcessChannelMode(QProcess::MergedChannels); + ui->outView->setModel(model2); + connect(process, SIGNAL (readyReadStandardOutput()), this, SLOT (opu())); + connect(process, SIGNAL(finished(int , QProcess::ExitStatus )), this, SLOT(dtTrigger(int , QProcess::ExitStatus ))); + connect(ui->abBu, SIGNAL(released()), this, SLOT(halt())); + MainWindow::stop = false; + batchInit(); +} + +void MainWindow::halt() { + Abort abt; + if (abt.exec()) { + MainWindow::stop = true; + process->kill(); + abt.deleteLater(); + } + else { + abt.deleteLater(); + } +} + +void MainWindow::batchInit() { + MainWindow::bDir = QFileDialog::getExistingDirectory(this, "Select folder containing FLAC and CUE files...", QDir::homePath()); + if (MainWindow::bDir.isEmpty()) { + ui->statusbar->showMessage( "ERROR: No Folder Specified"); + return; + }QDirIterator it(MainWindow::bDir, QDirIterator::Subdirectories); + while (it.hasNext()) { + if (it.fileName().contains(".cue")) { + MainWindow::jobs.append(it.filePath()); + }it.next(); + }MainWindow::jSize = MainWindow::jobs.size(); + QVariant bS(MainWindow::jSize); + ui->bSize->setText(bS.toString()); + MainWindow::bCount = 0; + batchDo(); +} + + + +void MainWindow::bTrigger () { + batchDo(); +} + +void MainWindow::batchDo() { + MainWindow::bCount++; + if (MainWindow::jobs.size() != MainWindow::jSize) { + if (MainWindow::jobs.size() == 0) { + ui->tProBar->setValue(100); + ui->bCurr->setText(ui->bSize->text()); + if (!MainWindow::errList.isEmpty()) { + ui->cmdout->append("Batch job completed but the Following Jobs encountered errors."); + for (int i = 0; i < MainWindow::errList.size(); i++) { + ui->cmdout->append(MainWindow::errList[i]); + } + }else { + ui->cmdout->append("Batch job completed with no fatal errors."); + }ui->statusbar->showMessage("Job Complete."); + }else { + QVariant c(MainWindow::bCount); + QString cs = c.toString(); + ui->bCurr->setText(cs); + } + }else{ + ui->bCurr->setText("1"); + }if (MainWindow::jobs.size() != 0) { + MainWindow::cue = MainWindow::jobs[0]; + ui->cmdout->append(MainWindow::jobs[0]); + MainWindow::jobs.removeFirst(); + processCUE(); + } +} + +void MainWindow::doTrack(int ex) { + if (MainWindow::stop) { + QApplication::quit(); + } + if (MainWindow::cmds.size() != MainWindow::Tracks.size()) { + if (MainWindow::count != 0) { + if (ex == 1) { + QVariant c(MainWindow::count); + QString cs = c.toString(); + MainWindow::errs.append(cs); + } + } + }if (MainWindow::cmds.size() == 0) { + if (!MainWindow::errs.isEmpty()) { + QString err = MainWindow::errs.join(", "); + ui->cProBar->setValue(100); + MainWindow::errList.append("Job " + MainWindow::cue + " encountered problems with the following tracks " + err + "."); + }int progress = 100 / MainWindow::jSize; + int tpro = progress * MainWindow::bCount; + ui->tProBar->setValue(tpro); + rA(0); + batchDo(); + }else { + QVariant c(MainWindow::count + 1); + QString cs = c.toString(); + QVariant ts(MainWindow::Tracks.size()); + QString tss = ts.toString(); + ui->statusbar->showMessage("Encoding file " + cs + " of " + tss + "."); + process->start(MainWindow::cmds[0]); + MainWindow::cmds.removeFirst(); + int progress = 100 / MainWindow::Tracks.size(); + int cc = MainWindow::count; + int cpro = progress * cc; + ui->cProBar->setValue(cpro); + MainWindow::count++; + } +} + +void MainWindow::processCUE() { + ui->cFileLabel->setText(MainWindow::cue); + bool first = true; + int trackCount = 0; + int linecount = 0; + QStringList lines; + QFile file(MainWindow::cue); + file.open(QIODevice::ReadOnly); + QTextStream in (&file); + QString line; + do { + line = in.readLine(); + lines.append(line); + } + while (!line.isNull()); + foreach(const QString &str, lines) + { + QMap tmap; + linecount++; + QString sr = str.simplified(); + if(sr.contains("PERFORMER", Qt::CaseSensitive)) { + MainWindow::pa = sr.mid(11); + MainWindow::pa.chop(1); + }else if(sr.contains("REM DATE", Qt::CaseSensitive)) { + MainWindow::year = sr.right(4); + }else if(sr.contains("REM GENRE", Qt::CaseSensitive)) { + MainWindow::genre = sr.mid(10); + MainWindow::genre.remove("\""); + }else if(sr.contains("FILE", Qt::CaseSensitive)) { + QString fs = str.mid(6); + fs.chop(6); + QVariant lcf(linecount); + QString flc = lcf.toString(); + QMap fmap; + fmap["file"] = fs; + fmap["lind"] = flc; + fmap["aArt"] = MainWindow::pa; + MainWindow::Files.append(fmap); + }else if(sr.contains("TITLE", Qt::CaseSensitive)) { + MainWindow::tra = sr.mid(7); + MainWindow::tra.chop(1); + if(first == true) { + first = false; + }else { + trackCount++; + }QVariant tcs(trackCount); + MainWindow::tc = tcs.toString(); + }else if(sr.contains("TRACK 01", Qt::CaseSensitive)) { + MainWindow::al = MainWindow::tra; + }else if(sr.contains("INDEX 01", Qt::CaseSensitive)) { + QString tind = sr.right(8); + QVariant lcs(linecount); + QString lc = lcs.toString(); + tmap["num"] = MainWindow::tc; + tmap["tind"] = tind; + tmap["lind"] = lc; + tmap["title"] = MainWindow::tra; + if (!pa.isEmpty()) { + tmap["artist"] = MainWindow::pa; + }if (!year.isEmpty()) { + tmap["year"] = MainWindow::year; + }if (!genre.isEmpty()) { + tmap["genre"] = MainWindow::genre; + }MainWindow::Tracks.append(tmap); + } + }first = true; + QVectorIterator> fIt(MainWindow::Files); + while (fIt.hasNext()) { + if (fIt.peekNext().value("file").contains(".flac")) { + QFileInfo fld(MainWindow::cue); + QString dir = fld.absolutePath(); + QString file = dir + "/" + fIt.peekNext().value("file"); + ui->cmdout->append(file); + if(!QFileInfo(file).exists()) { + ui->statusbar->showMessage("ERROR: Input file(s) does not exist."); + rA(1); + return; + }else { + QStandardItem *q = new QStandardItem(fIt.next().value("file")); + MainWindow::model->appendRow(q); + } + }else { + ui->statusbar->showMessage("ERROR: Input file(s) not in FLAC format."); + rA(1); + return; + } + }QVectorIterator> tIt(MainWindow::Tracks); + while (tIt.hasNext()) { + QStandardItem *q = new QStandardItem("Track " + tIt.peekNext().value("num") + " - " + tIt.peekNext().value("title")); + tIt.next(); + MainWindow::model2->appendRow(q); + }if (MainWindow::Files.size() == 1) { + MainWindow::dual = 1; + }else { + MainWindow::dual = 2; + }if (MainWindow::cue.isEmpty() || MainWindow::Tracks.isEmpty()|| MainWindow::Files.isEmpty()) { + ui->statusbar->showMessage("ERROR: Nothing to split."); + return; + }if (MainWindow::dual == 0) { + ui->statusbar->showMessage("ERROR: Invalid Format."); + return; + }bool last = false; + int bcount = 0; + QFileInfo fld(MainWindow::cue); + QString wdir = fld.absolutePath(); + tIt.toFront(); + tIt.next(); + while (tIt.hasNext()) { + QStringList start, end; + QString tn, namestr, amestr, side, ifile, cmd; + QMap it; + ifile = MainWindow::Files[0].value("file"); + if (last == true) { + it = tIt.peekNext(); + }else { + it = tIt.peekPrevious(); + }if (MainWindow::dual == 2) { + if (MainWindow::Files.size() == 2) { + if (last == true) { + side = "B"; + }else { + tn = tIt.peekPrevious().value("num"); + }if (tIt.peekPrevious().value("lind").toInt() < MainWindow::Files[1].value("lind").toInt()) { + side = "A"; + }else { + side = "B"; + }if (side.contains("B")) { + ifile = MainWindow::Files[1].value("file"); + bcount++; + QVariant bc(bcount); + QString bcs = bc.toString(); + tn = bcs; + } + }else { + ui->statusbar->showMessage("ERROR: CUEs with over 2 input files not currently supported."); + return; + }if (first){ + end = tIt.peekNext().value("tind").split(":"); + }else if (last == true) { + start = tIt.peekNext().value("tind").split(":"); + }else { + if (tIt.peekNext().value("tind").contains("00:00:00")) { + start = tIt.peekPrevious().value("tind").split(":"); + }else if (tIt.peekPrevious().value("tind").contains("00:00:00")) { + end = tIt.peekNext().value("tind").split(":"); + }else { + start = tIt.peekPrevious().value("tind").split(":"); + end = tIt.peekNext().value("tind").split(":"); + } + }amestr = side + tn + " - " + it.value("title") + ".flac"; + }else { + if (first){ + end = tIt.peekNext().value("tind").split(":"); + }else if (last == true) { + start = tIt.peekNext().value("tind").split(":"); + }else { + start = tIt.peekPrevious().value("tind").split(":"); + end = tIt.peekNext().value("tind").split(":"); + }if(it.value("num").length() == 1) { + tn = "0" + it.value("num"); + }else { + tn = it.value("num"); + }amestr = tn + " - " + it.value("title") + ".flac"; + }namestr = validateNamestr(amestr); + QString c = "flac.exe --best "; + if (it.contains("artist")) { + c = c + "-T \"ARTIST= " + it.value("artist") + "\" "; + }if (it.contains("year")) { + c = c + "-T \"DATE= " + it.value("year") + "\" "; + }if (it.contains("genre")) { + c = c + "-T \"GENRE= " + it.value("genre") + "\" "; + }if (start.isEmpty()) { + cmd = c + "-T \"TRACKNUMBER=" + tIt.peekPrevious().value("num") + "\" -T \"ALBUM=" + MainWindow::al + "\" " + "-T \"TITLE=" + tIt.peekPrevious().value("title") + "\" " + "--until=" + end[0] + ":" + end[1] + "." + end[2] + " \"" + wdir + "/" + ifile + "\" -o \"" + wdir + "/" + namestr + "\""; + }else if (end.isEmpty()) { + cmd = c + "-T \"TRACKNUMBER=" + it.value("num") + "\" -T \"ALBUM=" + MainWindow::al + "\" " + "-T \"TITLE=" + it.value("title") + "\" " + "--skip=" + start[0] + ":" + start[1] + "." + start[2] + " \"" + wdir + "/" + ifile + "\" -o \"" + wdir + "/" + namestr + "\""; + }else { + cmd = c + "-T \"TRACKNUMBER=" + tIt.peekPrevious().value("num") + "\" -T \"ALBUM=" + MainWindow::al + "\" " + "-T \"TITLE=" + tIt.peekPrevious().value("title") + "\" " + "--skip=" + start[0] + ":" + start[1] + "." + start[2] + " --until=" + end[0] + ":" + end[1] + "." + end[2] + " \"" + wdir + "/" + ifile + "\" -o \"" + wdir + "/" + namestr + "\""; + }MainWindow::cmds.append(cmd); + first = false; + tIt.next(); + if (!tIt.hasNext()) { + if (last) { + QVariant fas(MainWindow::Tracks.size()); + QString fass = fas.toString(); + ui->statusbar->showMessage("Encoding file 1 of " + fass + "."); + break; + }else { + tIt.previous(); + last = true; + } + } + }MainWindow::count = 0; + doTrack(0); +} + +void MainWindow::rA(int e) { + ui->cProBar->setValue(0); + MainWindow::model->clear(); + MainWindow::model2->clear(); + MainWindow::Files.clear(); + MainWindow::Tracks.clear(); + MainWindow::cmds.clear(); + MainWindow::errs.clear(); + MainWindow::count = 0; + MainWindow::cue.clear(); +} + +QString MainWindow::validateNamestr(QString str) { + QString illChars = "\\ | / : ? ! \" < >"; + QStringList illCharArr = illChars.split(" ", QString::SkipEmptyParts); + QList::iterator ici; + for (ici = illCharArr.begin(); ici != illCharArr.end(); ++ici){ + str.remove(*ici); + }return str; +} + +void MainWindow::dtTrigger(int d , QProcess::ExitStatus) { + doTrack(d); +} + +void MainWindow::opu() { + QString otpt(process->readAllStandardOutput()); + if (otpt.contains(", ratio=")) { + QTextCursor storeCursorPos = ui->cmdout->textCursor(); + ui->cmdout->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); + ui->cmdout->moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); + ui->cmdout->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor); + ui->cmdout->textCursor().removeSelectedText(); + ui->cmdout->textCursor().deletePreviousChar(); + ui->cmdout->setTextCursor(storeCursorPos); + }ui->cmdout->append(otpt); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +Abort::~Abort() +{ + delete ui; +} \ No newline at end of file diff --git a/Windows/Batch Processor/mainwindow.h b/Windows/Batch Processor/mainwindow.h new file mode 100644 index 0000000..46f80e3 --- /dev/null +++ b/Windows/Batch Processor/mainwindow.h @@ -0,0 +1,59 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { +class MainWindow; +class Abort; +} + +class Abort : public QDialog +{ + Q_OBJECT +public: + explicit Abort(QWidget *parent = 0); + ~Abort(); +private: + Ui::Abort *ui; +}; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + QString MainWindow::cue, MainWindow::pa, MainWindow::tra, MainWindow::genre, MainWindow::year, MainWindow::tc, MainWindow::al, MainWindow::bDir; + QStandardItemModel *MainWindow::model; + QStandardItemModel *MainWindow::model2; + QProcess *MainWindow::process; + QStringList MainWindow::cmds, MainWindow::errs, MainWindow::errList, MainWindow::jobs; + QVector> MainWindow::Files, MainWindow::Tracks; + int MainWindow::dual, MainWindow::count, MainWindow::jSize, MainWindow::bCount; + bool MainWindow::stop; + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private: + Ui::MainWindow *ui; +private slots: + void processCUE(); + void rA(int); + QString validateNamestr(QString); + void doTrack(int); + void dtTrigger(int , QProcess::ExitStatus); + void opu(); + void batchInit(); + void batchDo(); + void bTrigger(); + void halt(); +}; + +#endif // MAINWINDOW_H diff --git a/Windows/Batch Processor/mainwindow.ui b/Windows/Batch Processor/mainwindow.ui new file mode 100644 index 0000000..3474904 --- /dev/null +++ b/Windows/Batch Processor/mainwindow.ui @@ -0,0 +1,197 @@ + + + MainWindow + + + + 0 + 0 + 796 + 769 + + + + CUEy Batch Processor + + + + + + + + + Processing File + + + + + + + - + + + + + + + of + + + + + + + - + + + + + + + + + + + + 0 + 0 + + + + Current CUE File: + + + + + + + + 0 + 0 + + + + None + + + + + + + + + + + Current Job Progress + + + + + + + 0 + + + + + + + + + + + Total Progress + + + + + + + 0 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Input Files + + + + + + + Output Files + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Console Log: + + + + + + + + + + + + Abort + + + + + + + + + + + diff --git a/Windows/Main Application/abort.ui b/Windows/Main Application/abort.ui new file mode 100644 index 0000000..6a341ff --- /dev/null +++ b/Windows/Main Application/abort.ui @@ -0,0 +1,78 @@ + + + Abort + + + + 0 + 0 + 400 + 113 + + + + Abort Confirmation + + + + + + + + Are you sure you want to abort? + + + Qt::AlignCenter + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::No|QDialogButtonBox::Yes + + + + + + + + + buttonBox + accepted() + Abort + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Abort + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Windows/Main Application/dialog.ui b/Windows/Main Application/dialog.ui new file mode 100644 index 0000000..7ba02d5 --- /dev/null +++ b/Windows/Main Application/dialog.ui @@ -0,0 +1,102 @@ + + + Dialog + + + true + + + + 0 + 0 + 373 + 166 + + + + Errors Encountered + + + + + + + 0 + 0 + + + + + Segoe UI + 8 + + + + The following tracks failed to encode: + + + Qt::AlignCenter + + + true + + + + + + + + 0 + 0 + + + + + 75 + false + true + + + + Check console log for more details. + + + + + + + + 0 + 0 + + + + QDialogButtonBox::Ok + + + true + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 186 + 140 + + + 186 + 82 + + + + + diff --git a/Windows/Main Application/errdia.ui b/Windows/Main Application/errdia.ui new file mode 100644 index 0000000..7ba02d5 --- /dev/null +++ b/Windows/Main Application/errdia.ui @@ -0,0 +1,102 @@ + + + Dialog + + + true + + + + 0 + 0 + 373 + 166 + + + + Errors Encountered + + + + + + + 0 + 0 + + + + + Segoe UI + 8 + + + + The following tracks failed to encode: + + + Qt::AlignCenter + + + true + + + + + + + + 0 + 0 + + + + + 75 + false + true + + + + Check console log for more details. + + + + + + + + 0 + 0 + + + + QDialogButtonBox::Ok + + + true + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 186 + 140 + + + 186 + 82 + + + + + diff --git a/Windows/Main Application/main.cpp b/Windows/Main Application/main.cpp new file mode 100644 index 0000000..87d535c --- /dev/null +++ b/Windows/Main Application/main.cpp @@ -0,0 +1,12 @@ +#include "mainwindow.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + a.setWindowIcon(QIcon("icon.ico")); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/Windows/Main Application/mainwindow.cpp b/Windows/Main Application/mainwindow.cpp new file mode 100644 index 0000000..a38186d --- /dev/null +++ b/Windows/Main Application/mainwindow.cpp @@ -0,0 +1,468 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "ui_dialog.h" +#include "ui_abort.h" + +Abort::Abort(QWidget *parent) : + QDialog(parent), + ui(new Ui::Abort) +{ + ui->setupUi(this); +} + + +Dialog::Dialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::Dialog) +{ + ui->setupUi(this); +} + +void Dialog::setTxt(QString txt) { + ui->errtxt->setText(txt); +} + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + MainWindow::dual, MainWindow::count = 0; + connect(ui->impBu, SIGNAL(released()), this, SLOT(iBut())); + connect(ui->clearBu, SIGNAL(released()), this, SLOT(cBut())); + connect(ui->goBu, SIGNAL(released()), this, SLOT(split())); + connect(ui->abBu, SIGNAL(released()), this, SLOT(halt())); + ui->abBu->setDisabled(true); + ui->clearBu->setDisabled(true); + ui->goBu->setDisabled(true); + connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(ex())); + connect(ui->actionBatch, SIGNAL(triggered()), this, SLOT(batch())); + connect(ui->actionImport, SIGNAL(triggered()), this, SLOT(iBut())); + MainWindow::stop = false; + model = new QStandardItemModel; + ui->inView->setModel(model); + model2 = new QStandardItemModel; + proPal = ui->progressBar->palette(); + process = new QProcess(this); + process->setProcessChannelMode(QProcess::MergedChannels); + ui->outView->setModel(model2); + ui->statusbar->showMessage("Ready."); + setAcceptDrops(true); + connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(opu())); + connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(dtTrigger(int, QProcess::ExitStatus))); + if (QApplication::arguments().size() > 1) { + MainWindow::cue = QApplication::arguments().at(1); + fImport(); + } +} + +void MainWindow::halt() { + Abort abt; + if (abt.exec()) { + MainWindow::stop = true; + process->kill(); + abt.deleteLater(); + } + else { + abt.deleteLater(); + } +} + +void MainWindow::batch() { + QProcess::startDetached("CUEy-Batch.exe"); + QApplication::quit(); +} + +void MainWindow::ex() { + QApplication::quit(); +} + +void MainWindow::dtTrigger(int d, QProcess::ExitStatus) { + doTrack(d); +} + +void MainWindow::dragEnterEvent(QDragEnterEvent *e) +{ + const QMimeData* mimeData = e->mimeData(); + if (mimeData->hasUrls()) { + e->acceptProposedAction(); + } + else { + e->ignore(); + } +} + +void MainWindow::dropEvent(QDropEvent *e) +{ + const QMimeData* mimeData = e->mimeData(); + if (mimeData->hasUrls()) { + QString ifile; + QList urlList = mimeData->urls(); + if (urlList.size() == 1) { + rA(0); + ifile = urlList.at(0).toLocalFile(); + MainWindow::cue = ifile; + MainWindow::fImport(); + } + else { + ui->statusbar->showMessage("ERROR: Can only import 1 File."); + e->ignore(); + } + } +} +void MainWindow::iBut() { + QString filter = "CUE Files (*.cue)"; + MainWindow::cue = QFileDialog::getOpenFileName(this, "Select a file...", QDir::homePath(), filter); + if (MainWindow::cue.isEmpty()) { + ui->statusbar->showMessage("ERROR: No File Specified."); + return; + } + MainWindow::fImport(); +} + +void MainWindow::cBut() { + rA(0); +} + + +void MainWindow::fImport() { + bool first = true; + int trackCount = 0; + int linecount = 0; + QStringList lines; + QFile file(MainWindow::cue); + file.open(QIODevice::ReadOnly); + QTextStream in(&file); + QString line; + do { + line = in.readLine(); + lines.append(line); + } while (!line.isNull()); + foreach(const QString &str, lines) + { + QMap tmap; + linecount++; + QString sr = str.simplified(); + if (sr.contains("PERFORMER", Qt::CaseSensitive)) { + MainWindow::pa = sr.mid(11); + MainWindow::pa.chop(1); + } + else if (sr.contains("REM DATE", Qt::CaseSensitive)) { + MainWindow::year = sr.right(4); + } + else if (sr.contains("REM GENRE", Qt::CaseSensitive)) { + MainWindow::genre = sr.mid(10); + MainWindow::genre.remove("\""); + } + else if (sr.contains("FILE", Qt::CaseSensitive)) { + QString fs = str.mid(6); + fs.chop(6); + QVariant lcf(linecount); + QString flc = lcf.toString(); + QMap fmap; + fmap["file"] = fs; + fmap["lind"] = flc; + fmap["aArt"] = MainWindow::pa; + MainWindow::Files.append(fmap); + } + else if (sr.contains("TITLE", Qt::CaseSensitive)) { + MainWindow::tra = sr.mid(7); + MainWindow::tra.chop(1); + if (first == true) { + first = false; + } + else { + trackCount++; + }QVariant tcs(trackCount); + MainWindow::tc = tcs.toString(); + } + else if (sr.contains("TRACK 01", Qt::CaseSensitive)) { + MainWindow::al = MainWindow::tra; + } + else if (sr.contains("INDEX 01", Qt::CaseSensitive)) { + QString tind = sr.right(8); + QVariant lcs(linecount); + QString lc = lcs.toString(); + tmap["num"] = MainWindow::tc; + tmap["tind"] = tind; + tmap["lind"] = lc; + tmap["title"] = MainWindow::tra; + if (!pa.isEmpty()) { + tmap["artist"] = MainWindow::pa; + } + if (!year.isEmpty()) { + tmap["year"] = MainWindow::year; + }if (!genre.isEmpty()) { + tmap["genre"] = MainWindow::genre; + }MainWindow::Tracks.append(tmap); + } + } + first = true; + QVectorIterator> fIt(MainWindow::Files); + while (fIt.hasNext()) { + if (fIt.peekNext().value("file").contains(".flac")) { + QFileInfo fld(MainWindow::cue); + QString dir = fld.absolutePath(); + QString file = dir + "/" + fIt.peekNext().value("file"); + if (!QFileInfo(file).exists()) { + ui->statusbar->showMessage("ERROR: Input file(s) does not exist."); + rA(1); + return; + } + else { + QStandardItem *q = new QStandardItem(fIt.next().value("file")); + MainWindow::model->appendRow(q); + } + } + else { + ui->statusbar->showMessage("ERROR: Input file(s) not in FLAC format."); + rA(1); + return; + } + } + QVectorIterator> tIt(MainWindow::Tracks); + while (tIt.hasNext()) { + QStandardItem *q = new QStandardItem("Track " + tIt.peekNext().value("num") + " - " + tIt.peekNext().value("title")); + tIt.next(); + MainWindow::model2->appendRow(q); + } + ui->cueLab->setText("Current CUE File: " + MainWindow::cue); + QVariant fc(MainWindow::Files.size()); + QString fcs = fc.toString(); + ui->statusbar->showMessage("Successfully Imported CUE File (" + tIt.peekPrevious().value("num") + " Tracks Across " + fcs + " Files)."); + ui->goBu->setDisabled(false); + ui->clearBu->setDisabled(false); +} + +void MainWindow::rA(int e) { + ui->progressBar->setValue(0); + MainWindow::model->clear(); + MainWindow::model2->clear(); + MainWindow::Files.clear(); + MainWindow::Tracks.clear(); + MainWindow::cmds.clear(); + MainWindow::count = 0; + MainWindow::cue.clear(); + MainWindow::errs.clear(); + ui->goBu->setDisabled(true); + if (e != 1) { + ui->cmdout->clear(); + ui->statusbar->showMessage("Ready."); + }ui->cueLab->setText("Current CUE File: None."); +} + +void MainWindow::split() { + ui->clearBu->setDisabled(true); + ui->goBu->setDisabled(true); + ui->abBu->setDisabled(false); + ui->impBu->setDisabled(true); + if (MainWindow::Files.size() == 1) { + MainWindow::dual = 1; + } + else { + MainWindow::dual = 2; + } + if (MainWindow::cue.isEmpty() || MainWindow::Tracks.isEmpty() || MainWindow::Files.isEmpty()) { + ui->statusbar->showMessage("ERROR: Nothing to split."); + return; + } + if (MainWindow::dual == 0) { + ui->statusbar->showMessage("ERROR: Invalid Format."); + return; + }bool first = true; + bool last = false; + int bcount = 0; + QFileInfo fld(MainWindow::cue); + QString wdir = fld.absolutePath(); + QVectorIterator> tIt(MainWindow::Tracks); + tIt.next(); + while (tIt.hasNext()) { + QStringList start, end; + QString tn, namestr, amestr, side, ifile, cmd; + QMap it; + ifile = MainWindow::Files[0].value("file"); + if (last == true) { + it = tIt.peekNext(); + } + else { + it = tIt.peekPrevious(); + }if (MainWindow::dual == 2) { + if (MainWindow::Files.size() == 2) { + if (last == true) { + side = "B"; + } + else { + tn = tIt.peekPrevious().value("num"); + }if (tIt.peekPrevious().value("lind").toInt() < MainWindow::Files[1].value("lind").toInt()) { + side = "A"; + } + else { + side = "B"; + }if (side.contains("B")) { + ifile = MainWindow::Files[1].value("file"); + bcount++; + QVariant bc(bcount); + QString bcs = bc.toString(); + tn = bcs; + } + } + else { + ui->statusbar->showMessage("ERROR: CUEs with over 2 input files not currently supported."); + return; + }if (first) { + end = tIt.peekNext().value("tind").split(":"); + } + else if (last == true) { + start = tIt.peekNext().value("tind").split(":"); + } + else { + if (tIt.peekNext().value("tind").contains("00:00:00")) { + start = tIt.peekPrevious().value("tind").split(":"); + } + else if (tIt.peekPrevious().value("tind").contains("00:00:00")) { + end = tIt.peekNext().value("tind").split(":"); + } + else { + start = tIt.peekPrevious().value("tind").split(":"); + end = tIt.peekNext().value("tind").split(":"); + } + }amestr = side + tn + " - " + it.value("title") + ".flac"; + + } + else { + if (first) { + end = tIt.peekNext().value("tind").split(":"); + } + else if (last == true) { + start = tIt.peekNext().value("tind").split(":"); + } + else { + start = tIt.peekPrevious().value("tind").split(":"); + end = tIt.peekNext().value("tind").split(":"); + }if (it.value("num").length() == 1) { + tn = "0" + it.value("num"); + } + else { + tn = it.value("num"); + }amestr = tn + " - " + it.value("title") + ".flac"; + }namestr = validateNamestr(amestr); + QString c = "flac.exe --best "; + if (it.contains("artist")) { + c = c + "-T \"ARTIST= " + it.value("artist") + "\" "; + }if (it.contains("year")) { + c = c + "-T \"DATE= " + it.value("year") + "\" "; + }if (it.contains("genre")) { + c = c + "-T \"GENRE= " + it.value("genre") + "\" "; + }if (start.isEmpty()) { + cmd = c + "-T \"TRACKNUMBER=" + tIt.peekPrevious().value("num") + "\" -T \"ALBUM=" + MainWindow::al + "\" " + "-T \"TITLE=" + tIt.peekPrevious().value("title") + "\" " + "--until=" + end[0] + ":" + end[1] + "." + end[2] + " \"" + wdir + "/" + ifile + "\" -o \"" + wdir + "/" + namestr + "\""; + } + else if (end.isEmpty()) { + cmd = c + "-T \"TRACKNUMBER=" + it.value("num") + "\" -T \"ALBUM=" + MainWindow::al + "\" " + "-T \"TITLE=" + it.value("title") + "\" " + "--skip=" + start[0] + ":" + start[1] + "." + start[2] + " \"" + wdir + "/" + ifile + "\" -o \"" + wdir + "/" + namestr + "\""; + } + else { + cmd = c + "-T \"TRACKNUMBER=" + tIt.peekPrevious().value("num") + "\" -T \"ALBUM=" + MainWindow::al + "\" " + "-T \"TITLE=" + tIt.peekPrevious().value("title") + "\" " + "--skip=" + start[0] + ":" + start[1] + "." + start[2] + " --until=" + end[0] + ":" + end[1] + "." + end[2] + " \"" + wdir + "/" + ifile + "\" -o \"" + wdir + "/" + namestr + "\""; + }MainWindow::cmds.append(cmd); + first = false; + tIt.next(); + if (!tIt.hasNext()) { + if (last) { + QVariant fas(MainWindow::Tracks.size()); + QString fass = fas.toString(); + ui->statusbar->showMessage("Encoding file 1 of " + fass + "."); + break; + } + else { + tIt.previous(); + last = true; + } + } + }doTrack(0); +} + +QString MainWindow::validateNamestr(QString str) { + QString illChars = "\\ | / : ? ! \" < >"; + QStringList illCharArr = illChars.split(" ", QString::SkipEmptyParts); + QList::iterator ici; + for (ici = illCharArr.begin(); ici != illCharArr.end(); ++ici) { + str.remove(*ici); + }return str; +} + +void MainWindow::doTrack(int ex) { + if (MainWindow::stop) { + QVariant c(MainWindow::count - 1); + ui->statusbar->showMessage("Job aborted after " + c.toString() + " tracks."); + MainWindow::stop = false; + ui->abBu->setDisabled(true); + ui->clearBu->setDisabled(false); + ui->impBu->setDisabled(false); + rA(1); + return; + }if (MainWindow::cmds.size() != MainWindow::Tracks.size()) { + if (MainWindow::count != 0) { + if (ex == 1) { + QVariant c(MainWindow::count); + QString cs = c.toString(); + MainWindow::errs.append(cs); + } + } + }if (MainWindow::cmds.size() == 0) { + if (!MainWindow::errs.isEmpty()) { + QString err = MainWindow::errs.join(", "); + Dialog dia; + ui->statusbar->showMessage("Encode completed with errors."); + ui->progressBar->setValue(100); + dia.setTxt("The following tracks failed to encode: " + err + "."); + dia.exec(); + } + else { + ui->statusbar->showMessage("Encode completed, ready."); + ui->progressBar->setValue(100); + }ui->abBu->setDisabled(true); + ui->clearBu->setDisabled(false); + ui->impBu->setDisabled(false); + } + else { + QVariant c(MainWindow::count + 1); + QString cs = c.toString(); + QVariant ts(MainWindow::Tracks.size()); + QString tss = ts.toString(); + ui->statusbar->showMessage("Encoding file " + cs + " of " + tss + "."); + process->start(MainWindow::cmds[0]); + MainWindow::cmds.removeFirst(); + int cc = MainWindow::Tracks.size() - 1; + int progress = 100 / cc; + int cpro = progress * MainWindow::count; + ui->progressBar->setValue(cpro); + MainWindow::count++; + } +} + +void MainWindow::opu() { + QString otpt(process->readAllStandardOutput()); + if (otpt.contains(", ratio=")) { + QTextCursor storeCursorPos = ui->cmdout->textCursor(); + ui->cmdout->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); + ui->cmdout->moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); + ui->cmdout->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor); + ui->cmdout->textCursor().removeSelectedText(); + ui->cmdout->textCursor().deletePreviousChar(); + ui->cmdout->setTextCursor(storeCursorPos); + } + ui->cmdout->append(otpt); +} + +Dialog::~Dialog() +{ + delete ui; +} + +Abort::~Abort() +{ + delete ui; +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/Windows/Main Application/mainwindow.h b/Windows/Main Application/mainwindow.h new file mode 100644 index 0000000..62d03f6 --- /dev/null +++ b/Windows/Main Application/mainwindow.h @@ -0,0 +1,85 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { + class Dialog; + class Abort; + class MainWindow; + class Metadata; +} + +class Abort : public QDialog +{ + Q_OBJECT +public: + explicit Abort(QWidget *parent = 0); + ~Abort(); +private: + Ui::Abort *ui; +}; + +class Dialog : public QDialog +{ + Q_OBJECT +public: + explicit Dialog(QWidget *parent = 0); + ~Dialog(); +private: + Ui::Dialog *ui; + public slots: + void setTxt(QString); +}; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + QString MainWindow::cue, MainWindow::pa, MainWindow::tra, MainWindow::genre, MainWindow::year, MainWindow::tc, MainWindow::al, MainWindow::bDir; + QStandardItemModel *MainWindow::model; + QStandardItemModel *MainWindow::model2; + QProcess *MainWindow::process; + QPalette MainWindow::proPal; + bool MainWindow::stop; + QStringList MainWindow::cmds, MainWindow::errs; + QVector> MainWindow::Files, MainWindow::Tracks; + explicit MainWindow(QWidget *parent = 0); + int MainWindow::dual, MainWindow::count; + ~MainWindow(); + +protected: + void dragEnterEvent(QDragEnterEvent *e); + void dropEvent(QDropEvent *e); + +private: + Ui::MainWindow *ui; + + private slots: + void halt(); + void ex(); + void batch(); + void fImport(); + void rA(int); + void split(); + void iBut(); + void cBut(); + QString validateNamestr(QString); + void doTrack(int); + void dtTrigger(int, QProcess::ExitStatus); + void opu(); +}; + +#endif // MAINWINDOW_H diff --git a/Windows/Main Application/mainwindow.ui b/Windows/Main Application/mainwindow.ui new file mode 100644 index 0000000..c7af983 --- /dev/null +++ b/Windows/Main Application/mainwindow.ui @@ -0,0 +1,322 @@ + + + MainWindow + + + + 0 + 0 + 1112 + 854 + + + + + 0 + 0 + + + + CUEy + + + + icon.icoicon.ico + + + + Qt::LeftToRight + + + + + + + + Import CUE File + + + + + + + + + Qt::Horizontal + + + + + + + + + Input Files + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Output files + + + + + + + + + Qt::Horizontal + + + + + + + + + Current CUE File: None + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + + + + 0 + + + + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + Start + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + + + Abort + + + + + + + + 0 + 0 + + + + Clear and Reset + + + + + + + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + + + + + + + + Console Log + + + + + + + + 0 + 0 + + + + + + + + + + + 0 + 0 + 1112 + 26 + + + + + File + + + + + + + + + + + Import CUE File + + + + + Process Batch Split + + + + + Exit + + + + + + diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000..86d6846 Binary files /dev/null and b/icon.ico differ