#pragma once #include #include #include #include #include class Database; // Рендер Markdown (CommonMark + GFM) в HTML для режима просмотра. // Задачи/ссылки/переходы кодируются ссылками schemes: // flora://task/N — переключить задачу на строке N (1-based) // flora://open/ — открыть файл хранилища // flora://wiki/ — вики-ссылка без найденного файла class MdParser : public QObject { Q_OBJECT public: explicit MdParser(QObject *parent = nullptr); ~MdParser() override; // markdown → HTML. vaultRoot/vaultDir — для разрешения относительных путей. Q_INVOKABLE QString render(const QString &markdown, const QString &vaultRoot, const QString &fileDir); // Разбор на блоки для отдельного отображения кодовых блоков (CodeBlock.qml) // Возвращает список {type:"html"/"code", html/code/language/codeId/highlighted} Q_INVOKABLE QVariantList parseBlocks(const QString &markdown, const QString &vaultRoot, const QString &fileDir); // Те же блоки, но версия oldMd с подсветкой отличий от newMd (для «Истории»). // Каждый блок дополнительно имеет change:"same"/"del"/"add" (del — только в old, // add — только в new); изменённые блоки обёрнуты в цветной div прямо в html/highlighted. Q_INVOKABLE QVariantList parseBlocksWithDiff(const QString &oldMd, const QString &newMd, const QString &vaultRoot, const QString &fileDir); // То же, но в рабочем потоке (UI не виснет на больших файлах). // Возвращает requestId; результат приходит сигналом blocksReady (устаревшие id игнорить). // Регистрация кодов для копирования выполняется в главном потоке при приёме. Q_INVOKABLE int parseBlocksWithDiffAsync(const QString &oldMd, const QString &newMd, const QString &vaultRoot, const QString &fileDir); Q_INVOKABLE QString getCodeBlock(const QString &id) const; Q_INVOKABLE void copyToClipboard(const QString &text) const; // Скопировать кодовый блок по id (get + copy одним вызовом). false — нечего копировать. Q_INVOKABLE bool copyCodeBlock(const QString &id) const; // База хранилища для ~sql-блоков (по одному на хранилище; окна не мешают друг другу). // Регистрирует WindowController; из QML — только fallback для пути визарда. Q_INVOKABLE void setDatabaseForVault(const QString &vaultRoot, Database *db); Q_INVOKABLE void removeDatabaseForVault(const QString &vaultRoot, Database *db); private: Database *databaseFor(const QString &vaultRoot) const; signals: void blocksReady(int requestId, const QVariantList &blocks); public: struct Impl; private: // Внутренний рендер без сброса codeBlocks/codeCounter (для parseBlocks*, // которые сами управляют состоянием и вызывают его многократно) QString renderInner(const QString &markdown, const QString &vaultRoot, const QString &fileDir); Impl *m = nullptr; int m_asyncId = 0; // Кэш diff-блоков на время открытого диалога (ключ — хеши содержимого+пути). // Хранятся БЕЗ регистрации кодов; регистрация — при каждой выдаче. QCache m_diffCache; };