From 109a9c0130a024030a651aec7979fed283ec5bb7 Mon Sep 17 00:00:00 2001
From: Chris Xiong <chirs241097@gmail.com>
Date: Sun, 25 Sep 2022 23:41:43 -0400
Subject: Implement review marked images.

---
 qdeduper/imageitem.cpp | 21 +++++++++++++++----
 qdeduper/imageitem.hpp |  3 +++
 qdeduper/mingui.cpp    | 55 ++++++++++++++++++++++++++++++++++++++++----------
 qdeduper/mingui.hpp    |  4 +++-
 4 files changed, 67 insertions(+), 16 deletions(-)

(limited to 'qdeduper')

diff --git a/qdeduper/imageitem.cpp b/qdeduper/imageitem.cpp
index cb1c76e..7be667c 100644
--- a/qdeduper/imageitem.cpp
+++ b/qdeduper/imageitem.cpp
@@ -61,6 +61,9 @@ void ImageItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
     bfnt.setBold(true);
     QFontMetrics bfm(bfnt);
     imr.adjust(0, 0, 0, -2 * HKPADD - bfm.height() - LINESP);
+    QTextOption topt;
+    topt.setWrapMode(QTextOption::WrapMode::NoWrap);
+    topt.setAlignment(Qt::AlignmentFlag::AlignHCenter);
 
     QRect selr = option.rect.adjusted(MARGIN, MARGIN, -MARGIN, -MARGIN);
     QStyleOptionViewItem so(option);
@@ -78,7 +81,9 @@ void ImageItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
 
     QPoint hko = dtopright + QPoint(HKPADD, HKPADD + LINESP);
     QKeySequence ks = index.data(ImageItem::ImageItemRoles::hotkey_role).value<QKeySequence>();
-    QString kss = ks.toString();
+    QString kss = ks.isEmpty() ? "(-)" : ks.toString();
+    if (!show_hotkey)
+        kss = QString::number(index.row() + 1);
     QRect r = bfm.boundingRect(kss);
     r.moveTopLeft(hko);
     QRect hkbg = r.adjusted(-HKPADD, -HKPADD, HKPADD, HKPADD);
@@ -96,7 +101,12 @@ void ImageItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
     painter->setPen(option.widget->palette().color(QPalette::ColorGroup::Normal, QPalette::ColorRole::Window));
     painter->setBrush(QBrush());
     painter->setFont(bfnt);
-    painter->drawText(r, kss);
+    painter->drawText(r, kss, topt);
+#if DEBUGPAINT
+    painter->setPen(QPen(Qt::GlobalColor::red));
+    painter->drawRect(r);
+    painter->drawRect(hkbg);
+#endif
 
     QPoint ftopright = hkbg.topRight() + QPoint(LINESP + HKSHDS, 0);
     QSize dim = index.data(ImageItem::ImageItemRoles::dimension_role).value<QSize>();
@@ -105,8 +115,6 @@ void ImageItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
                     .arg(dim.width()).arg(dim.height())
                     .arg(QLocale::system().formattedDataSize(fsz, 3));
     QString fns = index.data(Qt::ItemDataRole::DisplayRole).toString();
-    QTextOption topt;
-    topt.setWrapMode(QTextOption::WrapMode::NoWrap);
     r = option.fontMetrics.boundingRect(infos);
     r.moveTopLeft(ftopright + QPoint(0, (hkbg.height() - r.height()) / 2));
     painter->setFont(option.font);
@@ -188,6 +196,11 @@ bool ImageItemDelegate::is_single_item_mode()
     return singlemode;
 }
 
+void ImageItemDelegate::set_show_hotkey(bool show)
+{
+    show_hotkey = show;
+}
+
 void ImageItemDelegate::set_model(QAbstractItemModel *m)
 {
     im = m;
diff --git a/qdeduper/imageitem.hpp b/qdeduper/imageitem.hpp
index 5b1a1f3..abef719 100644
--- a/qdeduper/imageitem.hpp
+++ b/qdeduper/imageitem.hpp
@@ -41,6 +41,7 @@ private:
     int vw = -1;
     int hh = -1;
     bool singlemode = false;
+    bool show_hotkey = true;
     QAbstractItemModel *im = nullptr;
 public:
     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
@@ -51,6 +52,8 @@ public:
     void set_single_item_mode(bool enabled);
     bool is_single_item_mode();
 
+    void set_show_hotkey(bool show);
+
     void set_model(QAbstractItemModel *m);
 Q_SIGNALS:
     void sizeHintChanged(const QModelIndex &index);
diff --git a/qdeduper/mingui.cpp b/qdeduper/mingui.cpp
index b245be4..f17374e 100644
--- a/qdeduper/mingui.cpp
+++ b/qdeduper/mingui.cpp
@@ -337,10 +337,17 @@ void DeduperMainWindow::setup_menu()
         ImageItem::ImageItemRoles sr = skeyr[i];
         QObject::connect(a, &QAction::triggered, [this, sr] {
             this->sort_role = sr;
-            if (this->vm == ViewMode::view_normal)
-                this->show_group(this->curgroup);
-            else
-                this->search_image(this->searched_image);
+            switch (this->vm)
+            {
+                case ViewMode::view_normal:
+                    this->show_group(this->curgroup);
+                    break;
+                case ViewMode::view_searchresult:
+                    this->search_image(this->searched_image);
+                    break;
+                case ViewMode::view_marked:
+                    this->show_marked();
+            }
         });
     }
     snon->setChecked(true);
@@ -362,10 +369,17 @@ void DeduperMainWindow::setup_menu()
         Qt::SortOrder so = sordv[i];
         QObject::connect(a, &QAction::triggered, [this, so] {
             this->sort_order = so;
-            if (this->vm == ViewMode::view_normal)
-                this->show_group(this->curgroup);
-            else
-                this->search_image(this->searched_image);
+            switch (this->vm)
+            {
+                case ViewMode::view_normal:
+                    this->show_group(this->curgroup);
+                    break;
+                case ViewMode::view_searchresult:
+                    this->search_image(this->searched_image);
+                    break;
+                case ViewMode::view_marked:
+                    this->show_marked();
+            }
         });
     }
     sasc->setChecked(true);
@@ -422,7 +436,9 @@ void DeduperMainWindow::setup_menu()
     });
     menuact["mark_all_dir_rec"] = madirr;
     mark->addSeparator();
-    mark->addAction("Review Marked Images");
+    QAction *view_marked = mark->addAction("Review Marked Images");
+    QObject::connect(view_marked, &QAction::triggered, this, &DeduperMainWindow::show_marked);
+    menuact["view_marked"] = view_marked;
 
     help->addAction("Help");
     help->addSeparator();
@@ -462,7 +478,7 @@ void DeduperMainWindow::update_actions()
     menuact["save_db"]->setEnabled(true);
     menuact["load_list"]->setEnabled(true);
     menuact["save_list"]->setEnabled(true);
-    if (vm == ViewMode::view_searchresult)
+    if (vm != ViewMode::view_normal)
     {
         menuact["next_group"]->setEnabled(true);
         menuact["prev_group"]->setEnabled(true);
@@ -485,6 +501,7 @@ void DeduperMainWindow::search_image(const fs::path &path)
         ps.push_back(s.first);
         dm[std::make_pair(0, s.first)] = s.second;
     }
+    this->id->set_show_hotkey(false);
     this->show_images(ps);
     this->sort_reassign_hotkeys();
     this->update_distances(dm);
@@ -499,7 +516,7 @@ void DeduperMainWindow::show_images(const std::vector<size_t> &ids)
     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 (ids.size() > keys.size() && !nohotkeywarn)
+    if (ids.size() > keys.size() && !nohotkeywarn && this->vm != ViewMode::view_marked)
         nohotkeywarn = QMessageBox::StandardButton::Ignore ==
                        QMessageBox::warning(this,
                              "Too many duplicates",
@@ -677,6 +694,7 @@ void DeduperMainWindow::show_group(size_t gid)
     if (!sdb || gid >= sdb->num_groups())
         return;
     this->vm = ViewMode::view_normal;
+    this->id->set_show_hotkey(true);
     auto g = sdb->get_group(gid);
     this->show_images(g);
     this->sort_reassign_hotkeys();
@@ -685,6 +703,21 @@ void DeduperMainWindow::show_group(size_t gid)
     this->update_actions();
 }
 
+void DeduperMainWindow::show_marked()
+{
+    this->id->set_show_hotkey(false);
+    this->vm = ViewMode::view_marked;
+    std::vector<size_t> g;
+    for (auto &m : marked)
+        g.push_back(this->sdb->get_path_id(m));
+    this->show_images(g);
+    this->sort_reassign_hotkeys();
+    this->update_distances({});
+    this->update_actions();
+    this->sb->showMessage("Use next group / previous group to go back.");
+    this->permamsg->setText("Viewing marked images");
+}
+
 void DeduperMainWindow::sort_reassign_hotkeys()
 {
     im->setSortRole(this->sort_role);
diff --git a/qdeduper/mingui.hpp b/qdeduper/mingui.hpp
index 29332d7..abc514d 100644
--- a/qdeduper/mingui.hpp
+++ b/qdeduper/mingui.hpp
@@ -31,7 +31,8 @@ namespace fs = std::filesystem;
 enum ViewMode
 {
     view_normal,
-    view_searchresult
+    view_searchresult,
+    view_marked
 };
 
 class DeduperMainWindow : public QMainWindow
@@ -85,6 +86,7 @@ public Q_SLOTS:
     void create_new();
     void update_actions();
     void show_group(size_t gid);
+    void show_marked();
 Q_SIGNALS:
     void next();
     void prev();
-- 
cgit v1.2.3