Фазы 2-3: мульти-окна (WindowController, per-window FileStore), файловое дерево (FileStore+FileTreePanel, иконки/раскрытие/ПКМ/+drag&drop/подтверждения), NameDialog/ConfirmDialog; тест filestore (13/13)
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
#include "app/WindowController.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QQmlComponent>
|
||||
#include <QQmlContext>
|
||||
|
||||
#include "core/FileStore.h"
|
||||
|
||||
WindowController::WindowController(QQmlApplicationEngine *engine,
|
||||
const QString &mainWindowUrl,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_engine(engine)
|
||||
, m_mainWindowUrl(mainWindowUrl)
|
||||
{
|
||||
}
|
||||
|
||||
int WindowController::windowCount() const
|
||||
{
|
||||
return m_windows.size();
|
||||
}
|
||||
|
||||
QStringList WindowController::openVaults() const
|
||||
{
|
||||
QStringList list;
|
||||
for (const Window &w : m_windows)
|
||||
if (!w.vault.isEmpty())
|
||||
list.append(w.vault);
|
||||
return list;
|
||||
}
|
||||
|
||||
int WindowController::indexOfVault(const QString &vaultPath) const
|
||||
{
|
||||
for (int i = 0; i < m_windows.size(); ++i)
|
||||
if (m_windows[i].vault == vaultPath)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
QObject *WindowController::openWindow(const QString &vaultPath)
|
||||
{
|
||||
if (!m_engine)
|
||||
return nullptr;
|
||||
|
||||
if (!m_component) {
|
||||
m_component = new QQmlComponent(m_engine, QUrl(m_mainWindowUrl), this);
|
||||
if (m_component->isError()) {
|
||||
qWarning("WindowController: %s", qPrintable(m_component->errorString()));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QQmlContext *ctx = new QQmlContext(m_engine->rootContext(), this);
|
||||
FileStore *store = new FileStore(ctx);
|
||||
ctx->setContextProperty("fileStore", store);
|
||||
|
||||
QObject *obj = m_component->create(ctx);
|
||||
if (!obj) {
|
||||
qWarning("WindowController: create failed: %s",
|
||||
qPrintable(m_component->errorString()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_windows.append({vaultPath, obj, store});
|
||||
connect(obj, &QObject::destroyed, this, [this, obj]() {
|
||||
for (int i = 0; i < m_windows.size(); ++i) {
|
||||
if (m_windows[i].object == obj) {
|
||||
const QString vault = m_windows[i].vault;
|
||||
m_windows.removeAt(i);
|
||||
emit windowsChanged();
|
||||
if (!vault.isEmpty())
|
||||
emit windowClosed(vault);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
obj->setProperty("windowVault", vaultPath);
|
||||
// Закрытие окна уничтожает QML-объект (чтобы последнее окно завершало приложение).
|
||||
obj->setProperty("destroyOnWindowClose", true);
|
||||
if (!vaultPath.isEmpty() && QDir(vaultPath).exists())
|
||||
store->openVault(vaultPath);
|
||||
|
||||
emit windowsChanged();
|
||||
if (!vaultPath.isEmpty())
|
||||
emit windowOpened(vaultPath);
|
||||
return obj;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QPointer>
|
||||
#include <QList>
|
||||
|
||||
class FileStore;
|
||||
|
||||
// Создание окон приложения (мульти-хранилища: новое хранилище — новое окно).
|
||||
class WindowController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int windowCount READ windowCount NOTIFY windowsChanged)
|
||||
Q_PROPERTY(QStringList openVaults READ openVaults NOTIFY windowsChanged)
|
||||
|
||||
public:
|
||||
WindowController(QQmlApplicationEngine *engine, const QString &mainWindowUrl,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
int windowCount() const;
|
||||
QStringList openVaults() const;
|
||||
|
||||
// Открывает окно с заданным хранилищем. Возвращает nullptr при ошибке.
|
||||
Q_INVOKABLE QObject *openWindow(const QString &vaultPath);
|
||||
|
||||
Q_INVOKABLE int indexOfVault(const QString &vaultPath) const;
|
||||
|
||||
signals:
|
||||
void windowsChanged();
|
||||
void windowOpened(const QString &vaultPath);
|
||||
void windowClosed(const QString &vaultPath);
|
||||
|
||||
private:
|
||||
struct Window {
|
||||
QString vault;
|
||||
QPointer<QObject> object;
|
||||
FileStore *fileStore = nullptr;
|
||||
};
|
||||
|
||||
QQmlApplicationEngine *m_engine;
|
||||
QString m_mainWindowUrl;
|
||||
QList<Window> m_windows;
|
||||
QQmlComponent *m_component = nullptr;
|
||||
};
|
||||
Reference in New Issue
Block a user