aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--mingui/CMakeLists.txt25
-rw-r--r--mingui/main.cpp161
-rw-r--r--qdeduper/CMakeLists.txt18
-rw-r--r--qdeduper/README.md (renamed from mingui/README.md)0
-rw-r--r--qdeduper/imageitem.cpp (renamed from mingui/imageitem.cpp)0
-rw-r--r--qdeduper/imageitem.hpp (renamed from mingui/imageitem.hpp)0
-rw-r--r--qdeduper/main.cpp29
-rw-r--r--qdeduper/mingui.cpp (renamed from mingui/mingui.cpp)69
-rw-r--r--qdeduper/mingui.hpp (renamed from mingui/mingui.hpp)6
10 files changed, 104 insertions, 206 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f535cf3..9c85b78 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,5 +20,5 @@ option(BUILD_SHARED_LIBS ON)
add_compile_definitions(PATH_VALSIZE=${PATH_VALSIZE})
add_subdirectory(xsig)
-
+add_subdirectory(qdeduper)
add_subdirectory(tests)
diff --git a/mingui/CMakeLists.txt b/mingui/CMakeLists.txt
deleted file mode 100644
index 3503f98..0000000
--- a/mingui/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-cmake_minimum_required(VERSION 3.10.0)
-
-project(mingui VERSION 0.0.1 LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-
-find_package(Qt5 REQUIRED COMPONENTS Widgets)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-add_executable(mingui
- main.cpp
- mingui.cpp
- imageitem.cpp
-)
-
-target_link_libraries(mingui
- Qt5::Widgets
-)
diff --git a/mingui/main.cpp b/mingui/main.cpp
deleted file mode 100644
index 8199cb9..0000000
--- a/mingui/main.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-#include <cstdio>
-#include <algorithm>
-#include <filesystem>
-#include <map>
-#include <string>
-#include <vector>
-#include <unordered_map>
-#include <utility>
-
-#include <QWidget>
-#include <QApplication>
-#include "mingui.hpp"
-
-using std::size_t;
-namespace fs = std::filesystem;
-
-std::unordered_map<fs::path, size_t> fnmap;
-std::vector<fs::path> fns;
-std::map<std::pair<size_t, size_t>, double> dist;
-std::vector<size_t> par;
-std::vector<std::vector<size_t>> lists;
-
-MinGuiWidget *w = nullptr;
-size_t curlist;
-
-size_t get_root(size_t x)
-{
- if (x != par[x])
- return par[x] = get_root(par[x]);
- return x;
-}
-
-void combine(size_t x, size_t y)
-{
- x = get_root(x);
- y = get_root(y);
- par[x] = y;
-}
-
-void load_result(const char* rp)
-{
- FILE *f = fopen(rp, "rb");
- while (1)
- {
- int l;
- double d;
- fs::path::string_type s1, s2;
- if (feof(f)) break;
- fread(&l, sizeof(int), 1, f);
- s1.resize(l);
- fread(s1.data(), sizeof(fs::path::value_type), l, f);
- fnmap.try_emplace(s1, fnmap.size() + 1);
- fread(&l, sizeof(int), 1, f);
- s2.resize(l);
- fread(s2.data(), sizeof(fs::path::value_type), l, f);
- fnmap.try_emplace(s2, fnmap.size() + 1);
- fread(&d, sizeof(double), 1, f);
- dist[std::make_pair(fnmap[s1], fnmap[s2])] = d;
- }
- fclose(f);
-}
-
-std::vector<fs::path> build_list(const std::vector<size_t> &l)
-{
- std::vector<fs::path> ret;
- for (auto &x : l)
- ret.push_back(fns[x]);
- return ret;
-}
-
-std::map<std::pair<size_t, size_t>, double> build_dists(const std::vector<size_t> &l)
-{
- std::map<std::pair<size_t, size_t>, double> ret;
- for (size_t i = 0; i < l.size(); ++i)
- {
- for (size_t j = i + 1; j < l.size(); ++j)
- {
- size_t x = l[i], y = l[j];
- if (dist.find(std::make_pair(x, y)) != dist.end())
- ret[std::make_pair(i, j)] = dist[std::make_pair(x, y)];
- else if (dist.find(std::make_pair(y, x)) != dist.end())
- ret[std::make_pair(i, j)] = dist[std::make_pair(y, x)];
- }
- }
- return ret;
-}
-
-int main(int argc, char **argv)
-{
- if (argc < 2) return 1;
-
- load_result(argv[1]);
- printf("%lu known files\n", fnmap.size());
-
- par.resize(fnmap.size() + 1);
- fns.resize(fnmap.size() + 1);
- lists.resize(fnmap.size() + 1);
- for (auto &kp : fnmap)
- fns[kp.second] = kp.first;
-
- for (size_t i = 1; i < par.size(); ++i)
- par[i] = i;
- for (auto &kp : dist)
- {
- auto p = kp.first;
- combine(p.first, p.second);
- }
- for (size_t i = 1; i < par.size(); ++i)
- lists[get_root(i)].push_back(i);
-
- auto listend = std::remove_if(lists.begin(), lists.end(), [](auto &a){return a.size() < 2;});
- lists.erase(listend, lists.end());
- if (lists.empty()) return 0;
- for (auto &l : lists)
- {
- if (l.size())
- {
- for (auto &x : l)
- printf("%s,", fns[x].c_str());
- puts("");
- }
- }
- fflush(stdout);
-
- QApplication a(argc, argv);
-
- curlist = 0;
- w = new MinGuiWidget();
- w->show_images(build_list(lists[curlist]));
- w->update_distances(build_dists(lists[curlist]));
- w->update_viewstatus(curlist, lists.size());
- w->show();
- QObject::connect(w, &MinGuiWidget::next,
- []{
- if (curlist < lists.size() - 1) ++curlist;
- w->show_images(build_list(lists[curlist]));
- w->update_distances(build_dists(lists[curlist]));
- w->update_viewstatus(curlist, lists.size());
- });
- QObject::connect(w, &MinGuiWidget::prev,
- []{
- if (curlist > 0) --curlist;
- w->show_images(build_list(lists[curlist]));
- w->update_distances(build_dists(lists[curlist]));
- w->update_viewstatus(curlist, lists.size());
- });
- QObject::connect(w, &MinGuiWidget::switch_group,
- [](size_t g){
- if (g < lists.size())
- {
- curlist = g;
- w->show_images(build_list(lists[curlist]));
- w->update_distances(build_dists(lists[curlist]));
- w->update_viewstatus(curlist, lists.size());
- }
- });
-
- a.exec();
-
- return 0;
-}
diff --git a/qdeduper/CMakeLists.txt b/qdeduper/CMakeLists.txt
new file mode 100644
index 0000000..f862c16
--- /dev/null
+++ b/qdeduper/CMakeLists.txt
@@ -0,0 +1,18 @@
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+find_package(Qt5 REQUIRED COMPONENTS Widgets)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+set(CMAKE_AUTOUIC ON)
+
+add_executable(qdeduper
+ main.cpp
+ mingui.cpp
+ imageitem.cpp
+)
+
+target_link_libraries(qdeduper
+ xsig
+ Qt5::Widgets
+)
diff --git a/mingui/README.md b/qdeduper/README.md
index dff674f..dff674f 100644
--- a/mingui/README.md
+++ b/qdeduper/README.md
diff --git a/mingui/imageitem.cpp b/qdeduper/imageitem.cpp
index 6fee930..6fee930 100644
--- a/mingui/imageitem.cpp
+++ b/qdeduper/imageitem.cpp
diff --git a/mingui/imageitem.hpp b/qdeduper/imageitem.hpp
index 43fb0c8..43fb0c8 100644
--- a/mingui/imageitem.hpp
+++ b/qdeduper/imageitem.hpp
diff --git a/qdeduper/main.cpp b/qdeduper/main.cpp
new file mode 100644
index 0000000..9b40ea4
--- /dev/null
+++ b/qdeduper/main.cpp
@@ -0,0 +1,29 @@
+#include <cstdio>
+#include <algorithm>
+#include <filesystem>
+#include <map>
+#include <string>
+#include <vector>
+#include <unordered_map>
+#include <utility>
+
+#include <QWidget>
+#include <QApplication>
+#include "mingui.hpp"
+
+using std::size_t;
+namespace fs = std::filesystem;
+
+DeduperMainWindow *w = nullptr;
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+
+ w = new DeduperMainWindow();
+ w->show();
+
+ a.exec();
+
+ return 0;
+}
diff --git a/mingui/mingui.cpp b/qdeduper/mingui.cpp
index 494745a..317076c 100644
--- a/mingui/mingui.cpp
+++ b/qdeduper/mingui.cpp
@@ -9,6 +9,8 @@
#include <QCloseEvent>
#include <QMouseEvent>
#include <QScrollBar>
+#include <QMenuBar>
+#include <QMenu>
#include <QAction>
#include <QSplitter>
#include <QString>
@@ -41,18 +43,18 @@ const std::vector<int> keys = {
QString fsstr_to_qstring(const fs::path::string_type &s)
{
-#ifdef _WIN32 //the degenerate platform
+#if PATH_VALSIZE == 2 //the degenerate platform
return QString::fromStdWString(s);
#else
return QString::fromStdString(s);
#endif
}
-MinGuiWidget::MinGuiWidget()
+DeduperMainWindow::DeduperMainWindow()
{
this->setFont(QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont));
- this->setWindowTitle("deduper minigui");
- this->setLayout(new QVBoxLayout(this));
+ this->setWindowTitle("deduper");
+ this->setup_menu();
sb = this->statusBar();
sb->addPermanentWidget(permamsg = new QLabel());
QLabel *opm = new QLabel();
@@ -164,7 +166,40 @@ MinGuiWidget::MinGuiWidget()
nohotkeywarn = false;
}
-void MinGuiWidget::show_images(const std::vector<fs::path> &fns)
+void DeduperMainWindow::setup_menu()
+{
+ QMenu *file = this->menuBar()->addMenu("File");
+ QMenu *view = this->menuBar()->addMenu("View");
+ QMenu *mark = this->menuBar()->addMenu("Marks");
+ QMenu *help = this->menuBar()->addMenu("Help");
+
+ file->addAction("Create Database...");
+ file->addAction("Load Database...");
+ file->addAction("Save Database...");
+ file->addSeparator();
+ file->addAction("Search for Image...");
+ file->addSeparator();
+ file->addAction("Preferences...");
+ file->addAction("Exit");
+
+ view->addAction("Next Group");
+ view->addAction("Previous Group");
+ view->addSeparator();
+ QMenu *sort = view->addMenu("Sort by");
+ sort->addAction("File size");
+ sort->addAction("Image dimension");
+ sort->addAction("File path");
+
+ mark->addAction("Mark All");
+ mark->addAction("Mark None");
+ mark->addAction("Mark All within...");
+ mark->addAction("Review Marked Imagess");
+
+ help->addAction("View Documentation");
+ help->addAction("About");
+}
+
+void DeduperMainWindow::show_images(const std::vector<fs::path> &fns)
{
current_set = fns;
marks.clear();
@@ -191,7 +226,7 @@ void MinGuiWidget::show_images(const std::vector<fs::path> &fns)
mark_view_update(false);
}
-void MinGuiWidget::update_distances(const std::map<std::pair<size_t, size_t>, double> &d)
+void DeduperMainWindow::update_distances(const std::map<std::pair<size_t, size_t>, double> &d)
{
QString r;
for (auto &p : d)
@@ -207,14 +242,14 @@ void MinGuiWidget::update_distances(const std::map<std::pair<size_t, size_t>, do
infopanel->setText(r);
}
-void MinGuiWidget::update_viewstatus(std::size_t cur, std::size_t size)
+void DeduperMainWindow::update_viewstatus(std::size_t cur, std::size_t size)
{
permamsg->setText(QString("Viewing group %1 of %2").arg(cur + 1).arg(size));
ngroups = size;
curgroup = cur;
}
-void MinGuiWidget::save_list()
+void DeduperMainWindow::save_list()
{
QString fn = QFileDialog::getSaveFileName(this, "Save list", QString(), "*.txt");
FILE *f = fopen(fn.toStdString().c_str(), "w");
@@ -228,7 +263,7 @@ void MinGuiWidget::save_list()
fclose(f);
}
-void MinGuiWidget::load_list()
+void DeduperMainWindow::load_list()
{
QString fn = QFileDialog::getOpenFileName(this, "Load list", QString(), "*.txt");
FILE *f = fopen(fn.toStdString().c_str(), "r");
@@ -256,7 +291,7 @@ void MinGuiWidget::load_list()
mark_view_update();
}
-void MinGuiWidget::mark_toggle(size_t x)
+void DeduperMainWindow::mark_toggle(size_t x)
{
if (x < marks.size())
{
@@ -270,7 +305,7 @@ void MinGuiWidget::mark_toggle(size_t x)
mark_view_update();
}
-void MinGuiWidget::mark_all_but(size_t x)
+void DeduperMainWindow::mark_all_but(size_t x)
{
if (x < marks.size())
{
@@ -287,7 +322,7 @@ void MinGuiWidget::mark_all_but(size_t x)
mark_view_update();
}
-void MinGuiWidget::mark_all()
+void DeduperMainWindow::mark_all()
{
for (size_t i = 0; i < marks.size(); ++i)
{
@@ -297,7 +332,7 @@ void MinGuiWidget::mark_all()
mark_view_update();
}
-void MinGuiWidget::mark_none()
+void DeduperMainWindow::mark_none()
{
for (size_t i = 0; i < marks.size(); ++i)
{
@@ -308,7 +343,7 @@ void MinGuiWidget::mark_none()
mark_view_update();
}
-void MinGuiWidget::mark_view_update(bool update_msg)
+void DeduperMainWindow::mark_view_update(bool update_msg)
{
size_t m = 0;
for (size_t i = 0; i < current_set.size(); ++i)
@@ -327,7 +362,7 @@ void MinGuiWidget::mark_view_update(bool update_msg)
sb->showMessage(QString("%1 of %2 marked for deletion").arg(m).arg(current_set.size()), 1000);
}
-fs::path::string_type MinGuiWidget::common_prefix(const std::vector<fs::path> &fns)
+fs::path::string_type DeduperMainWindow::common_prefix(const std::vector<fs::path> &fns)
{
using fsstr = fs::path::string_type;
fsstr ret;
@@ -349,7 +384,7 @@ fs::path::string_type MinGuiWidget::common_prefix(const std::vector<fs::path> &f
return ret;
}
-void MinGuiWidget::resizeEvent(QResizeEvent *e)
+void DeduperMainWindow::resizeEvent(QResizeEvent *e)
{
QWidget::resizeEvent(e);
if (!id || !im) return;
@@ -357,7 +392,7 @@ void MinGuiWidget::resizeEvent(QResizeEvent *e)
id->resize(im->indexFromItem(im->item(i)));
}
-void MinGuiWidget::closeEvent(QCloseEvent *e)
+void DeduperMainWindow::closeEvent(QCloseEvent *e)
{
if (QMessageBox::StandardButton::Yes ==
QMessageBox::question(this, "Confirmation", "Really quit?",
diff --git a/mingui/mingui.hpp b/qdeduper/mingui.hpp
index f80561b..b8d13ef 100644
--- a/mingui/mingui.hpp
+++ b/qdeduper/mingui.hpp
@@ -21,7 +21,7 @@ class ImageItemDelegate;
namespace fs = std::filesystem;
-class MinGuiWidget : public QMainWindow
+class DeduperMainWindow : public QMainWindow
{
Q_OBJECT
private:
@@ -48,7 +48,9 @@ protected:
void resizeEvent(QResizeEvent *e) override;
void closeEvent(QCloseEvent *e) override;
public:
- MinGuiWidget();
+ DeduperMainWindow();
+
+ void setup_menu();
void show_images(const std::vector<std::filesystem::path> &fns);
void update_distances(const std::map<std::pair<std::size_t, std::size_t>, double> &d);
void update_viewstatus(std::size_t cur, std::size_t size);