From 4b8d314f575d9e893d8dda7431194f8b470fc888 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sun, 18 Sep 2022 11:08:01 -0400 Subject: First step to adopt mingui as part of the project -- break it! --- mingui/CMakeLists.txt | 25 ---- mingui/README.md | 7 - mingui/imageitem.cpp | 136 ------------------- mingui/imageitem.hpp | 42 ------ mingui/main.cpp | 161 ---------------------- mingui/mingui.cpp | 369 -------------------------------------------------- mingui/mingui.hpp | 63 --------- 7 files changed, 803 deletions(-) delete mode 100644 mingui/CMakeLists.txt delete mode 100644 mingui/README.md delete mode 100644 mingui/imageitem.cpp delete mode 100644 mingui/imageitem.hpp delete mode 100644 mingui/main.cpp delete mode 100644 mingui/mingui.cpp delete mode 100644 mingui/mingui.hpp (limited to 'mingui') 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/README.md b/mingui/README.md deleted file mode 100644 index dff674f..0000000 --- a/mingui/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Minimal GUI for Deduper - -Very minimalistic, but working, prototype GUI for deduper. - -For testing purposes only. Not part of the main deduper project (yet). - -Beware extremely ugly code. diff --git a/mingui/imageitem.cpp b/mingui/imageitem.cpp deleted file mode 100644 index 6fee930..0000000 --- a/mingui/imageitem.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "imageitem.hpp" - -#include - -#include -#include -#include -#include -#include -#include -#include - -ImageItem::ImageItem(QString fn, QString dispn, QKeySequence hotkey, double pxratio) -{ - this->setText(dispn); - this->setData(fn, ImageItemRoles::path_role); - this->setData(QFileInfo(fn).size(), ImageItemRoles::file_size_role); - this->setCheckable(true); - QPixmap pm(fn); - pm.setDevicePixelRatio(pxratio); - this->setData(pm.size(), ImageItemRoles::dimension_role); - this->setData(hotkey, ImageItemRoles::hotkey_role); - this->setData(pm, Qt::ItemDataRole::DecorationRole); -} - -void ImageItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QRect imr = option.rect; - imr.adjust(MARGIN + BORDER, MARGIN + BORDER, -MARGIN - BORDER, -MARGIN - BORDER); - QFont bfnt(option.font); - bfnt.setBold(true); - QFontMetrics bfm(bfnt); - imr.adjust(0, 0, 0, -2 * HKPADD - bfm.height() - LINESP); - - QRect selr = option.rect.adjusted(MARGIN, MARGIN, -MARGIN, -MARGIN); - QStyleOptionViewItem so(option); - so.rect = selr; - if (index.data(Qt::ItemDataRole::CheckStateRole).value() == Qt::CheckState::Checked) - so.state |= QStyle::StateFlag::State_Selected; - so.state |= QStyle::StateFlag::State_Active; - option.widget->style()->drawPrimitive(QStyle::PrimitiveElement::PE_PanelItemViewItem, &so, painter, option.widget); - - - QPixmap pm = index.data(Qt::ItemDataRole::DecorationRole).value(); - QSize imd = pm.size().scaled(imr.size(), Qt::AspectRatioMode::KeepAspectRatio); - painter->setRenderHint(QPainter::RenderHint::SmoothPixmapTransform); - painter->drawPixmap(QRect(imr.topLeft(), imd), pm); - QPoint dtopright = QRect(imr.topLeft(),imd).bottomLeft(); - - QPoint hko = dtopright + QPoint(HKPADD, HKPADD + LINESP); - QKeySequence ks = index.data(ImageItem::ImageItemRoles::hotkey_role).value(); - QString kss = ks.toString(); - QRect r = bfm.boundingRect(kss); - r.moveTopLeft(hko); - QRect hkbg = r.adjusted(-HKPADD, -HKPADD, HKPADD, HKPADD); - if (hkbg.width() < hkbg.height()) - { - int shift = (hkbg.height() - hkbg.width()) / 2; - r.adjust(shift, 0, shift, 0); - hkbg.setWidth(hkbg.height()); - } - painter->setPen(QPen(QBrush(), 0)); - painter->setBrush(option.widget->palette().color(QPalette::ColorGroup::Normal, QPalette::ColorRole::Light)); - painter->drawRoundedRect(hkbg.adjusted(HKSHDS, HKSHDS, HKSHDS, HKSHDS), 4, 4); - painter->setBrush(option.widget->palette().color(QPalette::ColorGroup::Normal, QPalette::ColorRole::WindowText)); - painter->drawRoundedRect(hkbg, 4, 4); - painter->setPen(option.widget->palette().color(QPalette::ColorGroup::Normal, QPalette::ColorRole::Window)); - painter->setBrush(QBrush()); - painter->setFont(bfnt); - painter->drawText(r, kss); - - QPoint ftopright = hkbg.topRight() + QPoint(LINESP + HKSHDS, 0); - QSize dim = index.data(ImageItem::ImageItemRoles::dimension_role).value(); - qint64 fsz = index.data(ImageItem::ImageItemRoles::file_size_role).value(); - QString infos = QString("%1 x %2, %3") - .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); - painter->setPen(option.widget->palette().color(QPalette::ColorGroup::Normal, QPalette::ColorRole::Text)); - painter->drawText(r, infos, topt); - topt.setAlignment(Qt::AlignmentFlag::AlignRight); - r.setLeft(r.right()); - r.setRight(imr.right()); - QString efns = option.fontMetrics.elidedText(fns, Qt::TextElideMode::ElideMiddle, r.width()); - painter->drawText(r, efns, topt); -} - -QSize ImageItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - const QListView *lw = qobject_cast(option.widget); - QSize vpsz = lw->maximumViewportSize(); - vpsz.setWidth(vpsz.width() - vw); - vpsz.setHeight(vpsz.height() - hh); - QPixmap pm = index.data(Qt::ItemDataRole::DecorationRole).value(); - QSize onscsz = pm.size() / pm.devicePixelRatioF(); - int imh = onscsz.height(); - if (onscsz.width() > vpsz.width() - 2 * MARGIN - 2 * BORDER) - imh = (vpsz.width() - 2 * MARGIN - 2 * BORDER) / (double)onscsz.width() * onscsz.height(); - - QFont fnt(option.font); - fnt.setBold(true); - QFontMetrics fm(fnt); - int extra_height = 2 * MARGIN + 2 * BORDER + LINESP + fm.height() + 2 * HKPADD + HKSHDS; - int min_height = 64; - int max_height = imh; - - QSize dim = index.data(ImageItem::ImageItemRoles::dimension_role).value(); - qint64 fsz = index.data(ImageItem::ImageItemRoles::file_size_role).value(); - QString infos = QString("%1 x %2, %3") - .arg(dim.width()).arg(dim.height()) - .arg(QLocale::system().formattedDataSize(fsz, 3)); - int textw = option.fontMetrics.boundingRect(infos).width() + fm.height() + 2 * HKPADD + 48; - - QSize ret(vpsz); - if (textw > vpsz.width()) ret.setWidth(textw); - ret.setHeight(vpsz.height() / index.model()->rowCount() - lw->spacing()); - ret.setHeight(std::max(min_height + extra_height, ret.height())); - ret.setHeight(std::min(max_height + extra_height, ret.height())); - return ret; -} - -void ImageItemDelegate::resize(const QModelIndex &index) -{ - Q_EMIT sizeHintChanged(index); -} - -void ImageItemDelegate::setScrollbarMargins(int vw, int hh) -{ - this->vw = vw; - this->hh = hh; -} diff --git a/mingui/imageitem.hpp b/mingui/imageitem.hpp deleted file mode 100644 index 43fb0c8..0000000 --- a/mingui/imageitem.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef IMAGEITEM_HPP -#define IMAGEITEM_HPP - -#include -#include -#include -#include - -class ImageItem : public QStandardItem -{ -public: - enum ImageItemRoles - { - path_role = Qt::ItemDataRole::UserRole + 0x1000, - dimension_role, - file_size_role, - hotkey_role - }; - ImageItem(QString fn, QString dispn, QKeySequence hotkey, double pxratio = 1.0); -}; - -class ImageItemDelegate : public QAbstractItemDelegate -{ - Q_OBJECT -private: - const static int MARGIN = 3; - const static int BORDER = 3; - const static int HKPADD = 4; - const static int LINESP = 4; - const static int HKSHDS = 2; - int vw = -1; - int hh = -1; -public: - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; - void resize(const QModelIndex &index); - void setScrollbarMargins(int vw, int hh); -Q_SIGNALS: - void sizeHintChanged(const QModelIndex &index); -}; - -#endif 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "mingui.hpp" - -using std::size_t; -namespace fs = std::filesystem; - -std::unordered_map fnmap; -std::vector fns; -std::map, double> dist; -std::vector par; -std::vector> 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 build_list(const std::vector &l) -{ - std::vector ret; - for (auto &x : l) - ret.push_back(fns[x]); - return ret; -} - -std::map, double> build_dists(const std::vector &l) -{ - std::map, 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/mingui/mingui.cpp b/mingui/mingui.cpp deleted file mode 100644 index 494745a..0000000 --- a/mingui/mingui.cpp +++ /dev/null @@ -1,369 +0,0 @@ -#include "mingui.hpp" -#include "imageitem.hpp" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using std::size_t; -const std::vector keys = { - Qt::Key::Key_A, Qt::Key::Key_S, Qt::Key::Key_D, Qt::Key::Key_F, - Qt::Key::Key_G, Qt::Key::Key_H, Qt::Key::Key_J, Qt::Key::Key_K, - Qt::Key::Key_L, Qt::Key::Key_Semicolon, Qt::Key::Key_T, Qt::Key::Key_Y, - Qt::Key::Key_U, Qt::Key::Key_I, Qt::Key::Key_O, Qt::Key::Key_P -}; - -QString fsstr_to_qstring(const fs::path::string_type &s) -{ -#ifdef _WIN32 //the degenerate platform - return QString::fromStdWString(s); -#else - return QString::fromStdString(s); -#endif -} - -MinGuiWidget::MinGuiWidget() -{ - this->setFont(QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont)); - this->setWindowTitle("deduper minigui"); - this->setLayout(new QVBoxLayout(this)); - sb = this->statusBar(); - sb->addPermanentWidget(permamsg = new QLabel()); - QLabel *opm = new QLabel(); - opm->setText("placeholder status bar text"); - sb->addWidget(opm); - l = new QSplitter(Qt::Orientation::Horizontal, this); - l->setContentsMargins(6, 6, 6, 6); - l->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - this->setCentralWidget(l); - infopanel = new QTextEdit(this); - infopanel->setReadOnly(true); - infopanel->setMinimumWidth(80); - lw = new QListView(this); - im = new QStandardItemModel(this); - lw->setModel(im); - lw->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); - lw->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); - id = new ImageItemDelegate(); - id->setScrollbarMargins(lw->verticalScrollBar()->width(), - lw->horizontalScrollBar()->height()); - lw->setItemDelegate(id); - lw->setSelectionMode(QAbstractItemView::SelectionMode::NoSelection); - lw->setResizeMode(QListView::ResizeMode::Adjust); - lw->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - lw->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - lw->setHorizontalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel); - lw->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel); - lw->setMinimumWidth(240); - - for (size_t i = 0; i < keys.size(); ++i) - { - auto &k = keys[i]; - QAction *a = new QAction(); - a->setShortcut(QKeySequence(k)); - QObject::connect(a, &QAction::triggered, [this, i](){this->mark_toggle(i);}); - selhk.push_back(a); - QAction *sa = new QAction(); - sa->setShortcut(QKeySequence(Qt::Modifier::SHIFT | k)); - QObject::connect(sa, &QAction::triggered, [this, i](){this->mark_all_but(i);}); - selhk.push_back(a); - } - this->addActions(selhk); - QAction *mall = new QAction(); - mall->setShortcut(QKeySequence(Qt::Key::Key_X)); - QObject::connect(mall, &QAction::triggered, [this]{this->mark_all();}); - this->addAction(mall); - QAction *mnone = new QAction(); - mnone->setShortcut(QKeySequence(Qt::Key::Key_C)); - QObject::connect(mnone, &QAction::triggered, [this]{this->mark_none();}); - this->addAction(mnone); - QAction *nxt = new QAction(); - nxt->setShortcut(QKeySequence(Qt::Key::Key_M)); - QObject::connect(nxt, &QAction::triggered, [this]{Q_EMIT this->next();}); - this->addAction(nxt); - QAction *prv = new QAction(); - prv->setShortcut(QKeySequence(Qt::Key::Key_Z)); - QObject::connect(prv, &QAction::triggered, [this]{Q_EMIT this->prev();}); - this->addAction(prv); - QAction *load = new QAction(); - load->setShortcut(QKeySequence(Qt::Key::Key_N)); - QObject::connect(load, &QAction::triggered, [this]{Q_EMIT this->load_list();}); - this->addAction(load); - QAction *skip = new QAction(); - skip->setShortcut(QKeySequence(Qt::Key::Key_B)); - QObject::connect(skip, &QAction::triggered, [this]{ - bool ok = false; - int g = QInputDialog::getInt(this, "Skip to group", - QString("Group # (1-%1)").arg(ngroups), - curgroup + 1, - 1, ngroups, 1, &ok); - if (ok) Q_EMIT switch_group((size_t) g - 1); - }); - this->addAction(skip); - QAction *save = new QAction(); - save->setShortcut(QKeySequence(Qt::Modifier::SHIFT | Qt::Key::Key_Return)); - QObject::connect(save, &QAction::triggered, [this]{Q_EMIT this->save_list();}); - this->addAction(save); - - QObject::connect(lw, &QListView::clicked, [this](const QModelIndex &i) { - auto cs = i.data(Qt::ItemDataRole::CheckStateRole).value(); - if (cs == Qt::CheckState::Checked) - cs = Qt::CheckState::Unchecked; - else cs = Qt::CheckState::Checked; - this->im->setData(i, cs, Qt::ItemDataRole::CheckStateRole); - }); - QObject::connect(lw, &QListView::doubleClicked, [this](const QModelIndex &i) { - auto cs = i.data(Qt::ItemDataRole::CheckStateRole).value(); - if (cs == Qt::CheckState::Checked) - cs = Qt::CheckState::Unchecked; - else cs = Qt::CheckState::Checked; - this->im->setData(i, cs, Qt::ItemDataRole::CheckStateRole); - QDesktopServices::openUrl(QUrl::fromLocalFile(i.data(ImageItem::ImageItemRoles::path_role).toString())); - }); - QObject::connect(im, &QStandardItemModel::itemChanged, [this](QStandardItem *i) { - ImageItem *itm = static_cast(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(lw); - l->addWidget(infopanel); - l->setStretchFactor(0, 3); - l->setStretchFactor(1, 1); - l->setCollapsible(0, false); - marked.clear(); - infopanel->setText("bleh"); - infopanel->setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum); - nohotkeywarn = false; -} - -void MinGuiWidget::show_images(const std::vector &fns) -{ - current_set = fns; - marks.clear(); - im->clear(); - int max_height = (this->screen()->size().height() / fns.size() * 0.8 - 24) * this->screen()->devicePixelRatio(); - int max_width = this->screen()->size().width() * 0.8 * this->screen()->devicePixelRatio(); - if (max_height < 64) max_height = 64; - if (max_width < 64) max_width = 64; - fs::path::string_type common_pfx = common_prefix(fns); - size_t idx = 0; - if (fns.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) - { - 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], lw->devicePixelRatioF())); - ++idx; - } - mark_view_update(false); -} - -void MinGuiWidget::update_distances(const std::map, double> &d) -{ - QString r; - 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(); - r += QString("%1 <-> %2: %3\n").arg(ka).arg(kb).arg(QString::number(p.second)); - } - infopanel->setText(r); -} - -void MinGuiWidget::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() -{ - QString fn = QFileDialog::getSaveFileName(this, "Save list", QString(), "*.txt"); - FILE *f = fopen(fn.toStdString().c_str(), "w"); - if (!f) return; - for (auto &x : this->marked) -#ifdef _WIN32 - fwprintf(f, L"%ls\n", x.c_str()); -#else - fprintf(f, "%s\n", x.c_str()); -#endif - fclose(f); -} - -void MinGuiWidget::load_list() -{ - QString fn = QFileDialog::getOpenFileName(this, "Load list", QString(), "*.txt"); - FILE *f = fopen(fn.toStdString().c_str(), "r"); - if (!f) return; - this->marked.clear(); - while(!feof(f)) - { -#ifdef _WIN32 - wchar_t buf[32768]; - fgetws(buf, 32768, f); - std::wstring ws(buf); - if (ws.back() == L'\n') ws.pop_back(); - if (!ws.empty()) this->marked.insert(ws); -#else - char buf[32768]; - fgets(buf, 32768, f); - std::string s(buf); - if (s.back() == '\n') s.pop_back(); - if (!s.empty()) this->marked.insert(s); -#endif - } - fclose(f); - for (size_t i = 0; i < marks.size(); ++i) - marks[i] = marked.find(current_set[i]) != marked.end(); - mark_view_update(); -} - -void MinGuiWidget::mark_toggle(size_t x) -{ - if (x < marks.size()) - { - 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])); - } - mark_view_update(); -} - -void MinGuiWidget::mark_all_but(size_t x) -{ - if (x < marks.size()) - { - for (size_t i = 0; i < marks.size(); ++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])); - } - } - mark_view_update(); -} - -void MinGuiWidget::mark_all() -{ - for (size_t i = 0; i < marks.size(); ++i) - { - marks[i] = true; - marked.insert(current_set[i]); - } - mark_view_update(); -} - -void MinGuiWidget::mark_none() -{ - 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(); -} - -void MinGuiWidget::mark_view_update(bool update_msg) -{ - size_t m = 0; - for (size_t i = 0; i < current_set.size(); ++i) - { - if (marks[i]) - { - im->item(i)->setCheckState(Qt::CheckState::Checked); - ++m; - } - else - { - im->item(i)->setCheckState(Qt::CheckState::Unchecked); - } - } - if (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 &fns) -{ - using fsstr = fs::path::string_type; - fsstr ret; - fsstr shortest = *std::min_element(fns.begin(), fns.end(), [](auto &a, auto &b){return a.native().length() < b.native().length();}); - for (size_t i = 0; i < shortest.length(); ++i) - { - fs::path::value_type c = shortest[i]; - bool t = true; - for (auto &s : fns) if (s.c_str()[i] != c) {t = false; break;} - if (!t) break; - ret.push_back(c); - } - if (!ret.empty()) - { - auto p = ret.rfind(std::filesystem::path::preferred_separator); - if (p != fsstr::npos) - return fs::path(ret.substr(0, p + 1)); - } - return ret; -} - -void MinGuiWidget::resizeEvent(QResizeEvent *e) -{ - QWidget::resizeEvent(e); - if (!id || !im) return; - for (int i = 0; i < im->rowCount(); ++i) - id->resize(im->indexFromItem(im->item(i))); -} - -void MinGuiWidget::closeEvent(QCloseEvent *e) -{ - if (QMessageBox::StandardButton::Yes == - QMessageBox::question(this, "Confirmation", "Really quit?", - QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, - QMessageBox::StandardButton::No)) - e->accept(); - else - e->ignore(); -} diff --git a/mingui/mingui.hpp b/mingui/mingui.hpp deleted file mode 100644 index f80561b..0000000 --- a/mingui/mingui.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef MINGUI_HPP -#define MINGUI_HPP - -#include -#include -#include -#include - -#include -#include - -class QHBoxLayout; -class QLabel; -class QStatusBar; -class QScrollArea; -class QTextEdit; -class QListView; -class QSplitter; -class QStandardItemModel; -class ImageItemDelegate; - -namespace fs = std::filesystem; - -class MinGuiWidget : public QMainWindow -{ - Q_OBJECT -private: - QSplitter *l; - QTextEdit *infopanel; - QLabel *permamsg; - QStatusBar *sb; - QListView *lw; - QList selhk; - QStandardItemModel *im = nullptr; - ImageItemDelegate *id = nullptr; - std::size_t ngroups, curgroup; - bool nohotkeywarn; - void mark_toggle(std::size_t x); - void mark_all_but(std::size_t x); - void mark_all(); - void mark_none(); - void mark_view_update(bool update_msg = true); - fs::path::string_type common_prefix(const std::vector &fns); - std::vector marks; - std::unordered_set marked; - std::vector current_set; -protected: - void resizeEvent(QResizeEvent *e) override; - void closeEvent(QCloseEvent *e) override; -public: - MinGuiWidget(); - void show_images(const std::vector &fns); - void update_distances(const std::map, double> &d); - void update_viewstatus(std::size_t cur, std::size_t size); - void save_list(); - void load_list(); -Q_SIGNALS: - void next(); - void prev(); - void switch_group(std::size_t group); -}; - -#endif -- cgit v1.2.3