aboutsummaryrefslogtreecommitdiff
path: root/qdeduper
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2022-09-24 23:50:35 -0400
committerGravatar Chris Xiong <chirs241097@gmail.com> 2022-09-24 23:50:35 -0400
commit2962525cf5b4d26047ca2e79346fb85b2b93dd71 (patch)
tree006d7f42df6bed3cc2e5a5b47106b0db664b48bb /qdeduper
parentaa50f0049e6f81470fcda0935ca3da661bc7e37e (diff)
downloaddeduper-2962525cf5b4d26047ca2e79346fb85b2b93dd71.tar.xz
Prep work for sorting. Leftovers from image widgets are now all gone (finally).
Diffstat (limited to 'qdeduper')
-rw-r--r--qdeduper/imageitem.cpp24
-rw-r--r--qdeduper/imageitem.hpp11
-rw-r--r--qdeduper/mingui.cpp129
-rw-r--r--qdeduper/mingui.hpp6
-rw-r--r--qdeduper/sigdb_qt.cpp4
5 files changed, 95 insertions, 79 deletions
diff --git a/qdeduper/imageitem.cpp b/qdeduper/imageitem.cpp
index 2958e06..f53783a 100644
--- a/qdeduper/imageitem.cpp
+++ b/qdeduper/imageitem.cpp
@@ -12,7 +12,7 @@
#define DEBUGPAINT 0
-ImageItem::ImageItem(QString fn, QString dispn, QKeySequence hotkey, double pxratio)
+ImageItem::ImageItem(QString fn, QString dispn, QKeySequence hotkey, size_t dbid, size_t ord, double pxratio)
{
this->setText(dispn);
this->setData(fn, ImageItemRoles::path_role);
@@ -23,6 +23,28 @@ ImageItem::ImageItem(QString fn, QString dispn, QKeySequence hotkey, double pxra
this->setData(pm.size(), ImageItemRoles::dimension_role);
this->setData(hotkey, ImageItemRoles::hotkey_role);
this->setData(pm, Qt::ItemDataRole::DecorationRole);
+ this->setData(QVariant::fromValue<size_t>(dbid), ImageItemRoles::database_id_role);
+ this->setData(QVariant::fromValue<size_t>(ord), ImageItemRoles::default_order_role);
+}
+
+QString ImageItem::path() const
+{
+ return this->data(ImageItemRoles::path_role).toString();
+}
+
+size_t ImageItem::database_id() const
+{
+ return this->data(ImageItemRoles::database_id_role).value<size_t>();
+}
+
+size_t ImageItem::default_order() const
+{
+ return this->data(ImageItemRoles::default_order_role).value<size_t>();
+}
+
+QKeySequence ImageItem::hotkey() const
+{
+ return this->data(ImageItemRoles::hotkey_role).value<QKeySequence>();
}
void ImageItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
diff --git a/qdeduper/imageitem.hpp b/qdeduper/imageitem.hpp
index b6d775e..2d90644 100644
--- a/qdeduper/imageitem.hpp
+++ b/qdeduper/imageitem.hpp
@@ -15,9 +15,16 @@ public:
path_role = Qt::ItemDataRole::UserRole + 0x1000,
dimension_role,
file_size_role,
- hotkey_role
+ hotkey_role,
+ database_id_role,
+ default_order_role
};
- ImageItem(QString fn, QString dispn, QKeySequence hotkey, double pxratio = 1.0);
+ ImageItem(QString fn, QString dispn, QKeySequence hotkey, size_t dbid, size_t ord, double pxratio = 1.0);
+
+ QString path() const;
+ size_t database_id() const;
+ size_t default_order() const;
+ QKeySequence hotkey() const;
};
class ImageItemDelegate : public QAbstractItemDelegate
diff --git a/qdeduper/mingui.cpp b/qdeduper/mingui.cpp
index c9447c5..80a83dc 100644
--- a/qdeduper/mingui.cpp
+++ b/qdeduper/mingui.cpp
@@ -159,6 +159,7 @@ DeduperMainWindow::DeduperMainWindow()
cs = Qt::CheckState::Unchecked;
else cs = Qt::CheckState::Checked;
this->im->setData(i, cs, Qt::ItemDataRole::CheckStateRole);
+ this->marked_update();
});
QObject::connect(lv, &QListView::doubleClicked, [this](const QModelIndex &i) {
auto cs = i.data(Qt::ItemDataRole::CheckStateRole).value<Qt::CheckState>();
@@ -166,15 +167,9 @@ DeduperMainWindow::DeduperMainWindow()
cs = Qt::CheckState::Unchecked;
else cs = Qt::CheckState::Checked;
this->im->setData(i, cs, Qt::ItemDataRole::CheckStateRole);
+ this->marked_update();
QDesktopServices::openUrl(QUrl::fromLocalFile(i.data(ImageItem::ImageItemRoles::path_role).toString()));
});
- QObject::connect(im, &QStandardItemModel::itemChanged, [this](QStandardItem *i) {
- ImageItem *itm = static_cast<ImageItem*>(i);
- QModelIndex idx = itm->index();
- bool checked = itm->data(Qt::ItemDataRole::CheckStateRole) == Qt::CheckState::Checked;
- if (checked != marks[idx.row()])
- this->mark_toggle(idx.row());
- });
l->addWidget(lv);
l->addWidget(infopanel);
l->setStretchFactor(0, 3);
@@ -265,13 +260,12 @@ void DeduperMainWindow::setup_menu()
return;
}
this->vm = ViewMode::view_searchresult;
- std::vector<fs::path> ps;
+ std::vector<size_t> ps;
std::map<std::pair<size_t, size_t>, double> dm;
- for (size_t i = 0; i < sim.size(); ++i)
+ for (auto &s : sim)
{
- auto &s = sim[i];
- ps.push_back(this->sdb->get_image_path(s.first));
- dm[std::make_pair(0, i)] = s.second;
+ ps.push_back(s.first);
+ dm[std::make_pair(0, s.first)] = s.second;
}
this->show_images(ps);
this->update_distances(dm);
@@ -391,40 +385,48 @@ void DeduperMainWindow::update_actions()
}
}
-void DeduperMainWindow::show_images(const std::vector<fs::path> &fns)
+void DeduperMainWindow::show_images(const std::vector<size_t> &ids)
{
- current_set = fns;
- marks.clear();
im->clear();
+ std::vector<fs::path> fns;
+ for (auto &id : ids) fns.push_back(this->sdb->get_image_path(id));
fs::path::string_type common_pfx = common_prefix(fns);
size_t idx = 0;
- if (fns.size() > keys.size() && !nohotkeywarn)
+ if (ids.size() > keys.size() && !nohotkeywarn)
nohotkeywarn = QMessageBox::StandardButton::Ignore ==
QMessageBox::warning(this,
"Too many duplicates",
"Too many duplicates found. Some couldn't be assigned a hotkey. Ignore = do not show again.",
QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Ignore,
QMessageBox::StandardButton::Ok);
- for (auto &f : fns)
+ for (auto &id : ids)
{
- marks.push_back(marked.find(f) != marked.end());
- im->appendRow(new ImageItem(fsstr_to_qstring(f.native()), fsstr_to_qstring(f.native().substr(common_pfx.length())), keys[idx], lv->devicePixelRatioF()));
+ fs::path &f = fns[idx];
+ ImageItem *imitm = new ImageItem(fsstr_to_qstring(f.native()),
+ fsstr_to_qstring(f.native().substr(common_pfx.length())),
+ idx < keys.size() ? keys[idx] : QKeySequence(),
+ id, idx,
+ lv->devicePixelRatioF());
+ imitm->setCheckState(marked.find(f) == marked.end() ? Qt::CheckState::Unchecked : Qt::CheckState::Checked);
+ im->appendRow(imitm);
++idx;
}
- mark_view_update(false);
+ marked_update(false);
}
void DeduperMainWindow::update_distances(const std::map<std::pair<size_t, size_t>, double> &d)
{
QString r;
+ std::map<size_t, QString> idkeymap;
+ for (int i = 0; i < im->rowCount(); ++i)
+ {
+ ImageItem *itm = static_cast<ImageItem*>(im->item(i));
+ idkeymap[itm->database_id()] = itm->hotkey().isEmpty() ? "(No hotkey)" : itm->hotkey().toString();
+ }
for (auto &p : d)
{
- QString ka = "(No hotkey)";
- QString kb = "(No hotkey)";
- if (p.first.first < keys.size())
- ka = QKeySequence(keys[p.first.first]).toString();
- if (p.first.second < keys.size())
- kb = QKeySequence(keys[p.first.second]).toString();
+ QString ka = idkeymap[p.first.first];
+ QString kb = idkeymap[p.first.second];
if (vm == ViewMode::view_normal)
r += QString("%1 <-> %2: %3\n").arg(ka).arg(kb).arg(QString::number(p.second));
else
@@ -471,9 +473,12 @@ void DeduperMainWindow::load_list()
if (!s.empty()) this->marked.insert(s);
}
fst.close();
- for (size_t i = 0; i < marks.size(); ++i)
- marks[i] = marked.find(current_set[i]) != marked.end();
- mark_view_update();
+ for (int i = 0; i < im->rowCount(); ++i)
+ {
+ fs::path p = qstring_to_path(static_cast<ImageItem*>(im->item(i))->path());
+ im->item(i)->setCheckState(marked.find(p) != marked.end() ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ }
+ marked_update();
}
void DeduperMainWindow::create_new()
@@ -566,9 +571,7 @@ void DeduperMainWindow::show_group(size_t gid)
return;
this->vm = ViewMode::view_normal;
auto g = sdb->get_group(gid);
- current_set.clear();
- std::for_each(g.begin(), g.end(), [this](auto id){current_set.push_back(sdb->get_image_path(id));});
- this->show_images(current_set);
+ this->show_images(g);
this->update_distances(sdb->group_distances(gid));
this->update_viewstatus(gid, sdb->num_groups());
this->update_actions();
@@ -582,16 +585,13 @@ void DeduperMainWindow::mark_toggle(size_t x)
sb->showMessage("Marking images in search result is disabled.", 2000);
return;
}
- if (x < marks.size())
+ if (x < im->rowCount())
{
- marks[x] = !marks[x];
- if (marks[x])
- marked.insert(current_set[x]);
- else
- if (marked.find(current_set[x]) != marked.end())
- marked.erase(marked.find(current_set[x]));
+ Qt::CheckState ckst = im->item(x)->checkState() == Qt::CheckState::Checked ?
+ Qt::CheckState::Unchecked : Qt::CheckState::Checked;
+ im->item(x)->setCheckState(ckst);
}
- mark_view_update();
+ marked_update();
}
void DeduperMainWindow::mark_all_but(size_t x)
@@ -602,19 +602,15 @@ void DeduperMainWindow::mark_all_but(size_t x)
sb->showMessage("Marking images in search result is disabled.", 2000);
return;
}
- if (x < marks.size())
+ if (x < im->rowCount())
{
- for (size_t i = 0; i < marks.size(); ++i)
+ for (int i = 0; i < im->rowCount(); ++i)
{
- marks[i] = (i != x);
- if (marks[i])
- marked.insert(current_set[i]);
- else
- if (marked.find(current_set[i]) != marked.end())
- marked.erase(marked.find(current_set[i]));
+ Qt::CheckState ckst = (i == x) ? Qt::CheckState::Unchecked : Qt::CheckState::Checked;
+ im->item(x)->setCheckState(ckst);
}
}
- mark_view_update();
+ marked_update();
}
void DeduperMainWindow::mark_all()
@@ -625,42 +621,35 @@ void DeduperMainWindow::mark_all()
sb->showMessage("Marking images in search result is disabled.", 2000);
return;
}
- for (size_t i = 0; i < marks.size(); ++i)
- {
- marks[i] = true;
- marked.insert(current_set[i]);
- }
- mark_view_update();
+ for (int i = 0; i < im->rowCount(); ++i)
+ im->item(i)->setCheckState(Qt::CheckState::Checked);
+ marked_update();
}
void DeduperMainWindow::mark_none(bool msg)
{
- for (size_t i = 0; i < marks.size(); ++i)
- {
- marks[i] = false;
- if (marked.find(current_set[i]) != marked.end())
- marked.erase(marked.find(current_set[i]));
- }
- mark_view_update(msg);
+ for (int i = 0; i < im->rowCount(); ++i)
+ im->item(i)->setCheckState(Qt::CheckState::Unchecked);
+ marked_update(msg);
}
-void DeduperMainWindow::mark_view_update(bool update_msg)
+void DeduperMainWindow::marked_update(bool update_msg)
{
size_t m = 0;
- for (size_t i = 0; i < current_set.size(); ++i)
+ for (int i = 0; i < im->rowCount(); ++i)
{
- if (marks[i])
+ fs::path p = qstring_to_path(static_cast<ImageItem*>(im->item(i))->path());
+ if (im->item(i)->checkState() == Qt::CheckState::Checked)
{
- im->item(i)->setCheckState(Qt::CheckState::Checked);
+ marked.insert(p);
++m;
}
else
- {
- im->item(i)->setCheckState(Qt::CheckState::Unchecked);
- }
+ if (marked.find(p) != marked.end())
+ marked.erase(marked.find(p));
}
if (update_msg)
- sb->showMessage(QString("%1 of %2 marked for deletion").arg(m).arg(current_set.size()), 1000);
+ sb->showMessage(QString("%1 of %2 marked for deletion").arg(m).arg(im->rowCount()), 1000);
}
fs::path::string_type DeduperMainWindow::common_prefix(const std::vector<fs::path> &fns)
diff --git a/qdeduper/mingui.hpp b/qdeduper/mingui.hpp
index 9f3ff2a..8812f32 100644
--- a/qdeduper/mingui.hpp
+++ b/qdeduper/mingui.hpp
@@ -59,11 +59,9 @@ private:
void mark_all_but(size_t x);
void mark_all();
void mark_none(bool msg = true);
- void mark_view_update(bool update_msg = true);
+ void marked_update(bool update_msg = true);
fs::path::string_type common_prefix(const std::vector<fs::path> &fns);
- std::vector<bool> marks;
std::unordered_set<fs::path> marked;
- std::vector<fs::path> current_set;
protected:
void closeEvent(QCloseEvent *e) override;
bool eventFilter(QObject *obj, QEvent *ev) override;
@@ -71,7 +69,7 @@ public:
DeduperMainWindow();
void setup_menu();
- void show_images(const std::vector<fs::path> &fns);
+ void show_images(const std::vector<size_t> &ids);
void update_distances(const std::map<std::pair<size_t, size_t>, double> &d);
void update_viewstatus(size_t cur, size_t size);
void save_list();
diff --git a/qdeduper/sigdb_qt.cpp b/qdeduper/sigdb_qt.cpp
index 45fc55a..4bcc7af 100644
--- a/qdeduper/sigdb_qt.cpp
+++ b/qdeduper/sigdb_qt.cpp
@@ -138,9 +138,9 @@ std::map<std::pair<size_t, size_t>, double> SignatureDB::group_distances(size_t
{
size_t x = g[i], y = g[j];
if (distmap.find(std::make_pair(x, y)) != distmap.end())
- ret[std::make_pair(i, j)] = distmap[std::make_pair(x, y)];
+ ret[std::make_pair(x, y)] = distmap[std::make_pair(x, y)];
else if (distmap.find(std::make_pair(y, x)) != distmap.end())
- ret[std::make_pair(i, j)] = distmap[std::make_pair(y, x)];
+ ret[std::make_pair(x, y)] = distmap[std::make_pair(y, x)];
}
return ret;
}