Something went wrong. Try again.
The agentic engineering control plane for the posthuman future
Something went wrong. Try again.
3.6 kB · 119 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120#include "PathRowProvider.h"
#include <QDateTime>#include <QMutexLocker>
#include "PathFuzzy.h"
namespace {
// How long the deeper walk stays valid. Long enough that typing a name pays for// it once, short enough that a file created elsewhere appears on its own.constexpr qint64 kDeepCacheMs = 5000;
} // namespace
PathRowProvider::PathRowProvider(QObject* parent) : FuzzyRowProvider(parent) {}
void PathRowProvider::setIncludeFiles(bool include){ if (m_includeFiles == include) { return; } // The worker reads m_includeFiles under inputLock() while it ranks; the write // must take the same lock so it never sees a torn value. { QMutexLocker lock(&inputLock()); m_includeFiles = include; } emit includeFilesChanged(); invalidate();}
void PathRowProvider::setRoot(const QString& root){ if (m_root == root) { return; } // A new root makes the cached walk describe a different tree, so the cache // goes with it. { QMutexLocker lock(&inputLock()); m_root = root; m_deepRoot.clear(); m_deepStampMs = 0; } emit rootChanged(); invalidate();}
void PathRowProvider::setIncludeTerminalRow(bool include){ if (m_includeTerminalRow == include) { return; } { QMutexLocker lock(&inputLock()); m_includeTerminalRow = include; } emit includeTerminalRowChanged(); invalidate();}
const QStringList& PathRowProvider::deepPaths(){ // Reached under inputLock(), so m_root is stable. const qint64 now = QDateTime::currentMSecsSinceEpoch(); if (m_deepRoot != m_root || now - m_deepStampMs > kDeepCacheMs) { m_deepWalk = walkPaths(m_root, PathScope::Files); m_deepRoot = m_root; m_deepStampMs = now; } return m_deepWalk.paths;}
QVariantList PathRowProvider::rowsForQuery(const QString& query){ // Reached under inputLock(), so every input member is stable. const QString base = PathFuzzy::queryBase(query); const QString partial = PathFuzzy::queryPartial(query); const bool files = m_includeFiles; const PathScope scope = files ? PathScope::Entries : PathScope::Directories;
// The primary listing: the directory the text names, one level deep. const WalkResult listing = walkPaths(base, scope); QVariantList rows = rankRows(listing.paths, base, partial, scope, files && m_includeTerminalRow); WalkLimit limit = listing.limit;
if (files && !partial.isEmpty() && rows.isEmpty()) { // Nothing in the current directory matches, so look deeper from the root. // This is the only path that reads a whole tree, and deepPaths() caches it. // The partial is the search text, not the whole field: the field holds a // path, and a path never fuzzy-matches a file name. rows = rankRows(deepPaths(), m_root, partial, PathScope::Files, false); limit = m_deepWalk.limit; }
// The note explains the set that was just built. An empty listing on a // non-empty fragment is the case a user meets when the name they typed is not // there, and silence there reads as a broken picker rather than an absent // file. if (rows.isEmpty() && !partial.isEmpty()) { setNote(QStringLiteral("nothing here matches \"%1\"").arg(partial)); return rows; } switch (limit) { case WalkLimit::None: setNote(QString()); break; case WalkLimit::Count: setNote( QStringLiteral("showing the first %1 entries").arg(kMaxWalkPaths)); break; case WalkLimit::Depth: setNote(QStringLiteral("searched %1 levels down").arg(kMaxWalkDepth)); break; } return rows;}