Mercurial > dedupe
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(); -} - -
