summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mappingtreemodel.cpp2
-rw-r--r--newpicsdialog.cpp248
-rw-r--r--newpicsdialog.h77
-rw-r--r--shemov.cpp13
-rw-r--r--shemov.h2
-rw-r--r--shemov.pro6
6 files changed, 345 insertions, 3 deletions
diff --git a/mappingtreemodel.cpp b/mappingtreemodel.cpp
index 78a5fb9..9c96e69 100644
--- a/mappingtreemodel.cpp
+++ b/mappingtreemodel.cpp
@@ -129,7 +129,7 @@ bool MappingTreeModel::setData(const QModelIndex &index, const QVariant &value,
if(role == AddedRole){
item->setData(Added, value);
}
- return false;
+ return true;
}
bool MappingTreeModel::addMappingType(const QString &type){
diff --git a/newpicsdialog.cpp b/newpicsdialog.cpp
new file mode 100644
index 0000000..673865b
--- /dev/null
+++ b/newpicsdialog.cpp
@@ -0,0 +1,248 @@
+/*
+ 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.
+*/
+
+#include <QFileInfo>
+#include <QSqlQuery>
+#include <QLabel>
+#include <QTreeView>
+#include <QSortFilterProxyModel>
+#include <QPushButton>
+#include <QSettings>
+#include <QDir>
+#include <QFileDialog>
+#include <QPersistentModelIndex>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+
+#include "newpicsdialog.h"
+#include "smtreeitem.h"
+#include "helper.h"
+
+NewPicsDialog::NewPicsDialog(QWidget *parent) : QWidget(parent) {
+ //files widget
+ mFilesWidget = new QWidget;
+ mFilesV = new QTreeView;
+ mFilesProxy = new QSortFilterProxyModel(this);
+ mFilesModel = new NewPicFilesModel(QStringList() << tr("Filename") << tr("Val.") << tr("Md5") << tr("Mime type") << tr("Full path"), this);
+ mFilesProxy->setSourceModel(mFilesModel);
+ mFilesV->setModel(mFilesProxy);
+ mFilesV->setSortingEnabled(true);
+ mFilesV->setAlternatingRowColors(true);
+ mFilesV->setColumnHidden(1, true);
+ mAddFiles = new QPushButton(tr("Select..."));
+ connect(mAddFiles, SIGNAL(clicked()), this, SLOT(addFiles()));
+ mRemoveFiles = new QPushButton(tr("Remove"));
+ connect(mRemoveFiles, SIGNAL(clicked()), this, SLOT(removeFiles()));
+ QHBoxLayout *fileButtonLayout = new QHBoxLayout;
+ fileButtonLayout->addStretch();
+ fileButtonLayout->addWidget(mRemoveFiles);
+ fileButtonLayout->addWidget(mAddFiles);
+ QVBoxLayout *filesLayout = new QVBoxLayout;
+ filesLayout->addWidget(mFilesV);
+ filesLayout->addLayout(fileButtonLayout);
+ mFilesWidget->setLayout(filesLayout);
+
+ //put it together
+ setMinimumWidth(600);
+ setMinimumHeight(400);
+ mTab = new QTabWidget;
+ mTab->addTab(mFilesWidget, tr("Files"));
+ QHBoxLayout *mainLayout = new QHBoxLayout;
+ mainLayout->addWidget(mTab);
+ setLayout(mainLayout);
+}
+
+void NewPicsDialog::addFiles(){
+ QSettings s;
+ QString startDir = s.value("paths/selecteddir", QDir::homePath()).toString();
+ QStringList files = QFileDialog::getOpenFileNames(this, tr("Select pictures"), startDir);
+ if(files.isEmpty()){
+ return;
+ }
+ mFilesV->setSortingEnabled(false);
+ foreach(QString f, files){
+ mFilesModel->addFile(f);
+ }
+ mFilesV->setSortingEnabled(true);
+ for(int i = 0; i < NewPicFilesModel::NumFields; ++i){
+ mFilesV->resizeColumnToContents(i);
+ }
+}
+
+void NewPicsDialog::removeFiles(){
+ QModelIndexList selected = mFilesV->selectionModel()->selectedRows();
+ if(selected.isEmpty()){
+ return;
+ }
+ QModelIndexList real;
+ foreach(QModelIndex i, selected){
+ real << mFilesProxy->mapToSource(i);
+ }
+ QList<QPersistentModelIndex> perm;
+ foreach(QModelIndex i, real){
+ perm << i;
+ }
+ foreach(QPersistentModelIndex pi, perm){
+ mFilesModel->removeRows(pi.row(), 1, pi.parent());
+ }
+}
+
+NewPicFilesModel::NewPicFilesModel(const QStringList &header, QObject *parent) : SmTreeModel(header, parent){
+ mDb = QSqlDatabase::database("mDb");
+ mMd5Query = new QSqlQuery(mDb);
+ mMd5Query->prepare("SELECT COUNT(*) FROM pics WHERE cmd5sum = :md5");
+}
+
+NewPicFilesModel::~NewPicFilesModel(){
+ delete mMd5Query;
+ mDb = QSqlDatabase();
+}
+
+Qt::ItemFlags NewPicFilesModel::flags(const QModelIndex &index) const{
+ Q_UNUSED(index);
+ return (Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+}
+
+QVariant NewPicFilesModel::data(const QModelIndex &index, int role) const{
+ if(!index.isValid()){
+ return QVariant();
+ }
+ SmTreeItem *item = itemAt(index);
+ if(role == FileNameRole){
+ return item->data(FileName);
+ }
+ if(role == ValidRole){
+ return item->data(Valid);
+ }
+ if(role == Md5SumRole){
+ return item->data(Md5Sum);
+ }
+ if(role == MimeTypeRole){
+ return item->data(MimeType);
+ }
+ if(role == FullPathRole){
+ return item->data(FullPath);
+ }
+ if(role == Qt::DecorationRole && index.column() == 0){
+ bool valid = item->data(Valid).toBool();
+ if(valid){
+ return QIcon(":/gaping_ass.png");
+ }else{
+ return QIcon(":/chastity_belt.png");
+ }
+ }
+ if(role == Qt::FontRole && index.column() == Md5Sum){
+ return QFont("courier");
+ }
+ return SmTreeModel::data(index, role);
+}
+
+bool NewPicFilesModel::setData(const QModelIndex &index, const QVariant &value, int role){
+ if(role == Qt::EditRole || !index.isValid()){
+ return false;
+ }
+ SmTreeItem *item = itemAt(index);
+ if(role == FileNameRole){
+ item->setData(FileName, value);
+ }
+ if(role == ValidRole){
+ item->setData(Valid, value);
+ }
+ if(role == Md5SumRole){
+ item->setData(Md5Sum, value);
+ }
+ if(role == MimeTypeRole){
+ item->setData(MimeType, value);
+ }
+ if(role == FullPathRole){
+ item->setData(FullPath, value);
+ }
+ return true;
+}
+
+void NewPicFilesModel::setFiles(const QStringList &paths) {
+ SmTreeItem *rootItem = new SmTreeItem(NumFields);
+ foreach(QString file, paths){
+ QFileInfo fi(file);
+ QList<QVariant> fileData;
+ if(!fi.exists()){
+ continue;
+ }
+ QString md5 = Helper::md5Sum(fi.absoluteFilePath());
+ QString mt = Helper::mimeType(fi.absoluteFilePath()).toLower();
+ bool valid = true;
+ if(!mt.startsWith("image")){
+ valid = false;
+ }
+ if(haveMd5(md5)){
+ valid = false;
+ }
+ fileData << fi.fileName() << valid << md5 << mt << fi.absoluteFilePath();
+ SmTreeItem *newFile = new SmTreeItem(fileData, rootItem);
+ rootItem->appendChild(newFile);
+ }
+ setRoot(rootItem);
+}
+
+void NewPicFilesModel::addFile(const QString &path){
+ QFileInfo fi(path);
+ if(!fi.exists()){
+ return;
+ }
+ QString md5 = Helper::md5Sum(fi.absoluteFilePath());
+ QString mt = Helper::mimeType(fi.absoluteFilePath());
+ bool valid = true;
+ if(!mt.startsWith("image")){
+ valid = false;
+ }
+ if(haveMd5(md5)){
+ valid = false;
+ }
+ insertRows(0, 1, QModelIndex());
+ QModelIndex inserted = index(0, 1, QModelIndex());
+ setData(inserted, fi.fileName(), FileNameRole);
+ setData(inserted, valid, ValidRole);
+ setData(inserted, md5, Md5SumRole);
+ setData(inserted, mt, MimeTypeRole);
+ setData(inserted, fi.absoluteFilePath(), FullPathRole);
+}
+
+void NewPicFilesModel::removeFile(const QModelIndex &idx){
+ if(!idx.isValid()){
+ return;
+ }
+ removeRows(idx.row(), 1, idx.parent());
+}
+
+QList<FileData> NewPicFilesModel::validFiles() const {
+ SmTreeItem *rootItem = root();
+ QList<FileData> retval;
+ for(int i = 0; i < rootItem->childCount(); ++i){
+ SmTreeItem *child = rootItem->child(i);
+ if(!child->data(Valid).toBool()){
+ continue;
+ }
+ FileData data;
+ data.fileName = child->data(FileName).toString();
+ data.valid = child->data(Valid).toBool();
+ data.md5sum = child->data(Md5Sum).toString();
+ data.mimeType = child->data(MimeType).toString();
+ data.fullPath = child->data(FullPath).toString();
+ retval << data;
+ }
+ return retval;
+}
+
+bool NewPicFilesModel::haveMd5(const QString &md5) const {
+ mMd5Query->bindValue(":md5", md5);
+ mMd5Query->exec();
+ int count = 0;
+ while(mMd5Query->next()){
+ count = mMd5Query->value(0).toInt();
+ }
+ return ((count > 0) ? true : false);
+}
diff --git a/newpicsdialog.h b/newpicsdialog.h
new file mode 100644
index 0000000..de4275a
--- /dev/null
+++ b/newpicsdialog.h
@@ -0,0 +1,77 @@
+/*
+ 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.
+*/
+
+#ifndef NEWPICSDIALOG_H
+#define NEWPICSDIALOG_H
+
+#include <QWidget>
+#include <QSqlDatabase>
+
+#include "smtreemodel.h"
+
+class QTabWidget;
+class QSqlDatabase;
+class QSqlQuery;
+class QTreeView;
+class NewPicFilesModel;
+class QSortFilterProxyModel;
+class QPushButton;
+
+struct FileData;
+
+class NewPicsDialog : public QWidget {
+ Q_OBJECT
+ public:
+ explicit NewPicsDialog(QWidget *parent = 0);
+
+ public slots:
+ void addFiles();
+ void removeFiles();
+
+ private:
+ QTabWidget *mTab;
+ QWidget *mFilesWidget;
+ QTreeView *mFilesV;
+ NewPicFilesModel *mFilesModel;
+ QSortFilterProxyModel *mFilesProxy;
+ QPushButton *mAddFiles;
+ QPushButton *mRemoveFiles;
+};
+
+class NewPicFilesModel : public SmTreeModel {
+ Q_OBJECT
+ public:
+ enum Roles { FileNameRole = Qt::UserRole + 1, ValidRole = Qt::UserRole + 2, Md5SumRole = Qt::UserRole + 3, MimeTypeRole = Qt::UserRole + 4, FullPathRole = Qt::UserRole + 5 };
+ enum Fields { FileName = 0, Valid = 1, Md5Sum = 2, MimeType = 3, FullPath = 4 };
+ enum { NumFields = 5 };
+ explicit NewPicFilesModel(const QStringList &header, QObject *parent = 0);
+ ~NewPicFilesModel();
+
+ //data
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+ void setFiles(const QStringList &paths);
+ void addFile(const QString &path);
+ void removeFile(const QModelIndex &idx);
+ QList<FileData> validFiles() const;
+
+ private:
+ bool haveMd5(const QString &md5) const;
+ QSqlDatabase mDb;
+ QSqlQuery *mMd5Query;
+};
+
+struct FileData {
+ QString fileName;
+ bool valid;
+ QString md5sum;
+ QString mimeType;
+ QString fullPath;
+};
+
+#endif // NEWPICSDIALOG_H
diff --git a/shemov.cpp b/shemov.cpp
index 213e528..09d4f03 100644
--- a/shemov.cpp
+++ b/shemov.cpp
@@ -54,6 +54,7 @@
#include "mappingtablemodel.h"
#include "dbanalyzer.h"
#include "mappingtreewidget.h"
+#include "newpicsdialog.h"
SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), mOpenWithGroupFS(0), mOpenWithGroupAV(0) {
//application icon
@@ -331,6 +332,8 @@ void SheMov::createActions(){
connect(mAnalyzerA, SIGNAL(triggered()), this, SLOT(analyzeDb()));
mMappingEditorA = new QAction(tr("Mapping editor..."), this);
connect(mMappingEditorA, SIGNAL(triggered()), this, SLOT(mappingEditor()));
+ mNewPicsA = new QAction(tr("Archive pics...."), this);
+ connect(mNewPicsA, SIGNAL(triggered()), this, SLOT(newPicsDialog()));
//connnect
mQuitA = new QAction(tr("Quit"), this);
@@ -613,6 +616,7 @@ void SheMov::createMenus(){
fileMenu->addAction(mConsistencyA);
fileMenu->addAction(mAnalyzerA);
fileMenu->addAction(mMappingEditorA);
+ fileMenu->addAction(mNewPicsA);
//fileMenu->addAction(mShowNoCoverDialogA);
fileMenu->addSeparator();
fileMenu->addAction(mQuitA);
@@ -1029,3 +1033,12 @@ void SheMov::mappingEditor(){
dlg.setLayout(dlgLayout);
dlg.exec();
}
+
+void SheMov::newPicsDialog(){
+ QDialog dlg(this);
+ QHBoxLayout *dlgLayout = new QHBoxLayout;
+ NewPicsDialog *npd = new NewPicsDialog;
+ dlgLayout->addWidget(npd);
+ dlg.setLayout(dlgLayout);
+ dlg.exec();
+}
diff --git a/shemov.h b/shemov.h
index ae1c6c4..f7a2f03 100644
--- a/shemov.h
+++ b/shemov.h
@@ -54,6 +54,7 @@ class SheMov : public QMainWindow {
void toggleFilterGroup(bool checked);
void editMappings(QString table);
void mappingEditor();
+ void newPicsDialog();
signals:
void configChanged();
@@ -108,6 +109,7 @@ class SheMov : public QMainWindow {
QAction *mConsistencyA;
QAction *mAnalyzerA;
QAction *mMappingEditorA;
+ QAction *mNewPicsA;
//hmm
QAction *mHoverDirectoriesA;
diff --git a/shemov.pro b/shemov.pro
index ef92490..6e4d6d3 100644
--- a/shemov.pro
+++ b/shemov.pro
@@ -37,7 +37,8 @@ SOURCES = main.cpp \
propertiesdialog.cpp \
dbanalyzer.cpp \
mappingtreemodel.cpp \
- mappingtreewidget.cpp
+ mappingtreewidget.cpp \
+ newpicsdialog.cpp
HEADERS = listitem.h \
filesystemdirproxy.h \
filesystemwidget.h \
@@ -70,6 +71,7 @@ HEADERS = listitem.h \
propertiesdialog.h \
dbanalyzer.h \
mappingtreemodel.h \
- mappingtreewidget.h
+ mappingtreewidget.h \
+ newpicsdialog.h
LIBS += -lmagic -lXfixes -lX11
RESOURCES = shemov.qrc