Mercurial > dedupe
diff DataController.cpp @ 0:a3834af36579
Working with memory backend.
| author | Tom Fredrik Blenning Klaussen <bfg@blenning.no> |
|---|---|
| date | Mon, 20 Aug 2012 15:49:48 +0200 |
| parents | |
| children | aae83c0a771d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataController.cpp Mon Aug 20 15:49:48 2012 +0200 @@ -0,0 +1,326 @@ +#include "DataController.hpp" + +#include "MemoryDbLink.hpp" + +#include "PermissionException.hpp" +#include "DataController.hpp" + +#include <QtGui/QApplication> +#include <QtCore/QDir> + +#include <QtCore/QDebug> +#include <QtCore/QTimer> +#include <QtCore/QCryptographicHash> +#include <QtCore/QDateTime> + +#include <QtGui/QMainWindow> +#include <QtGui/QTreeWidget> +#include <QtGui/QHeaderView> +#include <QtGui/QMenuBar> +#include <QtGui/QToolBar> +#include <QtGui/QDoubleSpinBox> +#include <QtGui/QLabel> +#include <QtGui/QHBoxLayout> +#include <QtGui/QProgressBar> + +#include "EditDistance.hpp" + +#include <cassert> +void findFiles(const QDir& dir, FileDbLink& dblink) +{ + /* + QProgressDialog progressDialog(this); + progressDialog.setCancelButtonText(tr("&Cancel")); + progressDialog.setRange(0, files.size()); + progressDialog.setWindowTitle(tr("Find Files")); + */ + + foreach(QString filename, dir.entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + filename = dir.absoluteFilePath(filename); + findFiles(QDir(filename), dblink); + } + + foreach(QString filename, dir.entryList(QDir::Files)) { + filename = dir.absoluteFilePath(filename); + try { + dblink.updateIfModified(filename); + } + catch (const PermissionException& e) { + qDebug()<<e.toString(); + } + catch (Exception& e) { + qDebug()<<e.toString(); + exit(1); + } + } +} + +QTreeWidgetItem* DataController::createItem(const FileDbLink::DBInfo& info) +{ + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setData(0, Qt::DisplayRole, info.name()); + item->setData(0, 32, info.path()); + item->setData(0, 33, info.name()); + + item->setData(1, Qt::DisplayRole, info.size()); + item->setData(2, Qt::DisplayRole, info.mtime()); + item->setData(3, Qt::DisplayRole, info.checksum().toHex()); + return item; +} + +void DataController::delayPopulate() +{ + populateDelay->start(); +} + + +void DataController::populate() +{ + populate(nameFilter->isChecked(), sizeFilter->isChecked(), mtimeFilter->isChecked(), + checksumFilter->isChecked(), (100 - editCutoffSpin->value()) * .01); +} + +void DataController::populate(bool showNameDups, bool showSizeDups, + bool showMTimeDups, bool showCheckSumDups, + float editDistanceCutoff) +{ + tw->clear(); + + const QList<QSharedPointer<FileDbLink::DBInfo> > elems = dblink->sortOn(FileDbLink::EDIT, true); + + QProgressBar bar; + + bar.resize(200,25); + bar.setValue(0); + bar.setMinimum(0); + bar.setMaximum(elems.size()); + bar.show(); + + connect(this, SIGNAL(populateProgress(int)), &bar, SLOT(setValue(int))); + + int n = 0; + + tw->setUpdatesEnabled(false); + + foreach(QSharedPointer<FileDbLink::DBInfo> line, elems) { + QTreeWidgetItem* item = 0; + bool anyAdded = false; + + if (showNameDups) { + QTreeWidgetItem* topLevelItem = 0; + foreach(QSharedPointer<FileDbLink::DBInfo> dup, elems) { + if(dup != line && line->name() == dup->name() ) { + if (!topLevelItem) { + topLevelItem = new QTreeWidgetItem(); + topLevelItem->setData(0, Qt::DisplayRole, "Name"); + if(!item) + item = createItem(*line); + item->addChild(topLevelItem); + anyAdded = true; + } + topLevelItem->addChild(createItem(*dup)); + } + } + } + + if (showSizeDups) { + QTreeWidgetItem* topLevelItem = 0; + foreach(QSharedPointer<FileDbLink::DBInfo> dup, elems) { + if(dup != line && line->size() == dup->size() ) { + if (!topLevelItem) { + topLevelItem = new QTreeWidgetItem(); + topLevelItem->setData(0, Qt::DisplayRole, "Size"); + if(!item) + item = createItem(*line); + item->addChild(topLevelItem); + anyAdded = true; + } + topLevelItem->addChild(createItem(*dup)); + } + } + } + + if (showMTimeDups) { + QTreeWidgetItem* topLevelItem = 0; + foreach(QSharedPointer<FileDbLink::DBInfo> dup, elems) { + if(dup != line && line->mtime() == dup->mtime() ) { + if (!topLevelItem) { + topLevelItem = new QTreeWidgetItem(); + topLevelItem->setData(0, Qt::DisplayRole, "MTime"); + if(!item) + item = createItem(*line); + item->addChild(topLevelItem); + anyAdded = true; + } + topLevelItem->addChild(createItem(*dup)); + } + } + } + + if (showCheckSumDups) { + QTreeWidgetItem* topLevelItem = 0; + foreach(QSharedPointer<FileDbLink::DBInfo> dup, elems) { + if(dup != line && line->checksum() == dup->checksum() ) { + if (!topLevelItem) { + topLevelItem = new QTreeWidgetItem(); + topLevelItem->setData(0, Qt::DisplayRole, "Checksum"); + if(!item) + item = createItem(*line); + item->addChild(topLevelItem); + anyAdded = true; + } + topLevelItem->addChild(createItem(*dup)); + } + } + } + + if (editDistanceCutoff < 1.0) { + QTreeWidgetItem* topLevelItem = 0; + QMultiMap<int, QSharedPointer<FileDbLink::DBInfo> > oList; + + int absoluteCutoff = line->name().length() * editDistanceCutoff; + foreach(QSharedPointer<FileDbLink::DBInfo> dup, elems) { + if(dup != line) { + int distance = EditDistance::Compute(line->name(), dup->name()); + + if (distance <= absoluteCutoff) { + oList.insert(distance, dup); + } + } + } + + if (oList.size() > 0 ) { + topLevelItem = new QTreeWidgetItem(); + topLevelItem->setData(0, Qt::DisplayRole, "Editdistance"); + if(!item) + item = createItem(*line); + item->addChild(topLevelItem); + anyAdded = true; + } + + foreach(QSharedPointer<FileDbLink::DBInfo> dup, oList.values()) { + topLevelItem->addChild(createItem(*dup)); + } + } + + + + if (item) + tw->addTopLevelItem(item); + emit populateProgress(++n); + if (n % 64 == 0) { + QCoreApplication::processEvents(); + } + } + tw->setUpdatesEnabled(true); + +} + + +DataController::DataController() : showFullPath(false) +{ + populateDelay = new QTimer(this); + populateDelay->setSingleShot(true); + populateDelay->setInterval(500); + connect(populateDelay, SIGNAL(timeout()), this, SLOT(populate())); + + dblink = new MemoryDbLink(); + + findFiles(QDir("."), *dblink); + + mw = new QMainWindow(); + QMenuBar* mb = new QMenuBar(); + + QMenu* menu = mb->addMenu("&View"); + QAction* action = menu->addAction("Show full path"); + action->setCheckable(true); + connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowFullPath(bool))); + + mw->setMenuBar(mb); + + QToolBar* filterBar = new QToolBar("Filters"); + + nameFilter = filterBar->addAction("Name"); + nameFilter->setCheckable(true); + connect(nameFilter, SIGNAL(toggled(bool)), this, SLOT(delayPopulate())); + + sizeFilter = filterBar->addAction("Size"); + sizeFilter->setCheckable(true); + connect(sizeFilter, SIGNAL(toggled(bool)), this, SLOT(delayPopulate())); + + mtimeFilter = filterBar->addAction("MTime"); + mtimeFilter->setCheckable(true); + connect(mtimeFilter, SIGNAL(toggled(bool)), this, SLOT(delayPopulate())); + + checksumFilter = filterBar->addAction("Checksum"); + checksumFilter->setCheckable(true); + connect(checksumFilter, SIGNAL(toggled(bool)), this, SLOT(delayPopulate())); + + QWidget* widget = new QWidget(); + QLayout* layout = new QHBoxLayout(); + layout->setContentsMargins(0,0,0,0); + widget->setLayout(layout); + layout->addWidget(new QLabel("Edit distance", widget)); + editCutoffSpin = new QSpinBox(widget); + layout->addWidget(editCutoffSpin); + editCutoffSpin->setMinimum(0); + editCutoffSpin->setMaximum(100); + editCutoffSpin->setValue(70); + editCutoffSpin->setSingleStep(10); + editCutoffSpin->setSuffix("%"); + connect(editCutoffSpin, SIGNAL(valueChanged(int)), this, SLOT(delayPopulate())); + filterBar->addWidget(widget); + + mw->addToolBar(filterBar); + + tw = new QTreeWidget(mw); + mw->setCentralWidget(tw); + tw->setEditTriggers(QAbstractItemView::NoEditTriggers); + + tw->setHeaderLabels(QString("Path;Size;Date;Checksum").split(";")); + + populate(); + + tw->setSortingEnabled(true); + tw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tw->setSelectionBehavior(QAbstractItemView::SelectRows); + //tw->resizeColumnsToContents(); + mw->resize(800,800); + mw->show(); + + +} + +DataController::~DataController() +{ +} + + +void DataController::cellDoubleClicked(int row, int column) +{ + if(column == 0) { + toggleShowFullPath(); + } +} + + +void DataController::setShowFullPath(bool showFullPath) +{ + this->showFullPath = showFullPath; + + tw->setSortingEnabled(false); + + int role = (showFullPath)?32:33; + for (int row = 0; row < tw->topLevelItemCount(); ++row) { + QTreeWidgetItem* pathItem = tw->topLevelItem(row); + pathItem->setData(0, Qt::DisplayRole, pathItem->data(0,role)); + } + tw->setSortingEnabled(true); +} + +bool DataController::toggleShowFullPath() +{ + bool showFullPath = ! this->showFullPath; + setShowFullPath(showFullPath); + return showFullPath; +}
