From 753c26d320e894069157bd401f7779ad07073d7c Mon Sep 17 00:00:00 2001 From: rtk0c Date: Mon, 27 Jun 2022 00:09:44 +0000 Subject: (From git) Initial Qt GUI setup git-svn-id: file:///home/arch/svn/epistmool/trunk@2 71f44415-077c-4ad7-a976-72ddbf76608f --- ui.qt/source/document.cpp | 78 ++++++++++++++++++++++++++++++++++++++ ui.qt/source/document.hpp | 62 ++++++++++++++++++++++++++++++ ui.qt/source/fwd.hpp | 14 +++++++ ui.qt/source/keyword.cpp | 10 +++++ ui.qt/source/keyword.hpp | 26 +++++++++++++ ui.qt/source/knowledgefragment.cpp | 11 ++++++ ui.qt/source/knowledgefragment.hpp | 38 +++++++++++++++++++ ui.qt/source/main.cpp | 35 +++++++++++++++++ ui.qt/source/qml/Document.qml | 39 +++++++++++++++++++ ui.qt/source/qml/GoToKnowledge.qml | 4 ++ ui.qt/source/qml/MainWindow.qml | 12 ++++++ 11 files changed, 329 insertions(+) create mode 100644 ui.qt/source/document.cpp create mode 100644 ui.qt/source/document.hpp create mode 100644 ui.qt/source/fwd.hpp create mode 100644 ui.qt/source/keyword.cpp create mode 100644 ui.qt/source/keyword.hpp create mode 100644 ui.qt/source/knowledgefragment.cpp create mode 100644 ui.qt/source/knowledgefragment.hpp create mode 100644 ui.qt/source/main.cpp create mode 100644 ui.qt/source/qml/Document.qml create mode 100644 ui.qt/source/qml/GoToKnowledge.qml create mode 100644 ui.qt/source/qml/MainWindow.qml (limited to 'ui.qt/source') diff --git a/ui.qt/source/document.cpp b/ui.qt/source/document.cpp new file mode 100644 index 0000000..b418b0d --- /dev/null +++ b/ui.qt/source/document.cpp @@ -0,0 +1,78 @@ +#include "document.hpp" + +#include +#include + +DocumentBlock::DocumentBlock(QObject* parent) + : QObject{ parent } +{ +} + +DocumentModel* DocumentBlock::getModel() const +{ + return mModel; +} + +void DocumentBlock::setModel(DocumentModel* newModel) +{ + mModel = newModel; +} + +QQuickTextDocument* DocumentBlock::getDoc() const +{ + return mDoc; +} + +void DocumentBlock::setDoc(QQuickTextDocument* newDoc) +{ + if (mDoc != newDoc) { + if (mDoc) { + disconnect(mDoc->textDocument(), nullptr, this, nullptr); + } + mDoc = newDoc; + if (newDoc) { + connect(newDoc->textDocument(), &QTextDocument::modificationChanged, this, [&]() { + // TODO add a timer to wait for 1 second before updating? + mModifyTime = QDateTime::currentDateTime(); + emit modificationChanged(); + }); + } + emit docChanged(); + } +} + +const QDateTime& DocumentBlock::getModifyTime() const +{ + return mModifyTime; +} + +void DocumentModel::appendBlock(DocumentBlock* block) +{ + mBlocks.push_back(block); +} + +int DocumentModel::rowCount(const QModelIndex& parent) const +{ + return mBlocks.size(); +} + +QVariant DocumentModel::data(const QModelIndex& index, int role) const +{ + if (index.row() < 0 || index.row() >= mBlocks.size()) { + return QVariant(); + } + + switch (role) { + case Qt::DisplayRole: return QVariant::fromValue(mBlocks[index.row()]); + case ModifyTimeRole: return mBlocks[index.row()]->getModifyTime(); + default: return QVariant(); + } +} + +QHash DocumentModel::roleNames() const +{ + QHash roles; + roles[Qt::DisplayRole] = "display", + roles[ModifyTimeRole] = "modifyTime"; + return roles; +} diff --git a/ui.qt/source/document.hpp b/ui.qt/source/document.hpp new file mode 100644 index 0000000..ba11e26 --- /dev/null +++ b/ui.qt/source/document.hpp @@ -0,0 +1,62 @@ +#pragma once + +#include "fwd.hpp" + +#include +#include +#include +#include + +class DocumentBlock : public QObject +{ + Q_OBJECT + QML_ELEMENT + + Q_PROPERTY(QQuickTextDocument* textDocument READ getDoc WRITE setDoc NOTIFY docChanged) + +private: + DocumentModel* mModel; + QQuickTextDocument* mDoc = nullptr; + QDateTime mModifyTime; + +public: + explicit DocumentBlock(QObject* parent = nullptr); + + DocumentModel* getModel() const; + void setModel(DocumentModel* newModel); + + QQuickTextDocument* getDoc() const; + void setDoc(QQuickTextDocument* newDoc); + + const QDateTime& getModifyTime() const; + +signals: + void docChanged(); + void modificationChanged(); +}; + +class DocumentModel : public QAbstractItemModel +{ + Q_OBJECT + QML_ELEMENT + +private: + std::vector mBlocks; + +public: + enum DocumentRoles { + ModifyTimeRole = Qt::UserRole + 1, + }; + + DocumentModel(QObject* parent = nullptr); + + void appendBlock(DocumentBlock* block); + // TODO + // void moveBlock() + + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + +protected: + QHash roleNames() const override; +}; diff --git a/ui.qt/source/fwd.hpp b/ui.qt/source/fwd.hpp new file mode 100644 index 0000000..7f98627 --- /dev/null +++ b/ui.qt/source/fwd.hpp @@ -0,0 +1,14 @@ +#pragma once + +// document.hpp +class DocumentBlock; +class DocumentModel; + +// keyword.hpp +class Keyword; +class KeywordDatabase; + +// knowledgefragment.cpp +struct KnowledgeId; +class KnowledgeFragment; +class KnowledgeDatabase; diff --git a/ui.qt/source/keyword.cpp b/ui.qt/source/keyword.cpp new file mode 100644 index 0000000..f782437 --- /dev/null +++ b/ui.qt/source/keyword.cpp @@ -0,0 +1,10 @@ +#include "keyword.hpp" + +#include "knowledgefragment.hpp" + +Keyword::Keyword(const QString& name) + : name(name) +{ +} + +Keyword::~Keyword() = default; diff --git a/ui.qt/source/keyword.hpp b/ui.qt/source/keyword.hpp new file mode 100644 index 0000000..bc50473 --- /dev/null +++ b/ui.qt/source/keyword.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "fwd.hpp" + +#include +#include + +class Keyword +{ +private: + QString name; + std::vector associations; + +public: + Keyword(const QString& name); + ~Keyword(); + + Keyword(const Keyword&) = default; + Keyword& operator=(const Keyword&) = default; + Keyword(Keyword&&) = default; + Keyword& operator=(Keyword&&) = default; +}; + +class KeywordDatabase +{ +}; diff --git a/ui.qt/source/knowledgefragment.cpp b/ui.qt/source/knowledgefragment.cpp new file mode 100644 index 0000000..4db09e7 --- /dev/null +++ b/ui.qt/source/knowledgefragment.cpp @@ -0,0 +1,11 @@ +#include "knowledgefragment.hpp" + +KnowledgeFragment::KnowledgeFragment(KnowledgeId id) + : id{ id } +{ +} + +KnowledgeId KnowledgeFragment::getId() const +{ + return id; +} diff --git a/ui.qt/source/knowledgefragment.hpp b/ui.qt/source/knowledgefragment.hpp new file mode 100644 index 0000000..533d99f --- /dev/null +++ b/ui.qt/source/knowledgefragment.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "fwd.hpp" + +#include +#include +#include + +struct KnowledgeId +{ + size_t id; +}; + +class KnowledgeFragment +{ +private: + QDateTime createTime; + QDateTime modifyTime; + KnowledgeId id; + +public: + KnowledgeFragment(KnowledgeId id); + + KnowledgeId getId() const; +}; + +class KnowledgeDatabase +{ +private: + std::vector storage; + std::vector index; // Mapping from KnowledgeId (index) to `storage` index + KnowledgeId nextId; + +public: + KnowledgeId allocateFragment(); + bool deleteFragment(KnowledgeId id); + KnowledgeFragment* getFragment(KnowledgeId id); +}; diff --git a/ui.qt/source/main.cpp b/ui.qt/source/main.cpp new file mode 100644 index 0000000..e92863f --- /dev/null +++ b/ui.qt/source/main.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QTranslator translator; + const QStringList uiLanguages = QLocale::system().uiLanguages(); + for (const QString& locale : uiLanguages) { + const QString baseName = "EpistmoolUI_" + QLocale(locale).name(); + if (translator.load(":/i18n/" + baseName)) { + app.installTranslator(&translator); + break; + } + } + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/EpistmoolUI/source/qml/MainWindow.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreated, + &app, + [url](QObject* obj, const QUrl& objUrl) { + if (!obj && url == objUrl) { + QCoreApplication::exit(-1); + } + }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/ui.qt/source/qml/Document.qml b/ui.qt/source/qml/Document.qml new file mode 100644 index 0000000..e62b731 --- /dev/null +++ b/ui.qt/source/qml/Document.qml @@ -0,0 +1,39 @@ +import QtCore +import QtQuick +import QtQuick.Controls + +import EpistmoolUI + +Item { + DocumentModel { + id: documentModel + } + + ScrollView { + id: scrollView + + ListView { + id: listView + model: documentModel + anchors.fill: parent + + delegate: Item { + required property DocumentBlock documentBlock + required property date modifyTime + + Component.onCompleted: { + documentBlock.textDocument = textArea.textDocument + } + + TextArea { + id: textArea + textFormat: Qt.RichText + wrapMode: TextArea.Wrap + focus: true + selectByMouse: true + persistentSelection: true + } + } + } + } +} diff --git a/ui.qt/source/qml/GoToKnowledge.qml b/ui.qt/source/qml/GoToKnowledge.qml new file mode 100644 index 0000000..f97cbcf --- /dev/null +++ b/ui.qt/source/qml/GoToKnowledge.qml @@ -0,0 +1,4 @@ +import QtQuick + +Item { +} diff --git a/ui.qt/source/qml/MainWindow.qml b/ui.qt/source/qml/MainWindow.qml new file mode 100644 index 0000000..905f0e8 --- /dev/null +++ b/ui.qt/source/qml/MainWindow.qml @@ -0,0 +1,12 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Hello World") + + Document { + id: doc + } +} -- cgit v1.2.3-70-g09d2