diff --git a/cfile.cpp b/cfile.cpp index eae91e0..61605f0 100644 --- a/cfile.cpp +++ b/cfile.cpp @@ -1,11 +1,22 @@ +#include "common.h" + #include "cfile.h" +#include + #include #include -cFile::cFile(const QString& dir, const QString& file, const QDateTime& dateTime, const qint64& size, QObject* parent) : - QObject(parent), +cFile::cFile() : + m_dir(""), + m_file(""), + m_dateTime(QDateTime()), + m_size(0) +{ +} + +cFile::cFile(const QString& dir, const QString& file, const QDateTime& dateTime, const qint64& size) : m_dir(dir), m_file(file), m_dateTime(dateTime), @@ -50,26 +61,47 @@ qint64 cFile::size() return(m_size); } +bool cFile::operator==(const cFile& other) const +{ + if(g_bMatchDir) + if(m_dir != other.m_dir) + return(false); + if(g_bMatchFile) + if(m_file != other.m_file) + return(false); + if(g_bMatchDateTime) + if(m_dateTime != other.m_dateTime) + return(false); + if(g_bMatchSize) + if(m_size != other.m_size) + return(false); + + return(true); +} + void cFileList::parseLine(const QString& curDir, const QString& line) { QString date; QString time; QString size; QString file; + QString dir; date = line.left(10); time = line.mid(12, 5); size = line.mid(17, 18); file = line.mid(36); + dir = curDir; size = size.replace("(", "").replace(")", "").replace(QChar(0xA0), "").replace(" ", "").replace(".", ""); QDateTime dateTime = QDateTime(QDate::fromString(date, "dd.MM.yyyy"), QTime::fromString(time, "hh:mm")); - add(curDir, file, dateTime, size.toLongLong(), false); + if(file.endsWith(".nef", Qt::CaseInsensitive)) + add(dir.replace("\\", "/"), file, dateTime, size.toLongLong(), false); } -bool cFileList::load(const QString& file) +bool cFileList::load(const QString& file, QProgressBar* lpProgressBar) { clear(); @@ -78,7 +110,10 @@ bool cFileList::load(const QString& file) if(!inFile.open(QIODevice::ReadOnly)) return(false); + qint64 cur = 0; + qint64 max = inFile.size(); + lpProgressBar->setRange(0, 100); QTextStream in(&inFile); QString curDir = ""; @@ -86,6 +121,7 @@ bool cFileList::load(const QString& file) while(!in.atEnd()) { QString line = in.readLine(); + cur += line.length()+2; if(line.left(17) == " Volume in drive ") continue; @@ -101,6 +137,9 @@ bool cFileList::load(const QString& file) curDir = line.mid(14); else parseLine(curDir, line); + + lpProgressBar->setValue(static_cast(cur*100/max)); + qApp->processEvents(); } inFile.close(); @@ -118,7 +157,7 @@ cFile* cFileList::add(const QString& dir, const QString& file, const QDateTime& if(!lpFile) { lpFile = new cFile(dir, file, dateTime, size); - append(lpFile); + append(*lpFile); } return(lpFile); } @@ -127,9 +166,23 @@ cFile* cFileList::find(const QString& dir, const QString& file, const QDateTime& { for(cFileList::iterator i = begin();i != end();i++) { - cFile* lpFile = *i; - if(lpFile->compare(dir, file, dateTime, size)) - return(lpFile); + if(i->compare(dir, file, dateTime, size)) + return(&(*i)); } return(nullptr); } + +bool cFileList::contains(cFile& file, bool bDir, bool bFile, bool bDate, bool bSize) +{ + g_bMatchDir = bDir; + g_bMatchFile = bFile; + g_bMatchDateTime = bDate; + g_bMatchSize = bSize; + + return(QList::contains(file)); +} + +bool cFileList::contains(cFile& file) +{ + return(QList::contains(file)); +} diff --git a/cfile.h b/cfile.h index 78cb665..0bdddae 100644 --- a/cfile.h +++ b/cfile.h @@ -7,13 +7,14 @@ #include #include #include +#include -class cFile : public QObject +class cFile { - Q_OBJECT public: - explicit cFile(const QString& dir, const QString& file, const QDateTime& dateTime, const qint64& size, QObject *parent = nullptr); + cFile(); + explicit cFile(const QString& dir, const QString& file, const QDateTime& dateTime, const qint64& size); virtual ~cFile(); bool compare(const QString& dir, const QString& file, const QDateTime& dateTime, const qint64& size); @@ -22,6 +23,10 @@ public: QString file(); QDateTime dateTime(); qint64 size(); + + void setMatch(bool dir, bool file, bool dateTime, bool size); + + bool operator==(const cFile& other) const; private: QString m_dir; QString m_file; @@ -29,15 +34,18 @@ private: qint64 m_size; }; +Q_DECLARE_METATYPE(cFile) Q_DECLARE_METATYPE(cFile*) -class cFileList : public QList +class cFileList : public QList { public: - bool load(const QString& file); + bool load(const QString& file, QProgressBar* lpProgressBar = nullptr); cFile* add(const QString& dir, const QString& file, const QDateTime& dateTime, const qint64& size, bool search = true); cFile* find(const QString& dir, const QString& file, const QDateTime& dateTime, const qint64& size); + bool contains(cFile& file); + bool contains(cFile& file, bool bDir, bool bFile, bool bDate, bool bSize); private: void parseLine(const QString& curDir, const QString& line); }; diff --git a/cmainwindow.cpp b/cmainwindow.cpp index f974417..b39f138 100644 --- a/cmainwindow.cpp +++ b/cmainwindow.cpp @@ -1,6 +1,18 @@ +#include "common.h" + #include "cmainwindow.h" #include "ui_cmainwindow.h" +#include + + +//#define TREEVIEW + +bool g_bMatchDir = true; +bool g_bMatchFile = true; +bool g_bMatchDateTime = true; +bool g_bMatchSize = true; + bool fileSort(cFile* file1, cFile* file2) { @@ -18,15 +30,24 @@ bool fileSort(cFile* file1, cFile* file2) cMainWindow::cMainWindow(QWidget *parent) : QMainWindow(parent), - ui(new Ui::cMainWindow) + ui(new Ui::cMainWindow), + m_lpLeftListModel(nullptr), + m_lpRightListModel(nullptr), + m_lpLeftListProxyModel(nullptr), + m_lpRightListProxyModel(nullptr), + m_lpProgressBar(nullptr), + m_initializing(true), + m_loading(false) { - ui->setupUi(this); + initUI(); + createActions(); - m_lpLeftListModel = new QStandardItemModel(0, 1); - ui->m_lpLeftList->setModel(m_lpLeftListModel); + ui->m_lpMatchDir->setChecked(g_bMatchDir); + ui->m_lpMatchFile->setChecked(g_bMatchFile); + ui->m_lpMatchDateTime->setChecked(g_bMatchDateTime); + ui->m_lpMatchSize->setChecked(g_bMatchSize); - m_lpRightListModel = new QStandardItemModel(0, 1); - ui->m_lpRightList->setModel(m_lpRightListModel); + m_initializing = false; } cMainWindow::~cMainWindow() @@ -34,38 +55,313 @@ cMainWindow::~cMainWindow() delete ui; } -void cMainWindow::on_m_lpLoadListFromFileLeft_clicked() +void cMainWindow::closeEvent(QCloseEvent *event) { - m_listLeft.load("C:\\Users\\VET0572\\Documents\\github\\build-dir2csv-Desktop_Qt_5_13_0_MinGW_64_bit-Release\\deploy\\photos.txt"); -// std::sort(m_listLeft.begin(), m_listRight.end(), fileSort); - displayList(m_lpLeftListModel, m_listLeft); + QSettings settings; + settings.setValue("main/width", QVariant::fromValue(size().width())); + settings.setValue("main/height", QVariant::fromValue(size().height())); + settings.setValue("main/x", QVariant::fromValue(x())); + settings.setValue("main/y", QVariant::fromValue(y())); + if(this->isMaximized()) + settings.setValue("main/maximized", QVariant::fromValue(true)); + else + settings.setValue("main/maximized", QVariant::fromValue(false)); + + QList sizes = ui->m_lpSplitter->sizes(); + + for(int x = 0;x < sizes.count();x++) + settings.setValue(QString("main/splitter%1").arg(x+1), QVariant::fromValue(sizes[x])); + + event->accept(); } -void cMainWindow::on_m_lpLoadListFromFileRight_clicked() +void cMainWindow::initUI() { - m_listRight.load("C:\\Users\\VET0572\\Documents\\github\\build-dir2csv-Desktop_Qt_5_13_0_MinGW_64_bit-Release\\deploy\\photos1.txt"); -// std::sort(m_listRight.begin(), m_listRight.end(), fileSort); - displayList(m_lpRightListModel, m_listRight); + ui->setupUi(this); + + m_lpProgressBar = new QProgressBar(this); + m_lpProgressBar->setVisible(false); + ui->m_lpStatusBar->addPermanentWidget(m_lpProgressBar); + + m_lpLeftListModel = new QStandardItemModel(0, 1); + m_lpLeftListProxyModel = new cSortFilterProxyModel(this); + ui->m_lpLeftList->setModel(m_lpLeftListProxyModel); + m_lpLeftListProxyModel->setSourceModel(m_lpLeftListModel); + + m_lpRightListModel = new QStandardItemModel(0, 1); + m_lpRightListProxyModel = new cSortFilterProxyModel(this); + ui->m_lpRightList->setModel(m_lpRightListProxyModel); + m_lpRightListProxyModel->setSourceModel(m_lpRightListModel); + + QSettings settings; + + if(!settings.value("main/maximized").toBool()) + { + qint32 iX = settings.value("main/x", QVariant::fromValue(-1)).toInt(); + qint32 iY = settings.value("main/y", QVariant::fromValue(-1)).toInt(); + qint32 iWidth = settings.value("main/width", QVariant::fromValue(-1)).toInt(); + qint32 iHeight = settings.value("main/height", QVariant::fromValue(-1)).toInt(); + + if(iWidth != -1 && iHeight != -1) + resize(iWidth, iHeight); + if(iX != -1 && iY != -1) + move(iX, iY); + } + + qint32 iWidth1 = settings.value("main/splitter1", QVariant::fromValue(-1)).toInt(); + qint32 iWidth2 = settings.value("main/splitter2", QVariant::fromValue(-1)).toInt(); + + ui->m_lpSplitter->setSizes(QList() << iWidth1 << iWidth2); } -void cMainWindow::displayList(QStandardItemModel* lpModel, cFileList& fileList) +void cMainWindow::createActions() { + setToolButtonStyle(Qt::ToolButtonFollowStyle); + + createFileActions(); + createContextActions(); + + connect(ui->m_lpLoadListFromFileLeft, &QToolButton::clicked, this, &cMainWindow::onLoadListFromFileLeft); + connect(ui->m_lpLoadListFromFileRight, &QToolButton::clicked, this, &cMainWindow::onLoadListFromFileRight); + + connect(ui->m_lpLeftList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cMainWindow::onLeftListSelected); + connect(ui->m_lpRightList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cMainWindow::onRightListSelected); + + connect(ui->m_lpMatchDir, &QCheckBox::clicked, this, &cMainWindow::onMatchDirChecked); + connect(ui->m_lpMatchFile, &QCheckBox::clicked, this, &cMainWindow::onMatchFileChecked); + connect(ui->m_lpMatchDateTime, &QCheckBox::clicked, this, &cMainWindow::onMatchDateTimeChecked); + connect(ui->m_lpMatchSize, &QCheckBox::clicked, this, &cMainWindow::onMatchSizeChecked); +} + +void cMainWindow::createFileActions() +{ +} + +void cMainWindow::createContextActions() +{ +} + +void cMainWindow::onLoadListFromFileLeft() +{ + m_loading = true; + m_lpProgressBar->setVisible(true); + m_listLeft.load("C:\\Users\\VET0572\\Documents\\github\\build-dir2csv-Desktop_Qt_5_13_0_MinGW_64_bit-Release\\deploy\\photos.txt", m_lpProgressBar); + displayList(ui->m_lpLeftList, m_lpLeftListModel, m_listLeft); + m_lpProgressBar->setVisible(false); + m_loading = false; +} + +void cMainWindow::onLoadListFromFileRight() +{ + m_loading = true; + m_lpProgressBar->setVisible(true); + m_listRight.load("C:\\Users\\VET0572\\Documents\\github\\build-dir2csv-Desktop_Qt_5_13_0_MinGW_64_bit-Release\\deploy\\photos1.txt", m_lpProgressBar); + displayList(ui->m_lpRightList, m_lpRightListModel, m_listRight); + m_lpProgressBar->setVisible(false); + m_loading = false; +} + +#ifdef TREEVIEW +QStandardItem* insertPath(QTreeView* lpView, QStandardItem* lpRootItem, QString szPath) +{ + if(!lpRootItem) + return(nullptr); + + QStringList szPathList = szPath.split("/"); + QStandardItem* lpCurRoot = lpRootItem; + int path; + bool bFound; + QString szPath1 = ""; + + for(path = 0;path < szPathList.count();path++) + { + bFound = false; + for(int x = 0;x < lpCurRoot->rowCount();x++) + { + QStandardItem* lpCurItem = lpCurRoot->child(x, 0); + + if(!lpCurItem->text().compare(szPathList[path], Qt::CaseInsensitive)) + { + lpCurRoot = lpCurItem; + bFound = true; + break; + } + } + + if(!bFound) + break; + + szPath1.append(szPathList[path]+"/"); + } + + for(;path < szPathList.count();path++) + { + szPath1.append(szPathList[path]); + + QStandardItem* lpNewItem = new QStandardItem(szPathList[path]); + + lpCurRoot->appendRow(lpNewItem); + lpView->setFirstColumnSpanned(lpRootItem->rowCount()-1, lpRootItem->index(), true); + + lpNewItem->setData(QVariant::fromValue(szPath1), Qt::UserRole+1); + szPath1.append("/"); + + lpCurRoot = lpNewItem; + } + + return(lpCurRoot); +} +#endif + +void cMainWindow::displayList(QTreeView* lpView, QStandardItemModel* lpModel, cFileList& fileList) +{ + lpView->setUpdatesEnabled(false); + lpModel->clear(); - QStringList header; - header << "directory" << "file" << "date/time" << "size"; + QStringList header; +#ifdef TREEVIEW + header << "file" << "date/time" << "size"; + QStandardItem* lpDir = nullptr; +#else + header << "path" << "file" << "date/time" << "size"; +#endif + lpModel->setHorizontalHeaderLabels(header); + QStandardItem* lpRoot = lpModel->invisibleRootItem(); for(cFileList::iterator i = fileList.begin();i != fileList.end();i++) { QList items; - cFile* lpFile = *i; + cFile* lpFile = &(*i); +#ifdef TREEVIEW + lpDir = insertPath(lpView, lpRoot, lpFile->dir()); +#else items.append(new QStandardItem(lpFile->dir())); +#endif + items.append(new QStandardItem(lpFile->file())); items.append(new QStandardItem(lpFile->dateTime().toString())); items.append(new QStandardItem(QString::number(lpFile->size()))); + items[0]->setData(QVariant::fromValue(lpFile), Qt::UserRole+1); + items[1]->setData(QVariant::fromValue(lpFile), Qt::UserRole+1); + items[2]->setData(QVariant::fromValue(lpFile), Qt::UserRole+1); +#ifdef TREEVIEW + items[2]->setTextAlignment(Qt::AlignRight); +#else + items[3]->setData(QVariant::fromValue(lpFile), Qt::UserRole+1); + items[3]->setTextAlignment(Qt::AlignRight); +#endif - lpModel->appendRow(items); +#ifdef TREEVIEW + lpDir->appendRow(items); +#else + lpRoot->appendRow(items); +#endif } + +#ifdef TREEVIEW + lpView->expandAll(); +#endif + lpView->resizeColumnToContents(0); + lpView->resizeColumnToContents(1); + lpView->resizeColumnToContents(2); +#ifndef TREEVIEW + lpView->resizeColumnToContents(3); +#endif + lpView->setUpdatesEnabled(true); + lpView->update(); +} + +void cMainWindow::onLeftListSelected(const QItemSelection& selection, const QItemSelection& /*previous*/) +{ + if(m_loading) + return; + + if(!selection.indexes().count()) + return; + + QModelIndex index = selection.indexes()[0]; + if(!index.isValid()) + return; + + cFile* lpFile = index.data(Qt::UserRole+1).value(); + if(!lpFile) + return; + + m_lpLeftListProxyModel->setFilterFile(nullptr); + m_lpRightListProxyModel->setFilterFile(lpFile); +} + +void cMainWindow::onRightListSelected(const QItemSelection& selection, const QItemSelection& /*previous*/) +{ + if(m_loading) + return; + + if(!selection.indexes().count()) + return; + + QModelIndex index = selection.indexes()[0]; + if(!index.isValid()) + return; + + cFile* lpFile = index.data(Qt::UserRole+1).value(); + if(!lpFile) + return; + + m_lpRightListProxyModel->setFilterFile(nullptr); + m_lpLeftListProxyModel->setFilterFile(lpFile); +} + +void cMainWindow::onMatchDirChecked(bool checked) +{ + if(m_initializing) + return; + + g_bMatchDir = checked; + + if(m_lpLeftListProxyModel->filterFile()) + m_lpLeftListProxyModel->invalidate(); + if(m_lpRightListProxyModel->filterFile()) + m_lpRightListProxyModel->invalidate(); +} + +void cMainWindow::onMatchFileChecked(bool checked) +{ + if(m_initializing) + return; + + g_bMatchFile = checked; + + if(m_lpLeftListProxyModel->filterFile()) + m_lpLeftListProxyModel->invalidate(); + if(m_lpRightListProxyModel->filterFile()) + m_lpRightListProxyModel->invalidate(); +} + +void cMainWindow::onMatchDateTimeChecked(bool checked) +{ + if(m_initializing) + return; + + g_bMatchDateTime = checked; + + if(m_lpLeftListProxyModel->filterFile()) + m_lpLeftListProxyModel->invalidate(); + if(m_lpRightListProxyModel->filterFile()) + m_lpRightListProxyModel->invalidate(); +} + +void cMainWindow::onMatchSizeChecked(bool checked) +{ + if(m_initializing) + return; + + g_bMatchSize = checked; + + if(m_lpLeftListProxyModel->filterFile()) + m_lpLeftListProxyModel->invalidate(); + if(m_lpRightListProxyModel->filterFile()) + m_lpRightListProxyModel->invalidate(); } diff --git a/cmainwindow.h b/cmainwindow.h index c3c0d39..a2ad1a0 100644 --- a/cmainwindow.h +++ b/cmainwindow.h @@ -3,10 +3,12 @@ #include "cfile.h" +#include "csortfilterproxymodel.h" #include #include #include +#include namespace Ui { @@ -22,17 +24,38 @@ public: ~cMainWindow(); private slots: - void on_m_lpLoadListFromFileLeft_clicked(); - void on_m_lpLoadListFromFileRight_clicked(); + void onLoadListFromFileLeft(); + void onLoadListFromFileRight(); + + void onLeftListSelected(const QItemSelection& selection, const QItemSelection& previous); + void onRightListSelected(const QItemSelection& selection, const QItemSelection& previous); + + void onMatchDirChecked(bool checked); + void onMatchFileChecked(bool checked); + void onMatchDateTimeChecked(bool checked); + void onMatchSizeChecked(bool checked); private: - Ui::cMainWindow* ui; - QStandardItemModel* m_lpLeftListModel; - QStandardItemModel* m_lpRightListModel; - cFileList m_listLeft; - cFileList m_listRight; + Ui::cMainWindow* ui; + QStandardItemModel* m_lpLeftListModel; + QStandardItemModel* m_lpRightListModel; + cSortFilterProxyModel* m_lpLeftListProxyModel; + cSortFilterProxyModel* m_lpRightListProxyModel; + cFileList m_listLeft; + cFileList m_listRight; + QProgressBar* m_lpProgressBar; - void displayList(QStandardItemModel* lpModel, cFileList& fileList); + bool m_initializing; + bool m_loading; + + void initUI(); + void displayList(QTreeView* lpView, QStandardItemModel* lpModel, cFileList& fileList); + void createActions(); + void createFileActions(); + void createContextActions(); + +protected: + void closeEvent(QCloseEvent* event); }; #endif // CMAINWINDOW_H diff --git a/cmainwindow.ui b/cmainwindow.ui index f35f0c6..a178035 100644 --- a/cmainwindow.ui +++ b/cmainwindow.ui @@ -16,18 +16,39 @@ - + - + - + - from File + match path - + + + match file + + + + + + + match date/time + + + + + + + match size + + + + + Qt::Horizontal @@ -42,38 +63,81 @@ - - - - - - - - - - - - from File - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - + + + Qt::Horizontal + + + + + + + + + from File + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + false + + + + + + + + + + + + + from File + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + false + + + + + + diff --git a/common.h b/common.h new file mode 100644 index 0000000..7055390 --- /dev/null +++ b/common.h @@ -0,0 +1,11 @@ +#ifndef COMMON_H +#define COMMON_H + + +extern bool g_bMatchDir; +extern bool g_bMatchFile; +extern bool g_bMatchDateTime; +extern bool g_bMatchSize; + + +#endif diff --git a/compareDir.pro b/compareDir.pro index 1aab9ef..12605e7 100644 --- a/compareDir.pro +++ b/compareDir.pro @@ -26,12 +26,15 @@ CONFIG += c++11 SOURCES += \ cfile.cpp \ + csortfilterproxymodel.cpp \ main.cpp \ cmainwindow.cpp HEADERS += \ cfile.h \ - cmainwindow.h + cmainwindow.h \ + common.h \ + csortfilterproxymodel.h FORMS += \ cmainwindow.ui diff --git a/csortfilterproxymodel.cpp b/csortfilterproxymodel.cpp new file mode 100644 index 0000000..af004a9 --- /dev/null +++ b/csortfilterproxymodel.cpp @@ -0,0 +1,36 @@ +#include "csortfilterproxymodel.h" + + +cSortFilterProxyModel::cSortFilterProxyModel(QObject* parent) : + QSortFilterProxyModel(parent), + m_lpFile(nullptr) +{ +} + +void cSortFilterProxyModel::setFilterFile(cFile* lpFile) +{ + m_lpFile = lpFile; + + invalidateFilter(); +} + +cFile* cSortFilterProxyModel::filterFile() +{ + return(m_lpFile); +} + +bool cSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + if(!m_lpFile) + return(true); + + bool bValid = false; + + QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent); + cFile* lpFile = sourceModel()->data(index0, Qt::UserRole+1).value(); + + if(!lpFile) + return(true); + + return(*m_lpFile == *lpFile); +} diff --git a/csortfilterproxymodel.h b/csortfilterproxymodel.h new file mode 100644 index 0000000..b54812c --- /dev/null +++ b/csortfilterproxymodel.h @@ -0,0 +1,27 @@ +#ifndef CSORTFILTERPROXYMODEL_H +#define CSORTFILTERPROXYMODEL_H + + +#include "cfile.h" + +#include + + +class cSortFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + cSortFilterProxyModel(QObject* parent = nullptr); + + cFile* filterFile(); + void setFilterFile(cFile* lpFile); + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + +private: + cFile* m_lpFile; +}; + +#endif // CSORTFILTERPROXYMODEL_H diff --git a/main.cpp b/main.cpp index a976cb8..76e1385 100644 --- a/main.cpp +++ b/main.cpp @@ -1,12 +1,26 @@ #include "cmainwindow.h" #include +#include + int main(int argc, char *argv[]) { - QApplication a(argc, argv); - cMainWindow w; - w.showMaximized(); + QApplication a(argc, argv); + + a.setApplicationDisplayName("pictureLibrary"); + a.setOrganizationName("WIN-DESIGN"); + a.setOrganizationDomain("windesign.at"); + a.setApplicationName("pictureLibrary"); + + QSettings settings; + + cMainWindow w; + + if(settings.value("main/maximized").toBool()) + w.showMaximized(); + else + w.show(); return a.exec(); }