#pragma once #include #include #include #include // Индекс связей хранилища: теги, [[перекрёстные ссылки]], md-ссылки между // файлами, а также узлы и рёбра графа. Сканируется синхронно. class VaultIndex : public QObject { Q_OBJECT Q_PROPERTY(QVariantList nodes READ nodes NOTIFY indexChanged) Q_PROPERTY(QVariantList edges READ edges NOTIFY indexChanged) Q_PROPERTY(int fileCount READ fileCount NOTIFY indexChanged) Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) public: explicit VaultIndex(QObject *parent = nullptr); QVariantList nodes() const { return m_nodes; } QVariantList edges() const { return m_edges; } int fileCount() const { return m_fileCount; } bool busy() const { return m_busy; } // Полное пересканирование хранилища. Q_INVOKABLE void rebuild(const QString &vault); // Теги файла / ссылки файла (список {text,path} для открытия). Q_INVOKABLE QStringList tagsOfFile(const QString &path) const; Q_INVOKABLE QVariantList linksOfFile(const QString &path) const; // Все файлы с тегом tag. Q_INVOKABLE QStringList filesWithTag(const QString &tag) const; Q_INVOKABLE QString displayName(const QString &nodeKey) const; signals: void indexChanged(); void busyChanged(); private: QString nodeKeyFor(const QString &path, bool isFile) const; void collectFiles(const QString &dir, int depth, QStringList &out) const; void parseFile(const QString &path); QString resolveLink(const QString &fileDir, const QString &target) const; int ensureNode(const QString &key, const QString &name, const QString &type); void addEdge(const QString &from, const QString &to); QVariantList m_nodes; QVariantList m_edges; QHash m_nodeById; QHash m_tagsOfFile; QHash m_linksOfFile; QHash m_filesWithTag; QHash m_fileByBase; // имя без расширения → путь int m_fileCount = 0; bool m_busy = false; };