2026-08-17 01:14:00 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
#include <QList>
|
|
|
|
|
|
|
|
|
|
// Управление открытыми документами: вкладки, содержимое, признак «изменён»,
|
|
|
|
|
// автосохранение каждые 5 секунд (защита от потери текста).
|
|
|
|
|
// Режимы редактирование/просмотр — на стороне QML (на документ).
|
|
|
|
|
class DocumentManager : public QObject
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
Q_PROPERTY(QStringList openTabs READ openTabs NOTIFY openTabsChanged)
|
|
|
|
|
Q_PROPERTY(int activeIndex READ activeIndex WRITE setActiveIndex NOTIFY activeIndexChanged)
|
|
|
|
|
Q_PROPERTY(int secondaryIndex READ secondaryIndex WRITE setSecondaryIndex NOTIFY secondaryIndexChanged)
|
|
|
|
|
Q_PROPERTY(bool sideBySide READ sideBySide WRITE setSideBySide NOTIFY sideBySideChanged)
|
|
|
|
|
Q_PROPERTY(int autosaveIntervalMs READ autosaveIntervalMs WRITE setAutosaveIntervalMs
|
|
|
|
|
NOTIFY autosaveIntervalChanged)
|
|
|
|
|
Q_PROPERTY(QString lastStatus READ lastStatus NOTIFY lastStatusChanged)
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit DocumentManager(QObject *parent = nullptr);
|
|
|
|
|
|
|
|
|
|
QStringList openTabs() const;
|
|
|
|
|
int activeIndex() const;
|
2026-09-01 19:25:07 +03:00
|
|
|
Q_INVOKABLE void setActiveIndex(int index);
|
2026-08-17 01:14:00 +03:00
|
|
|
int secondaryIndex() const;
|
2026-09-01 19:25:07 +03:00
|
|
|
Q_INVOKABLE void setSecondaryIndex(int index);
|
2026-08-17 01:14:00 +03:00
|
|
|
bool sideBySide() const;
|
2026-09-01 19:25:07 +03:00
|
|
|
Q_INVOKABLE void setSideBySide(bool on);
|
2026-08-17 01:14:00 +03:00
|
|
|
int autosaveIntervalMs() const;
|
2026-09-01 19:25:07 +03:00
|
|
|
Q_INVOKABLE void setAutosaveIntervalMs(int ms);
|
2026-08-17 01:14:00 +03:00
|
|
|
QString lastStatus() const;
|
|
|
|
|
|
|
|
|
|
// Открывает документ (при необходимости создаётся вкладка). Возвращает индекс.
|
|
|
|
|
Q_INVOKABLE int openDocument(const QString &path);
|
|
|
|
|
|
|
|
|
|
// Содержимое/заголовок/признак по индексу вкладки.
|
|
|
|
|
Q_INVOKABLE QString contentAt(int index) const;
|
|
|
|
|
Q_INVOKABLE QString titleAt(int index) const;
|
|
|
|
|
Q_INVOKABLE QString pathAt(int index) const;
|
|
|
|
|
Q_INVOKABLE bool isDirty(int index) const;
|
|
|
|
|
|
|
|
|
|
// Редактирование: пользователь изменил текст вкладки.
|
|
|
|
|
Q_INVOKABLE void updateContent(int index, const QString &text);
|
|
|
|
|
|
|
|
|
|
// Можно ли открыть файл в текстовом редакторе (md и прочие текстовые).
|
|
|
|
|
Q_INVOKABLE bool isTextForEditor(const QString &path) const;
|
|
|
|
|
|
|
|
|
|
Q_INVOKABLE void saveDocument(int index);
|
|
|
|
|
Q_INVOKABLE void saveAll();
|
|
|
|
|
|
|
|
|
|
Q_INVOKABLE bool closeTab(int index);
|
2026-09-01 19:25:07 +03:00
|
|
|
Q_INVOKABLE void moveTab(int from, int to);
|
2026-08-17 01:14:00 +03:00
|
|
|
|
|
|
|
|
signals:
|
|
|
|
|
void openTabsChanged();
|
|
|
|
|
void activeIndexChanged();
|
|
|
|
|
void secondaryIndexChanged();
|
|
|
|
|
void sideBySideChanged();
|
|
|
|
|
void autosaveIntervalChanged();
|
|
|
|
|
void lastStatusChanged();
|
|
|
|
|
|
|
|
|
|
// Уведомляет вкладку о смене признака «изменено».
|
|
|
|
|
void dirtyFlagChanged(int index);
|
|
|
|
|
// Содержимое документа изменилось (вкладка index).
|
|
|
|
|
void contentChanged(int index);
|
|
|
|
|
// Файл фактически записан на диск.
|
|
|
|
|
void documentSaved(int index, const QString &path);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
struct Doc {
|
|
|
|
|
QString path;
|
|
|
|
|
QString content;
|
|
|
|
|
bool dirty = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void ensureAutosave();
|
|
|
|
|
QString readFile(const QString &path, bool *ok) const;
|
|
|
|
|
|
|
|
|
|
QList<Doc> m_docs;
|
|
|
|
|
int m_active = -1;
|
|
|
|
|
int m_secondary = -1;
|
|
|
|
|
bool m_sideBySide = false;
|
|
|
|
|
int m_autosaveMs = 5000;
|
|
|
|
|
QString m_lastStatus;
|
2026-09-01 19:25:07 +03:00
|
|
|
QTimer *m_autosave = nullptr;
|
2026-08-17 01:14:00 +03:00
|
|
|
};
|