diff --git a/RIP.cpp b/RIP.cpp index 57b431b..96d5e01 100644 --- a/RIP.cpp +++ b/RIP.cpp @@ -78,9 +78,13 @@ static void paintLogo(QPainter& _p, QRect _r, int _degrees = 360, QVector _p.drawEllipse(_r.adjusted(wx * .4, wy * .4, -wx * .4, -wy * .4)); } -Progress::Progress(RIP* _r): QWidget(0, Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint), m_r(_r) +Progress::Progress(): QWidget(0, Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint) { - resize(176, 192); + QApplication::setQuitOnLastWindowClosed(false); + m_r = new RIP(this); + resize(156, 192); + setWindowIcon(QIcon(":/RipInPeace.png")); + m_r->show(); } void Progress::paintEvent(QPaintEvent*) @@ -90,7 +94,7 @@ void Progress::paintEvent(QPaintEvent*) f.reserve(m_r->progress().size()); for (auto i: m_r->progress()) total += i.second; - int pos; + int pos = 0; for (auto i: m_r->progress()) { f.push_back(float(pos) / total); @@ -100,24 +104,26 @@ void Progress::paintEvent(QPaintEvent*) QPainter p(this); auto r = rect(); QPixmap px(140, 140); + int m = 6; px.fill(Qt::transparent); { QPainter p(&px); - paintLogo(p, QRect(6, 6, 128, 128), 360 * m_r->amountDone(), f); + paintLogo(p, QRect(m, m, px.width() - m * 2, px.height() - m * 2), 360 * m_r->amountDone(), f); } QLinearGradient g(r.topLeft(), r.bottomLeft()); g.setStops(QGradientStops() << QGradientStop(0, QColor::fromHsv(0, 0, 96)) << QGradientStop(1, QColor::fromHsv(0, 0, 48))); p.fillRect(r, g); - p.drawPixmap(18, 0, px); + p.drawPixmap((width() - px.width()) / 2, 0, px); p.setPen(QColor::fromHsv(0, 0, 64)); p.drawRect(r.adjusted(0, 0, -1, -1)); p.setPen(Qt::black); - p.drawText(QRect(0, 133, width(), 58), Qt::AlignCenter|Qt::TextWordWrap, m_r->toolTip()); - p.setPen(QColor::fromHsv(0, 0, 192)); - p.drawText(QRect(0, 134, width(), 58), Qt::AlignCenter|Qt::TextWordWrap, m_r->toolTip()); + p.drawText(QRect(0, px.height() - m - 1, width(), height() - px.height() + m), Qt::AlignCenter|Qt::TextWordWrap, m_r->toolTip()); + p.setPen(QColor::fromHsv(0, 0, 240)); + p.drawText(QRect(0, px.height() - m, width(), height() - px.height() + m), Qt::AlignCenter|Qt::TextWordWrap, m_r->toolTip()); } -RIP::RIP(): +RIP::RIP(Progress* _p): + QSystemTrayIcon(_p), m_path("/media/Data/Music"), m_filename("(discartist ? discartist : 'Various')+' - '+disctitle+(total>1 ? ' ['+index+'-'+total+']' : '')+'/'+sortnumber+' '+(compilation ? artist+' - ' : '')+title+'.flac'"), m_device("/dev/cdrom2"), @@ -127,9 +133,9 @@ RIP::RIP(): m_identifier(nullptr), m_ripped(false), m_identified(false), - m_confirmed(false) + m_confirmed(false), + m_progressPie(_p) { - QApplication::setQuitOnLastWindowClosed(false); { QPixmap px(22, 22); px.fill(Qt::transparent); @@ -145,9 +151,8 @@ RIP::RIP(): readSettings(); - m_settings = new Settings(this); - m_progressPie = new Progress(this); - m_popup = new QFrame(0, Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint); + m_settings = new Settings(m_progressPie, this); + m_popup = new QFrame(m_progressPie, Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint|Qt::Window); m_info.setupUi(m_popup); m_popup->setEnabled(false); connect(m_info.presets, SIGNAL(currentIndexChanged(int)), SLOT(updatePreset(int))); @@ -318,9 +323,11 @@ void RIP::tagAll() vc->append_comment(FLAC::Metadata::VorbisComment::Entry("date", toString(m_di.year).c_str())); vc->append_comment(FLAC::Metadata::VorbisComment::Entry("tracknumber", toString(i + 1).c_str())); vc->append_comment(FLAC::Metadata::VorbisComment::Entry("title", m_di.tracks[i].title.c_str())); - vc->append_comment(FLAC::Metadata::VorbisComment::Entry("artist", m_di.tracks[i].artist.c_str())); + vc->append_comment(FLAC::Metadata::VorbisComment::Entry("artist", (m_di.tracks[i].artist.size() ? m_di.tracks[i].artist : m_di.artist).c_str())); vc->append_comment(FLAC::Metadata::VorbisComment::Entry("discnumber", toString(m_di.setIndex + 1).c_str())); vc->append_comment(FLAC::Metadata::VorbisComment::Entry("disctotal", toString(m_di.setTotal).c_str())); + vc->append_comment(FLAC::Metadata::VorbisComment::Entry("tracktotal", toString(m_di.tracks.size()).c_str())); + vc->append_comment(FLAC::Metadata::VorbisComment::Entry("totaltracks", toString(m_di.tracks.size()).c_str())); } if (!chain.write()) @@ -346,16 +353,26 @@ QString scrubbed(QString _s) void RIP::moveAll() { QScriptEngine s; + // RIP-style variables - deprecated. s.globalObject().setProperty("disctitle", scrubbed(fSS(m_di.title)), QScriptValue::ReadOnly|QScriptValue::Undeletable); s.globalObject().setProperty("discartist", scrubbed(fSS(m_di.artist)), QScriptValue::ReadOnly|QScriptValue::Undeletable); s.globalObject().setProperty("index", m_di.setIndex + 1, QScriptValue::ReadOnly|QScriptValue::Undeletable); s.globalObject().setProperty("total", m_di.setTotal, QScriptValue::ReadOnly|QScriptValue::Undeletable); s.globalObject().setProperty("year", m_di.year == 1900 ? QString() : QString::number(m_di.year), QScriptValue::ReadOnly|QScriptValue::Undeletable); + // Vorbiscomment-style variables. Use these. s.globalObject().setProperty("compilation", m_di.isCompilation(), QScriptValue::ReadOnly|QScriptValue::Undeletable); + s.globalObject().setProperty("album", scrubbed(fSS(m_di.title)), QScriptValue::ReadOnly|QScriptValue::Undeletable); + s.globalObject().setProperty("albumartist", scrubbed(fSS(m_di.artist)), QScriptValue::ReadOnly|QScriptValue::Undeletable); + s.globalObject().setProperty("discnumber", m_di.setIndex + 1, QScriptValue::ReadOnly|QScriptValue::Undeletable); + s.globalObject().setProperty("disctotal", m_di.setTotal, QScriptValue::ReadOnly|QScriptValue::Undeletable); + s.globalObject().setProperty("date", m_di.year == 1900 ? QString() : QString::number(m_di.year), QScriptValue::ReadOnly|QScriptValue::Undeletable); for (unsigned i = 0; i < m_di.tracks.size(); ++i) if (m_p.trackLength(i)) { + // RIP-style variables - deprecated. s.globalObject().setProperty("number", i + 1, QScriptValue::ReadOnly|QScriptValue::Undeletable); + // Vorbiscomment-style variables. Use these. + s.globalObject().setProperty("tracknumber", i + 1, QScriptValue::ReadOnly|QScriptValue::Undeletable); s.globalObject().setProperty("sortnumber", QString("%1").arg(i + 1, 2, 10, QChar('0')), QScriptValue::ReadOnly|QScriptValue::Undeletable); s.globalObject().setProperty("title", scrubbed(fSS(m_di.tracks[i].title)), QScriptValue::ReadOnly|QScriptValue::Undeletable); s.globalObject().setProperty("artist", scrubbed(fSS(m_di.tracks[i].artist)), QScriptValue::ReadOnly|QScriptValue::Undeletable); @@ -386,37 +403,57 @@ void RIP::timerEvent(QTimerEvent*) m_progressPie->update(); if (m_ripped) { - m_ripper->join(); - m_identifier->join(); - delete m_ripper; - m_ripper = nullptr; - delete m_identifier; - m_identifier = nullptr; - m_ripped = false; - if (!m_aborting) + if ((m_identified && m_started.elapsed() > 30000 && m_justRipped && !m_popup->isVisible()) || m_aborting || m_confirmed) + { + m_ripper->join(); + m_identifier->join(); + delete m_ripper; + m_ripper = nullptr; + delete m_identifier; + m_identifier = nullptr; + m_ripped = false; + if (!m_aborting) + { + takeDiscInfo(); + if (m_dis.size() || !m_di.title.empty()) + { + tagAll(); + moveAll(); + } + else + showMessage("Unknown CD", "Couldn't find the CD with the available resources. Please reinsert once a database entry is accessible and the rip will be finished."); + } + m_p.close(); + m_progress.clear(); + eject(); + m_dis.clear(); + m_info.presets->clear(); + updatePreset(-1); + m_popup->setEnabled(false); + m_aborting = false; + m_abortRip->setEnabled(false); + m_unconfirm->setEnabled(false); + m_progressPie->hide(); + m_justRipped = false; + } + else if (m_justRipped) { - takeDiscInfo(); if (m_dis.size() || !m_di.title.empty()) { - tagAll(); - moveAll(); + showMessage("Please confirm", "Please click to inspect and confirm the CD details entered or abort the rip operation now and re-enter the CD to continue later."); + m_justRipped = false; + } + else if (!m_popup->isVisible() && m_identified) + { + showMessage("Unknown CD", "Couldn't find the CD with the available resources. Please click to specify and confirm the correct artist/title information or abort the rip."); + m_justRipped = false; } - else + else if (m_popup->isVisible()) { - showMessage("Unknown CD", "Couldn't find the CD with the available resources. Please reinsert once a database entry is accessible and the rip will be finished."); + showMessage("Data acquired", "All audio data from the CD is ripped; press confirm once the CD information is complete."); + m_justRipped = false; } } - m_p.close(); - m_progress.clear(); - eject(); - m_dis.clear(); - m_info.presets->clear(); - updatePreset(-1); - m_popup->setEnabled(false); - m_aborting = false; - m_abortRip->setEnabled(false); - m_unconfirm->setEnabled(false); - m_progressPie->hide(); } if (!m_ripper) { @@ -435,7 +472,9 @@ void RIP::timerEvent(QTimerEvent*) m_confirmed = false; m_aborting = false; m_identified = false; - m_ripper = new std::thread([&](){ rip(); m_ripped = true; }); + m_started.restart(); + m_popup->setEnabled(true); + m_ripper = new std::thread([&](){ rip(); m_ripped = m_justRipped = true; }); m_abortRip->setEnabled(true); m_identifier = new std::thread([&](){ getDiscInfo(); m_identified = true; }); } @@ -446,19 +485,29 @@ void RIP::timerEvent(QTimerEvent*) setIcon(m_inactive); } } - if (m_identified && !m_popup->isEnabled()) + if (m_ripper && !m_aborting && m_identified && !m_confirmed && m_info.title->text().isEmpty() && !m_dis.size()) + { + m_identified = false; + if (m_identifier) + { + m_identifier->join(); + delete m_identifier; + } + m_identifier = new std::thread([&](){ getDiscInfo(); m_identified = true; }); + } + if (m_identified && m_info.title->text().isEmpty() && m_dis.size()) { m_info.presets->clear(); for (DiscInfo const& di: m_dis) m_info.presets->addItem(fSS(di.artist + " - " + di.title)); updatePreset(0); - m_popup->setEnabled(true); } + QString tt; if (m_progress.size()) for (unsigned i = 0; i < m_progress.size(); ++i) if (m_progress[i].first != 0 && m_progress[i].first != m_progress[i].second) - tt += QString("%1: %2%\n").arg(i < m_di.tracks.size() && m_di.tracks[i].title.size() ? fSS(m_di.tracks[i].title) : QString("Track %1").arg(i + 1)).arg(int(m_progress[i].first * 100.0 / m_progress[i].second)); + tt += QString("%1: %2%\n").arg((int)i < m_info.tracks->rowCount() && m_info.tracks->item(i, 0)->text().size() ? m_info.tracks->item(i, 0)->text() : QString("Track %1").arg(i + 1)).arg(int(m_progress[i].first * 100.0 / m_progress[i].second)); else{} else tt = "Ready\n"; @@ -494,7 +543,7 @@ void RIP::timerEvent(QTimerEvent*) } } setIcon(QIcon(px)); - if (percDone >= 90 && m_lastPercentDone < 90 && !m_confirmed) + if (percDone >= 90 && m_lastPercentDone < 90 && !m_confirmed && !m_info.title->text().isEmpty()) showMessage("Ripping nearly finished", "Ripping is almost complete; tagging will begin shortly. Are you sure the tags are OK?"); m_lastPercentDone = percDone; } diff --git a/RIP.h b/RIP.h index c68aef6..2afffc2 100644 --- a/RIP.h +++ b/RIP.h @@ -3,7 +3,8 @@ #include #include #include -#include +#include +#include #include "DiscInfo.h" #include "Paranoia.h" #include "ui_Info.h" @@ -20,7 +21,9 @@ class RIP; class Progress: public QWidget { public: - Progress(RIP* _r); + Progress(); + + RIP* rip() const { return m_r; } private: void paintEvent(QPaintEvent*); @@ -33,7 +36,7 @@ class RIP: public QSystemTrayIcon Q_OBJECT public: - RIP(); + RIP(Progress* _p); ~RIP(); QString directory() const { return QString::fromUtf8(m_path.c_str()); } @@ -96,7 +99,9 @@ private slots: std::thread* m_identifier; bool m_ripped; bool m_identified; + bool m_justRipped; bool m_confirmed; + QTime m_started; int m_lastPercentDone; std::vector > m_progress; diff --git a/RIP.qrc b/RIP.qrc index 98d50b8..3454c45 100644 --- a/RIP.qrc +++ b/RIP.qrc @@ -1,5 +1,5 @@ - rip.png + RipInPeace.png diff --git a/RipInPeace.pro b/RipInPeace.pro index ef6db2d..18c6ef1 100644 --- a/RipInPeace.pro +++ b/RipInPeace.pro @@ -36,3 +36,24 @@ FORMS += \ RESOURCES += \ RIP.qrc +unix { + #VARIABLES + isEmpty(PREFIX) { + PREFIX = /usr + } + BINDIR = $$PREFIX/bin + DATADIR =$$PREFIX/share + + DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\" + INSTALLS += target desktop service iconxpm icon26 icon48 icon64 + + system (cat $${TARGET}.desktop > $${DESTDIR_TARGET}.desktop) + system (echo "Exec=$$BINDIR/$${TARGET}" >> $${DESTDIR_TARGET}.desktop) + system (echo "Icon=$$DATADIR/icons/hicolor/64x64/apps/$${TARGET}.png" >> $${DESTDIR_TARGET}.desktop) + + target.path = $$BINDIR + desktop.path = $$DATADIR/applications + desktop.files += $${TARGET}.desktop + icon64.path = $$DATADIR/icons/hicolor/64x64/apps + icon64.files += $${TARGET}.png +} diff --git a/Settings.cpp b/Settings.cpp index c705b93..a4a3f56 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -7,8 +7,8 @@ #include "Settings.h" using namespace std; -Settings::Settings(RIP* _parent): - QDialog(nullptr), +Settings::Settings(Progress* _parent, RIP* _rip): + QDialog(_parent), ui(new Ui::Settings), m_rip(nullptr) { @@ -24,7 +24,7 @@ Settings::Settings(RIP* _parent): it->setCheckState(0, Qt::Unchecked); } - m_rip = _parent; + m_rip = _rip; populate(); connect(ui->directory, SIGNAL(textEdited(QString)), m_rip, SLOT(setDirectory(QString))); diff --git a/Settings.h b/Settings.h index 692e8c0..c2be76f 100644 --- a/Settings.h +++ b/Settings.h @@ -7,6 +7,7 @@ class Settings; } class RIP; +class Progress; class QTreeWidgetItem; class Settings: public QDialog @@ -14,7 +15,7 @@ class Settings: public QDialog Q_OBJECT public: - explicit Settings(RIP* _parent); + explicit Settings(Progress* _parent, RIP* _rip); ~Settings(); public slots: diff --git a/Settings.ui b/Settings.ui index 792eb3e..79e5b45 100644 --- a/Settings.ui +++ b/Settings.ui @@ -73,7 +73,11 @@ - + + + <html><head/><body>Variables available:<br/><span style=" font-weight:600;">album</span> album title<br/><span style=" font-weight:600;">albumartist</span> apparent artist of the album<br/><span style=" font-weight:600;">disctotal</span> total discs in this album<br/><span style=" font-weight:600;">discnumber</span> this disc's number<br/><span style=" font-weight:600;">tracktotal</span> total tracks on this disc<br/><span style=" font-weight:600;">tracknumber</span> this track's number<br/><span style=" font-weight:600;">compilation</span> if all tracks haven't the same artist<br/><span style=" font-weight:600;">date</span> album release date<br/><span style=" font-weight:600;">sortnumber</span> this track's number in alpha-sortable format</body></html> + + diff --git a/debian/changelog b/debian/changelog index ff63170..2b8b420 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +ripinpeace (1.0.0~rc1) precise; urgency=low + + * First release candidate + + -- Gav Wood Fri, 07 Sep 2012 12:12:33 +0100 + ripinpeace (1.0.0~rc1) precise; urgency=low * First release candidate diff --git a/main.cpp b/main.cpp index 83801c1..8bee1fa 100644 --- a/main.cpp +++ b/main.cpp @@ -4,8 +4,6 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); - RIP w; - w.show(); - + Progress w; return a.exec(); }