From dce686c895fce27cce1d8bf0247c692bd790f93a Mon Sep 17 00:00:00 2001 From: Arno Date: Fri, 24 Feb 2012 23:32:10 +0100 Subject: Implemented NewPicsDialog Version 1 of NewPicsDialog. Just one single tab for adding files. Does nothing yet besides adding and removing files. --- mappingtreemodel.cpp | 2 +- newpicsdialog.cpp | 248 +++++++++++++++++++++++++++++++++++++++++++++++++++ newpicsdialog.h | 77 ++++++++++++++++ shemov.cpp | 13 +++ shemov.h | 2 + shemov.pro | 6 +- 6 files changed, 345 insertions(+), 3 deletions(-) create mode 100644 newpicsdialog.cpp create mode 100644 newpicsdialog.h 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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 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 NewPicFilesModel::validFiles() const { + SmTreeItem *rootItem = root(); + QList 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 +#include + +#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 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 -- cgit v1.2.3-70-g09d2