aboutsummaryrefslogblamecommitdiff
path: root/mingui/main.cpp
blob: 8199cb97d26407897b858b5dc490add2c1d1639b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

                    
                     










                        
                               
 

                                           



























                                                 
                                     


                                     

                                                             

                                     

                                                             
                                        
                                                       



              
                                                              
 
                              


























                                                                                     
                                              
 



                                   































                                                                                                 
                                                





                                                                            
                                                                       





                                                                            










                                                                                





             
#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;
}