git repos / SagoImageBrowser

blame: src/pathcompletermodel.cpp

normal view · raw

14cf904f Poul Sander 2026-06-22 18:18 1
/*
14cf904f Poul Sander 2026-06-22 18:18 2
MIT License
14cf904f Poul Sander 2026-06-22 18:18 3
14cf904f Poul Sander 2026-06-22 18:18 4
Copyright (c) 2026 Poul Sander
14cf904f Poul Sander 2026-06-22 18:18 5
14cf904f Poul Sander 2026-06-22 18:18 6
Permission is hereby granted, free of charge, to any person obtaining a copy
14cf904f Poul Sander 2026-06-22 18:18 7
of this software and associated documentation files (the "Software"), to deal
14cf904f Poul Sander 2026-06-22 18:18 8
in the Software without restriction, including without limitation the rights
14cf904f Poul Sander 2026-06-22 18:18 9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14cf904f Poul Sander 2026-06-22 18:18 10
copies of the Software, and to permit persons to whom the Software is
14cf904f Poul Sander 2026-06-22 18:18 11
furnished to do so, subject to the following conditions:
14cf904f Poul Sander 2026-06-22 18:18 12
14cf904f Poul Sander 2026-06-22 18:18 13
The above copyright notice and this permission notice shall be included in all
14cf904f Poul Sander 2026-06-22 18:18 14
copies or substantial portions of the Software.
14cf904f Poul Sander 2026-06-22 18:18 15
14cf904f Poul Sander 2026-06-22 18:18 16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14cf904f Poul Sander 2026-06-22 18:18 17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14cf904f Poul Sander 2026-06-22 18:18 18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14cf904f Poul Sander 2026-06-22 18:18 19
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14cf904f Poul Sander 2026-06-22 18:18 20
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14cf904f Poul Sander 2026-06-22 18:18 21
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
14cf904f Poul Sander 2026-06-22 18:18 22
SOFTWARE.
14cf904f Poul Sander 2026-06-22 18:18 23
14cf904f Poul Sander 2026-06-22 18:18 24
*/
14cf904f Poul Sander 2026-06-22 18:18 25
fd7f51cd Poul Sander 2026-05-22 15:30 26
#include "pathcompletermodel.h"
fd7f51cd Poul Sander 2026-05-22 15:30 27
fd7f51cd Poul Sander 2026-05-22 15:30 28
#include <QFileInfo>
fd7f51cd Poul Sander 2026-05-22 15:30 29
fd7f51cd Poul Sander 2026-05-22 15:30 30
#include <algorithm>
fd7f51cd Poul Sander 2026-05-22 15:30 31
#include <filesystem>
fd7f51cd Poul Sander 2026-05-22 15:30 32
#include <vector>
fd7f51cd Poul Sander 2026-05-22 15:30 33
fd7f51cd Poul Sander 2026-05-22 15:30 34
namespace fs = std::filesystem;
fd7f51cd Poul Sander 2026-05-22 15:30 35
fd7f51cd Poul Sander 2026-05-22 15:30 36
PathCompleterModel::PathCompleterModel(QObject *parent)
fd7f51cd Poul Sander 2026-05-22 15:30 37
    : QAbstractListModel(parent)
fd7f51cd Poul Sander 2026-05-22 15:30 38
{
fd7f51cd Poul Sander 2026-05-22 15:30 39
}
fd7f51cd Poul Sander 2026-05-22 15:30 40
fd7f51cd Poul Sander 2026-05-22 15:30 41
int PathCompleterModel::rowCount(const QModelIndex &parent) const
fd7f51cd Poul Sander 2026-05-22 15:30 42
{
fd7f51cd Poul Sander 2026-05-22 15:30 43
    if (parent.isValid())
fd7f51cd Poul Sander 2026-05-22 15:30 44
        return 0;
fd7f51cd Poul Sander 2026-05-22 15:30 45
    return static_cast<int>(m_entries.size());
fd7f51cd Poul Sander 2026-05-22 15:30 46
}
fd7f51cd Poul Sander 2026-05-22 15:30 47
fd7f51cd Poul Sander 2026-05-22 15:30 48
QVariant PathCompleterModel::data(const QModelIndex &index, int role) const
fd7f51cd Poul Sander 2026-05-22 15:30 49
{
fd7f51cd Poul Sander 2026-05-22 15:30 50
    if (!index.isValid() || index.row() < 0 || index.row() >= m_entries.size())
fd7f51cd Poul Sander 2026-05-22 15:30 51
        return {};
fd7f51cd Poul Sander 2026-05-22 15:30 52
    if (role == Qt::DisplayRole || role == Qt::EditRole)
fd7f51cd Poul Sander 2026-05-22 15:30 53
        return m_entries.at(index.row());
fd7f51cd Poul Sander 2026-05-22 15:30 54
    return {};
fd7f51cd Poul Sander 2026-05-22 15:30 55
}
fd7f51cd Poul Sander 2026-05-22 15:30 56
fd7f51cd Poul Sander 2026-05-22 15:30 57
void PathCompleterModel::setPrefix(const QString &text)
fd7f51cd Poul Sander 2026-05-22 15:30 58
{
fd7f51cd Poul Sander 2026-05-22 15:30 59
    // Determine the directory whose children we should list.
fd7f51cd Poul Sander 2026-05-22 15:30 60
    QString parentDir;
fd7f51cd Poul Sander 2026-05-22 15:30 61
    if (text.isEmpty()) {
fd7f51cd Poul Sander 2026-05-22 15:30 62
        parentDir = QStringLiteral("/");
fd7f51cd Poul Sander 2026-05-22 15:30 63
    } else if (text.endsWith(QLatin1Char('/'))) {
fd7f51cd Poul Sander 2026-05-22 15:30 64
        // Strip the trailing slash unless we're at filesystem root.
fd7f51cd Poul Sander 2026-05-22 15:30 65
        parentDir = (text.size() == 1) ? text : text.left(text.size() - 1);
fd7f51cd Poul Sander 2026-05-22 15:30 66
    } else {
fd7f51cd Poul Sander 2026-05-22 15:30 67
        QFileInfo info(text);
fd7f51cd Poul Sander 2026-05-22 15:30 68
        parentDir = info.path();
fd7f51cd Poul Sander 2026-05-22 15:30 69
        if (parentDir.isEmpty())
fd7f51cd Poul Sander 2026-05-22 15:30 70
            parentDir = QStringLiteral("/");
fd7f51cd Poul Sander 2026-05-22 15:30 71
    }
fd7f51cd Poul Sander 2026-05-22 15:30 72
fd7f51cd Poul Sander 2026-05-22 15:30 73
    if (m_hasParent && parentDir == m_currentParent)
fd7f51cd Poul Sander 2026-05-22 15:30 74
        return;
fd7f51cd Poul Sander 2026-05-22 15:30 75
fd7f51cd Poul Sander 2026-05-22 15:30 76
    QStringList newEntries;
fd7f51cd Poul Sander 2026-05-22 15:30 77
    try {
fd7f51cd Poul Sander 2026-05-22 15:30 78
        const QByteArray parentNative = QFile::encodeName(parentDir);
fd7f51cd Poul Sander 2026-05-22 15:30 79
        std::vector<std::pair<std::string, std::string>> entries; // {nativePath, filename}
fd7f51cd Poul Sander 2026-05-22 15:30 80
        for (const fs::directory_entry &entry :
fd7f51cd Poul Sander 2026-05-22 15:30 81
             fs::directory_iterator(parentNative.toStdString(),
fd7f51cd Poul Sander 2026-05-22 15:30 82
                                    fs::directory_options::skip_permission_denied))
fd7f51cd Poul Sander 2026-05-22 15:30 83
        {
fd7f51cd Poul Sander 2026-05-22 15:30 84
            std::error_code ec;
fd7f51cd Poul Sander 2026-05-22 15:30 85
            const std::string fname = entry.path().filename().native();
fd7f51cd Poul Sander 2026-05-22 15:30 86
            if (fname.empty() || fname[0] == '.')
fd7f51cd Poul Sander 2026-05-22 15:30 87
                continue;
fd7f51cd Poul Sander 2026-05-22 15:30 88
            if (!entry.is_directory(ec))
fd7f51cd Poul Sander 2026-05-22 15:30 89
                continue;
fd7f51cd Poul Sander 2026-05-22 15:30 90
            entries.push_back({entry.path().native(), fname});
fd7f51cd Poul Sander 2026-05-22 15:30 91
        }
fd7f51cd Poul Sander 2026-05-22 15:30 92
        std::sort(entries.begin(), entries.end(),
fd7f51cd Poul Sander 2026-05-22 15:30 93
                  [](const auto &a, const auto &b) { return a.second < b.second; });
fd7f51cd Poul Sander 2026-05-22 15:30 94
fd7f51cd Poul Sander 2026-05-22 15:30 95
        newEntries.reserve(static_cast<qsizetype>(entries.size()));
fd7f51cd Poul Sander 2026-05-22 15:30 96
        for (const auto &[npath, fname] : entries) {
fd7f51cd Poul Sander 2026-05-22 15:30 97
            newEntries.append(QFile::decodeName(
fd7f51cd Poul Sander 2026-05-22 15:30 98
                QByteArray::fromStdString(npath)));
fd7f51cd Poul Sander 2026-05-22 15:30 99
        }
fd7f51cd Poul Sander 2026-05-22 15:30 100
    } catch (const fs::filesystem_error &) {
fd7f51cd Poul Sander 2026-05-22 15:30 101
        // Inaccessible parent — fall through with an empty list.
fd7f51cd Poul Sander 2026-05-22 15:30 102
    }
fd7f51cd Poul Sander 2026-05-22 15:30 103
fd7f51cd Poul Sander 2026-05-22 15:30 104
    beginResetModel();
fd7f51cd Poul Sander 2026-05-22 15:30 105
    m_entries = std::move(newEntries);
fd7f51cd Poul Sander 2026-05-22 15:30 106
    m_currentParent = parentDir;
fd7f51cd Poul Sander 2026-05-22 15:30 107
    m_hasParent = true;
fd7f51cd Poul Sander 2026-05-22 15:30 108
    endResetModel();
fd7f51cd Poul Sander 2026-05-22 15:30 109
}
1970-01-01 00:00 110