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;
+}