summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ShemovCleaner.pro6
-rw-r--r--filewidget.cpp45
-rw-r--r--filewidget.h9
-rw-r--r--origindialog.cpp166
-rw-r--r--origindialog.h47
5 files changed, 265 insertions, 8 deletions
diff --git a/ShemovCleaner.pro b/ShemovCleaner.pro
index 1b3ea3b..2647e72 100644
--- a/ShemovCleaner.pro
+++ b/ShemovCleaner.pro
@@ -25,7 +25,8 @@ SOURCES += main.cpp\
helper.cpp \
filedisplay.cpp \
globals.cpp \
- actorwidget.cpp
+ actorwidget.cpp \
+ origindialog.cpp
HEADERS += \
filesorter.h \
@@ -38,7 +39,8 @@ HEADERS += \
helper.h \
filedisplay.h \
globals.h \
- actorwidget.h
+ actorwidget.h \
+ origindialog.h
DISTFILES +=
diff --git a/filewidget.cpp b/filewidget.cpp
index 216cce7..4b22b77 100644
--- a/filewidget.cpp
+++ b/filewidget.cpp
@@ -35,6 +35,7 @@
#include "filewidget.h"
#include "filesorter.h"
#include "filedisplay.h"
+#include "origindialog.h"
#include "helper.h"
#include "globals.h"
@@ -91,8 +92,13 @@ void FileWidget::setupGui(){
mQOrigin.prepare("SELECT COUNT(*) FROM files_origin WHERE cmd5sum = :md5");
mQFiles = QSqlQuery(mDb);
mQFiles.prepare("SELECT COUNT(*) FROM files WHERE cmd5sum = :md5");
+ mQSimilar = QSqlQuery(mDb);
+ mQSimilar.prepare("SELECT ifiles_id, tfilename FROM files WHERE tfilename ~ :fn AND files.ifiles_id NOT IN (SELECT ifiles_id FROM files_origin WHERE ifiles_id = files.ifiles_id)");
mFileDisplay = new FileDisplay(this);
+ mOrignDlg = new OriginDialog(this);
+ connect(mOrignDlg, SIGNAL(statusMessage(QString)), this, SIGNAL(statusMessage(QString)));
+ connect(mOrignDlg, SIGNAL(refreshNeeded()), this, SLOT(gatherData()));
mMenuBar = new QMenuBar;
mToolBar = new QToolBar;
mToolBar->setIconSize(QSize(16, 16));
@@ -139,6 +145,8 @@ void FileWidget::createActions(){
mPropertiesA = new QAction(QIcon(":/diaper.png"), tr("Properties..."), this);
mPropertiesA->setShortcut(Qt::CTRL + Qt::Key_Return);
connect(mPropertiesA, SIGNAL(triggered()), this, SLOT(properties()));
+ mAddAsOriginA = new QAction(QIcon(":/butt_plug.png"), tr("Add as Origin..."), this);
+ connect(mAddAsOriginA, SIGNAL(triggered()), this, SLOT(addAsOrigin()));
QMenu *fileMenu = new QMenu(tr("&File"));
fileMenu->addAction(mSelDirA);
@@ -156,6 +164,7 @@ void FileWidget::createActions(){
editMenu->addAction(mDeleteA);
editMenu->addSeparator();
editMenu->addAction(mPropertiesA);
+ editMenu->addAction(mAddAsOriginA);
editMenu->addSeparator();
editMenu->addAction(Globals::instance()->action(Globals::ConfigAction));
@@ -174,10 +183,11 @@ void FileWidget::createActions(){
mToolBar->addAction(mDeleteA);
mToolBar->addAction(createSeparator());
mToolBar->addAction(mPropertiesA);
+ mToolBar->addAction(mAddAsOriginA);
mToolBar->addAction(createSeparator());
mToolBar->addAction(Globals::instance()->action(Globals::ConfigAction));
- addActions(QList<QAction*>() << mDirBackA << mDirUpA << createSeparator() << mRefreshA << mSelDirA << createSeparator() << mCopyA << mCutA << mPasteA << mDeleteA << createSeparator() << mPropertiesA);
+ addActions(QList<QAction*>() << mDirBackA << mDirUpA << createSeparator() << mRefreshA << mSelDirA << createSeparator() << mCopyA << mCutA << mPasteA << mDeleteA << createSeparator() << mAddAsOriginA << mPropertiesA);
}
void FileWidget::fileData(const QString &fullPath, const QString &md5){
@@ -201,6 +211,7 @@ void FileWidget::gatherData(){
mModel->setHorizontalHeaderLabels(QStringList() << QChar(0x26A7) << tr("Name") << tr("MIME") << tr("Duration") << tr("MD5"));
QBrush redBrush(Qt::red);
QBrush greenBrush(Qt::darkGreen);
+ QBrush blueBrush(Qt::darkBlue);
QMimeDatabase db;
qApp->setOverrideCursor(Qt::BusyCursor);
@@ -238,9 +249,17 @@ void FileWidget::gatherData(){
fData[NameColumn]->setForeground(greenBrush);
attr = Present;
}else{
- fData[IconColumn]->setIcon(QIcon(":/chastity_belt.png"));
- fData[NameColumn]->setForeground(redBrush);
- attr = NotPresent;
+ QString complFn = fi.completeBaseName();
+ bool hasOrig = haveOrigin(complFn);
+ if(hasOrig){
+ fData[IconColumn]->setIcon(QIcon(":/butt_plug.png"));
+ fData[NameColumn]->setForeground(blueBrush);
+ attr = Origin;
+ }else{
+ fData[IconColumn]->setIcon(QIcon(":/chastity_belt.png"));
+ fData[NameColumn]->setForeground(redBrush);
+ attr = NotPresent;
+ }
}
QJsonDocument jDoc = Helper::ffpmegData(fi.absoluteFilePath());
QJsonObject jObj = jDoc.object();
@@ -299,6 +318,16 @@ int FileWidget::md5Count(const QString &md5) {
return retval;
}
+bool FileWidget::haveOrigin(const QString filename){
+ bool retval = false;
+ mQSimilar.bindValue(":fn", filename);
+ mQSimilar.exec();
+ while(mQSimilar.next()){
+ retval = true;
+ }
+ return retval;
+}
+
void FileWidget::readHeaderData(){
QSettings s;
QByteArray headers = s.value("video/fileheaders").toByteArray();
@@ -425,6 +454,14 @@ void FileWidget::selectFirst(){
}
}
+void FileWidget::addAsOrigin(){
+ mOrignDlg->clear();
+ QModelIndex idx = mFileView->selectionModel()->selectedRows().first();
+ QString fp = idx.data(FullPathRole).toString();
+ mOrignDlg->setSrctData(fp);
+ mOrignDlg->setDstData(fp);
+ mOrignDlg->show();
+}
void FileWidget::fileSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected){
Q_UNUSED(selected);
diff --git a/filewidget.h b/filewidget.h
index b9133e2..ef18603 100644
--- a/filewidget.h
+++ b/filewidget.h
@@ -18,12 +18,12 @@ class QAction;
class QMimeData;
class VideoSorter;
class FileDisplay;
-
+class OriginDialog;
class FileWidget : public QWidget {
Q_OBJECT
public:
- enum FileAttrs { NotPresent = 0, Present = 1, NoVideo = 2, ParentDir = 3, Directory = 4 };
+ enum FileAttrs { NotPresent = 0, Present = 1, NoVideo = 2, ParentDir = 3, Directory = 4, Origin = 5 };
enum CustomRoles { AttrsRole = Qt::UserRole + 1, FullPathRole = Qt::UserRole + 2, DurationRole = Qt::UserRole + 3, MD5SumRole = Qt::UserRole + 4, SecondsRole = Qt::UserRole + 5 };
enum { ColumnCount = 5 };
enum Columns { IconColumn = 0, NameColumn = 1, MimeColumn = 2, DurationColumn = 3, Md5Column = 4 };
@@ -56,6 +56,7 @@ class FileWidget : public QWidget {
void cut();
void paste();
void selectFirst();
+ void addAsOrigin();
protected:
virtual void keyPressEvent(QKeyEvent *e);
@@ -66,6 +67,7 @@ class FileWidget : public QWidget {
void createActions();
void fileData(const QString &fullPath, const QString &md5);
int md5Count(const QString &md5);
+ bool haveOrigin(const QString filename);
void readHeaderData();
void writeHeaderData();
void readSettings();
@@ -84,6 +86,7 @@ class FileWidget : public QWidget {
QSqlDatabase mDb;
QSqlQuery mQOrigin;
QSqlQuery mQFiles;
+ QSqlQuery mQSimilar;
QMimeData *mMimeData;
QAction *mSelDirA;
QAction *mRefreshA;
@@ -94,8 +97,10 @@ class FileWidget : public QWidget {
QAction *mCutA;
QAction *mPasteA;
QAction *mDeleteA;
+ QAction *mAddAsOriginA;
FileDisplay *mFileDisplay;
VideoSorter *mProxy;
+ OriginDialog *mOrignDlg;
int mFileAction;
};
diff --git a/origindialog.cpp b/origindialog.cpp
new file mode 100644
index 0000000..3e8bd3a
--- /dev/null
+++ b/origindialog.cpp
@@ -0,0 +1,166 @@
+#include <QLabel>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QFileInfo>
+#include <QLocale>
+#include <QJsonObject>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+
+#include "origindialog.h"
+#include "helper.h"
+
+OriginDialog::OriginDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) {
+ setupGui();
+}
+
+void OriginDialog::setupGui(){
+ QGroupBox *origGB = new QGroupBox(tr("Origin data"));
+ mOrigDur = new QLineEdit;
+ mOrigDur->setReadOnly(true);
+ mOrigName = new QLineEdit;
+ mOrigName->setReadOnly(true);
+ mOrigSize = new QLineEdit;
+ mOrigSize->setReadOnly(true);
+ mOrigBitrate = new QLineEdit;
+ mOrigBitrate->setReadOnly(true);
+ mOrigMd5 = new QLineEdit;
+ mOrigMd5->setReadOnly(true);
+ mOrigMd5->setFont(QFont("courier new"));
+ QGridLayout *origLayout = new QGridLayout;
+ origLayout->addWidget(new QLabel(tr("Origin Name")), 0, 0);
+ origLayout->addWidget(mOrigName, 0, 1);
+ origLayout->addWidget(new QLabel(tr("Origin duration")), 1, 0);
+ origLayout->addWidget(mOrigDur, 1, 1);
+ origLayout->addWidget(new QLabel(tr("Origin Size")), 2, 0);
+ origLayout->addWidget(mOrigSize, 2, 1);
+ origLayout->addWidget(new QLabel(tr("Origin Bitrate")), 3, 0);
+ origLayout->addWidget(mOrigBitrate, 3, 1);
+ origLayout->addWidget(new QLabel(tr("MD5")), 4, 0);
+ origLayout->addWidget(mOrigMd5, 4, 1);
+ origGB->setLayout(origLayout);
+ QGroupBox *destGB = new QGroupBox(tr("Destination data"));
+ mDstDur = new QLineEdit;
+ mDstDur->setReadOnly(true);
+ mDstName = new QLineEdit;
+ mDstName->setReadOnly(true);
+ mDstSize = new QLineEdit;
+ mDstSize->setReadOnly(true);
+ mDstMd5 = new QLineEdit;
+ mDstMd5->setReadOnly(true);
+ mDstMd5->setFont(QFont("courier new"));
+ QGridLayout *dstLayout = new QGridLayout;
+ dstLayout->addWidget(new QLabel(tr("Destination Name")), 0, 0);
+ dstLayout->addWidget(mDstName, 0, 1);
+ dstLayout->addWidget(new QLabel(tr("Destination duration")), 1, 0);
+ dstLayout->addWidget(mDstDur, 1, 1);
+ dstLayout->addWidget(new QLabel(tr("Destination Size")), 2, 0);
+ dstLayout->addWidget(mDstSize, 2, 1);
+ dstLayout->addWidget(new QLabel(tr("MD5")), 3, 0);
+ dstLayout->addWidget(mDstMd5, 3, 1);
+ destGB->setLayout(dstLayout);
+ mOk = new QPushButton(tr("Add"));
+ connect(mOk, SIGNAL(clicked()), this, SLOT(accept()));
+ mCancel = new QPushButton(tr("Cancel"));
+ connect(mCancel, SIGNAL(clicked()), this, SLOT(reject()));
+ QHBoxLayout *btnLayout = new QHBoxLayout;
+ btnLayout->addStretch();
+ btnLayout->addWidget(mOk);
+ btnLayout->addWidget(mCancel);
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(origGB);
+ mainLayout->addWidget(destGB);
+ mainLayout->addLayout(btnLayout);
+ setLayout(mainLayout);
+ setMinimumWidth(400);
+ mLineEdits << mOrigBitrate << mOrigDur << mOrigMd5 << mOrigName << mOrigSize << mDstDur << mDstMd5 << mDstName << mDstSize;
+}
+
+void OriginDialog::setSrctData(const QString &absolutefn){
+ QFileInfo fi(absolutefn);
+ if(fi.exists() && fi.isFile()){
+ mOrigName->setText(fi.fileName());
+ QLocale l;
+ mOrigSize->setText(l.toString(fi.size()));
+ mSize = fi.size();
+ QJsonDocument jDoc = Helper::ffpmegData(absolutefn);
+ QJsonObject jObj = jDoc.object();
+ QJsonValue durationV = jObj["format"].toObject()["duration"];
+ qint64 seconds = durationV.toVariant().toDouble();
+ Helper::Duration dur = Helper::Duration(seconds);
+ QString duration = dur.toString();
+ mOrigDur->setText(duration);
+ QJsonValue brv = jObj["format"].toObject()["bit_rate"];
+ mBitrate = brv.toVariant().toLongLong();
+ QString brString = QString("%1 kb/s").arg(l.toString(mBitrate / 1000));
+ mOrigBitrate->setText(brString);
+ mMd5 = Helper::md5Sum(absolutefn);
+ mOrigMd5->setText(mMd5);
+ }
+}
+
+void OriginDialog::setDstData(const QString &absolutefn){
+ QFileInfo fi(absolutefn);
+ QSqlDatabase db = QSqlDatabase::database("shemovdb");
+ QSqlQuery dstQ(db);
+ dstQ.prepare("SELECT tfilename, iduration, bisize, cmd5sum, ifiles_id FROM files WHERE tfilename ~ :fnb");
+ dstQ.bindValue(":fnb", fi.completeBaseName());
+ dstQ.exec();
+ while(dstQ.next()){
+ mDstName->setText(dstQ.value(0).toString());
+ Helper::Duration dur = Helper::Duration(dstQ.value(1).toDouble());
+ mDstDur->setText(dur.toString());
+ QLocale l;
+ mDstSize->setText(l.toString(dstQ.value(2).toLongLong()));
+ mDstMd5->setText(dstQ.value(3).toString());
+ mFileId = dstQ.value(4).toInt();
+ }
+ if(mDstName->text().isEmpty()){
+ mOk->setEnabled(false);
+ mDstName->setText(tr("(n/a)"));
+ return;
+ }
+ bool originExists = false;
+ QSqlQuery origExistsQ(db);
+ origExistsQ.prepare("SELECT COUNT(*) FROM files_origin where ifiles_id = :fid");
+ origExistsQ.bindValue(":fid", mFileId);
+ origExistsQ.exec();
+ while(origExistsQ.next()){
+ originExists = origExistsQ.value(0).toInt() == 0 ? false : true;
+ }
+ if(originExists){
+ mOk->setEnabled(false);
+ return;
+ }
+ mOk->setEnabled(true);
+}
+
+void OriginDialog::clear(){
+ foreach(QLineEdit *le, mLineEdits){
+ le->clear();
+ }
+}
+
+void OriginDialog::accept(){
+ QSqlDatabase db = QSqlDatabase::database("shemovdb");
+ QSqlQuery insertQ(db);
+ insertQ.prepare("INSERT INTO files_origin (ifiles_id, tname, cmd5sum, bisize, ibitrate) VALUES(:fid, :name, :md5, :size, :bitrate)");
+ insertQ.bindValue(":fid", mFileId);
+ insertQ.bindValue(":name", mOrigName->text());
+ insertQ.bindValue(":md5", mMd5);
+ insertQ.bindValue(":size", mSize);
+ insertQ.bindValue(":bitrate", mBitrate);
+ if(insertQ.exec()){
+ QString msg = QString(tr("Inserted %1 as origin to %2")).arg(mOrigName->text()).arg(mFileId);
+ emit statusMessage(msg);
+ emit refreshNeeded();
+ }else{
+ QString msg = QString(tr("Failed to add %1 as origin")).arg(mOrigName->text());
+ emit statusMessage(msg);
+ }
+ QDialog::accept();
+}
diff --git a/origindialog.h b/origindialog.h
new file mode 100644
index 0000000..dd9cb3f
--- /dev/null
+++ b/origindialog.h
@@ -0,0 +1,47 @@
+#ifndef ORIGINDIALOG_H
+#define ORIGINDIALOG_H
+
+#include <QDialog>
+#include <QVector>
+
+class QLineEdit;
+class QPushButton;
+
+class OriginDialog : public QDialog {
+ Q_OBJECT
+ public:
+ explicit OriginDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
+
+ signals:
+ void statusMessage(const QString &msg);
+ void refreshNeeded();
+
+ public slots:
+ void setSrctData(const QString &absolutefn);
+ void setDstData(const QString &absolutefn);
+ void clear();
+ virtual void accept();
+
+ private:
+ void setupGui();
+ QLineEdit *mOrigName;
+ QLineEdit *mOrigDur;
+ QLineEdit *mOrigSize;
+ QLineEdit *mOrigBitrate;
+ QLineEdit *mOrigMd5;
+ QLineEdit *mDstName;
+ QLineEdit *mDstDur;
+ QLineEdit *mDstSize;
+ QLineEdit *mDstMd5;
+ QVector<QLineEdit*> mLineEdits;
+ QPushButton *mOk;
+ QPushButton *mCancel;
+ qint64 mSeconds;
+ qint64 mSize;
+ qint64 mBitrate;
+ QString mMd5;
+ int mFileId;
+
+};
+
+#endif // ORIGINDIALOG_H