changeset 5:5e4985407feb

Add commandline tool updateDeDupe. Fix removal of removed files from DB.
author Tom Fredrik Blenning Klaussen <bfg@blenning.no>
date Wed, 22 Aug 2012 00:41:15 +0200
parents f489b0c9bf99
children 7ebdd2373ea4
files CMakeLists.txt DataController.cpp DataController.hpp DeDupe.cpp FileDBLink.hpp SqliteDBLink.cpp SqliteDBLink.hpp main.cpp updateDeDupe.cpp
diffstat 9 files changed, 174 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Tue Aug 21 15:27:29 2012 +0200
+++ b/CMakeLists.txt	Wed Aug 22 00:41:15 2012 +0200
@@ -39,7 +39,6 @@
 SET(SOURCES
 	${CLASS_SOURCES}
 	${MOC_SOURCES}
-	main.cpp
 )
 
 SET(TEST_SOURCES
@@ -51,9 +50,12 @@
 
 
 SET(CMAKE_CXX_FLAGS "-g2 -Wall -Werror -fno-inline")
-ADD_EXECUTABLE(DeDupe ${SOURCES} ${MOC_SOURCES})
+ADD_EXECUTABLE(DeDupe DeDupe.cpp ${SOURCES} ${MOC_SOURCES})
 TARGET_LINK_LIBRARIES(DeDupe ${QT_LIBRARIES} ${SQLITE3_LIBRARIES})
 
+ADD_EXECUTABLE(updateDeDupe updateDeDupe.cpp ${SOURCES} ${MOC_SOURCES})
+TARGET_LINK_LIBRARIES(updateDeDupe ${QT_LIBRARIES} ${SQLITE3_LIBRARIES})
+
 ENABLE_TESTING()
 
 ADD_EXECUTABLE(TestEditDistance TestEditDistance.cpp ${TEST_SOURCES})
--- a/DataController.cpp	Tue Aug 21 15:27:29 2012 +0200
+++ b/DataController.cpp	Wed Aug 22 00:41:15 2012 +0200
@@ -10,6 +10,7 @@
 
 #include <QtGui/QApplication>
 #include <QtCore/QDir>
+#include <QtCore/QUrl>
 
 #include <QtCore/QDebug>
 #include <QtCore/QTimer>
@@ -17,6 +18,7 @@
 #include <QtCore/QDateTime>
 
 #include <QtGui/QMainWindow>
+#include <QtGui/QMessageBox>
 #include <QtGui/QDesktopServices>
 #include <QtGui/QTreeWidget>
 #include <QtGui/QHeaderView>
@@ -36,7 +38,7 @@
     findFiles(QDir(filename), list);
   }
 
-  foreach(QString filename, dir.entryList(QDir::Files)) {
+  foreach(QString filename, dir.entryList(QDir::Files | QDir::NoSymLinks)) {
     list << dir.absoluteFilePath(filename);
   }
 }
@@ -52,17 +54,25 @@
 {
   QStringList list = findFiles(dir);
 
-  QProgressBar bar;
-
   QDateTime last = QDateTime::currentDateTime();
 
-  bar.resize(200,25);
-  bar.setValue(0);
-  bar.setMinimum(0);
-  bar.setMaximum(list.size());
-  bar.show();
+  dblink.keepOnlyFromPrefix(dir.path(), list);
+
+  std::auto_ptr<QProgressBar> bar;
+
+  progressMax = list.size();
+
+  if (showGUI) {
+    bar = std::auto_ptr<QProgressBar>(new QProgressBar());
 
-  connect(this, SIGNAL(populateProgress(int)), &bar, SLOT(setValue(int)));
+    bar->resize(200,25);
+    bar->setValue(0);
+    bar->setMinimum(0);
+    bar->setMaximum(progressMax);
+    bar->show();
+
+    connect(this, SIGNAL(populateProgress(int)), bar.get(), SLOT(setValue(int)));
+  }
 
   int n = 0;
   foreach(QString filename, findFiles(dir)) {
@@ -271,6 +281,18 @@
 
 }
 
+void DataController::contextMenuRequested(const QPoint& point)
+{
+  contextMenuItem = tw->itemAt(point);
+  if (!contextMenu) {
+    contextMenu = new QMenu(tw);
+    QAction* deleteAction = contextMenu->addAction("Delete");
+    connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteFile()));    
+  }
+  contextMenu->popup(tw->mapToGlobal(point));
+}
+
+
 void DataController::setDir(const QDir& dir)
 {
   this->dir = dir.absolutePath();
@@ -336,6 +358,12 @@
   mw->addToolBar(filterBar);
 
   tw = new QTreeWidget(mw);
+  tw->setContextMenuPolicy( Qt::CustomContextMenu);
+  connect(tw, SIGNAL(customContextMenuRequested (const QPoint&)),
+	  this, SLOT(contextMenuRequested(const QPoint&)));
+  connect(tw, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
+	  this, SLOT(itemDoubleClicked(QTreeWidgetItem*, int)));
+
   mw->setCentralWidget(tw);
   tw->setEditTriggers(QAbstractItemView::NoEditTriggers);
 
@@ -360,8 +388,56 @@
   setup(QString(), QString(), showGUI);
 }
 
+#include <iostream>
+
+void DataController::progressUpdate(int p)
+{
+  QString str;
+  if (p == 0)
+    str.sprintf("Progress %6.2f%%", p * 100.0 / progressMax);
+  else
+    str.sprintf("\b\b\b\b\b\b%6.2f%%", p * 100.0 / progressMax);
+  std::cout<<str.toStdString();
+  std::cout.flush();
+}
+
+
+void DataController::deleteFile()
+{
+  QString path = contextMenuItem->data(0, 32).toString();
+  QMessageBox::StandardButton button =
+    QMessageBox::question(tw, "Confirm delete",
+			  QString("Do you really want to delete \"%1\"?").arg(path),
+			  QMessageBox::Cancel | QMessageBox::Ok,
+			  QMessageBox::Cancel);
+  if (button ==  QMessageBox::Ok) {
+    QFile file(path);
+    if (file.remove()) {
+      dblink->deleteFileFromDB(path);
+      populate();
+    }
+    else {
+      QMessageBox::warning(tw, "Delete failed", QString("Could not delete \"%1\"?").arg(file.fileName()));
+    }
+  }
+}
+
+
+void DataController::itemDoubleClicked (QTreeWidgetItem * item, int column)
+{
+  QUrl url = QUrl::fromLocalFile(item->data(0, 32).toString());
+  QDesktopServices::openUrl(url);  
+}
+
+
 void DataController::setup(const QString& dbpath_in, const QString& searchPath_in, bool showGUI)
 {
+  this->showGUI = showGUI;
+
+  contextMenu = 0;
+
+  connect(this, SIGNAL(populateProgress(int)), this, SLOT(progressUpdate(int)));
+
   QString dbpath;
   if (dbpath_in.size() > 0) {
     dbpath = dbpath_in;
@@ -406,14 +482,27 @@
 
   tw->setSortingEnabled(false);
 
-  int role = (showFullPath)?32:33;
+  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));
+    pathItem->setData(0, Qt::DisplayRole, pathItem->data(0, role));
+    setShowFullPath(pathItem, showFullPath);
   }
   tw->setSortingEnabled(true);
 }
 
+void DataController::setShowFullPath(QTreeWidgetItem* item, bool showFullPath)
+{
+  int role = (showFullPath) ? 32 : 33;
+  for (int row = 0; row < item->childCount(); ++row) {
+    QTreeWidgetItem* child = item->child(row);
+    QVariant data = child->data(0,role);
+    if (data.isValid())
+      child->setData(0, Qt::DisplayRole, data);
+    setShowFullPath(child, showFullPath);
+  }
+}
+
 bool DataController::toggleShowFullPath()
 {
   bool showFullPath = ! this->showFullPath;
--- a/DataController.hpp	Tue Aug 21 15:27:29 2012 +0200
+++ b/DataController.hpp	Wed Aug 22 00:41:15 2012 +0200
@@ -12,6 +12,9 @@
 class QAction;
 class QSpinBox;
 class QTimer;
+class QPoint;
+class QTreeWidgetItem;
+class QMenu;
 
 class DataController : QObject {
 private:
@@ -43,7 +46,14 @@
 signals:
   void populateProgress(int);
 
+private slots:
+  void progressUpdate(int);
+  void deleteFile();
+  void itemDoubleClicked (QTreeWidgetItem * item, int column);
+  void contextMenuRequested(const QPoint&);
+
 private:
+  static void setShowFullPath(QTreeWidgetItem* item, bool showFullPath);
   void setup(const QString& dbpath, const QString& searchPath, bool showGUI);
   void populate(bool showNameDups, bool showSizeDups,
 		bool showMTimeDups, bool showCheckSumDups,
@@ -67,7 +77,14 @@
 
   QTimer* populateDelay;
 
+  QMenu* contextMenu;
+  QTreeWidgetItem* contextMenuItem;
+
   QDir dir;
+
+  bool showGUI;
+
+  int progressMax;
 };
 
 #endif //DATACONTROLLER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DeDupe.cpp	Wed Aug 22 00:41:15 2012 +0200
@@ -0,0 +1,14 @@
+#include "DataController.hpp"
+
+#include <QtGui/QApplication>
+
+int main(int argc, char *argv[]) {
+
+  QApplication app(argc, argv);
+
+  DataController dc(true);
+
+  return app.exec();
+}
+
+
--- a/FileDBLink.hpp	Tue Aug 21 15:27:29 2012 +0200
+++ b/FileDBLink.hpp	Wed Aug 22 00:41:15 2012 +0200
@@ -98,6 +98,9 @@
   void updateIfModified(const QString& path);
 
   virtual void addFile(const QString& path, qint64 size, const QDateTime& dtime, const QByteArray& hash) = 0;
+  virtual void keepOnlyFromPrefix(const QString& prefix, const QStringList& files) = 0;
+  virtual void deleteFileFromDB(const QString& path) = 0;
+
   void addFile(const QString& path, qint64 size, const QDateTime& dtime);
   void addFile(const QFileInfo& fileinfo);
 
--- a/SqliteDBLink.cpp	Tue Aug 21 15:27:29 2012 +0200
+++ b/SqliteDBLink.cpp	Wed Aug 22 00:41:15 2012 +0200
@@ -158,3 +158,27 @@
 
   return values;
 }
+
+void SqliteDBLink::deleteFileFromDB(const QString& path)
+{
+  QSqlQuery query;
+    query.prepare("DELETE FROM files WHERE path = :path");
+    query.bindValue(":path", path);
+    if (!query.exec()) {
+      qDebug() << path << "::" << query.lastQuery() << "::" << query.lastError().text();
+    }
+}
+
+
+void SqliteDBLink::keepOnlyFromPrefix(const QString& prefix, const QStringList& files)
+{
+  QStringList list;
+  foreach(QSharedPointer<DBInfo> info, values(prefix)) {
+    if (!files.contains(info->path())) {
+      list << info->path();
+    }
+  }
+  foreach(QString path, list) {
+    deleteFileFromDB(path);
+  }
+}
--- a/SqliteDBLink.hpp	Tue Aug 21 15:27:29 2012 +0200
+++ b/SqliteDBLink.hpp	Wed Aug 22 00:41:15 2012 +0200
@@ -19,6 +19,8 @@
 
   QStringList toStringList();
   const QList<QSharedPointer<DBInfo> > values(const QString& prefix = QString() ) const;
+  virtual void keepOnlyFromPrefix(const QString& prefix, const QStringList& files);
+  virtual void deleteFileFromDB(const QString& path);
 
 private:
   void addFile(const DBInfo& info);
--- a/main.cpp	Tue Aug 21 15:27:29 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#include "DataController.hpp"
-
-#include <QtGui/QApplication>
-
-int main(int argc, char *argv[]) {
-
-  QApplication app(argc, argv);
-
-  DataController dc(true);
-
-  return app.exec();
-}
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/updateDeDupe.cpp	Wed Aug 22 00:41:15 2012 +0200
@@ -0,0 +1,10 @@
+#include "DataController.hpp"
+
+#include <QtGui/QApplication>
+
+int main(int argc, char *argv[]) {
+
+  DataController dc(false);
+}
+
+