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/.clang-format | 55 ++++++ ui.qt/CMakeLists.txt | 43 +++++ ui.qt/CMakeLists.txt.user | 332 +++++++++++++++++++++++++++++++++++++ ui.qt/locale/EpistmoolUI_zh_CN.ts | 3 + 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 ++ 15 files changed, 762 insertions(+) create mode 100644 ui.qt/.clang-format create mode 100644 ui.qt/CMakeLists.txt create mode 100644 ui.qt/CMakeLists.txt.user create mode 100644 ui.qt/locale/EpistmoolUI_zh_CN.ts 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') diff --git a/ui.qt/.clang-format b/ui.qt/.clang-format new file mode 100644 index 0000000..841dce2 --- /dev/null +++ b/ui.qt/.clang-format @@ -0,0 +1,55 @@ +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignOperands: false +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: true +AllowAllArgumentsOnNextLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: true +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: MultiLine + AfterEnum: false + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +ColumnLimit: 0 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +IncludeCategories: + - Regex: '".*"' + Priority: 1 + - Regex: '^<.*\.h>' + Priority: 2 + - Regex: '^<.*' + Priority: 3 +IndentCaseLabels: true +IndentPPDirectives: AfterHash +IndentWidth: 4 +NamespaceIndentation: Inner +PointerAlignment: Left +TabWidth: 4 +UseTab: Always +--- +### C++ specific config ### +Language: Cpp +Standard: Cpp11 diff --git a/ui.qt/CMakeLists.txt b/ui.qt/CMakeLists.txt new file mode 100644 index 0000000..7d7624a --- /dev/null +++ b/ui.qt/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.16) +project(EpistmoolUI VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.2 COMPONENTS Quick REQUIRED) + +qt_add_executable(appEpistmoolUI + source/main.cpp + source/fwd.hpp + source/document.hpp source/document.cpp + source/knowledgefragment.hpp source/knowledgefragment.cpp + source/keyword.hpp source/keyword.cpp +) + + +qt_add_qml_module(appEpistmoolUI + URI EpistmoolUI + VERSION 1.0 + QML_FILES + source/qml/MainWindow.qml + source/qml/GoToKnowledge.qml + source/qml/Document.qml +) + +set_target_properties(appEpistmoolUI PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER rtk0cium0001.github.io + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_include_directories(appEpistmoolUI PUBLIC source) +target_compile_definitions(appEpistmoolUI +PRIVATE + $<$,$>:QT_QML_DEBUG> +) +target_link_libraries(appEpistmoolUI +PRIVATE + Qt6::Quick +) diff --git a/ui.qt/CMakeLists.txt.user b/ui.qt/CMakeLists.txt.user new file mode 100644 index 0000000..69693ad --- /dev/null +++ b/ui.qt/CMakeLists.txt.user @@ -0,0 +1,332 @@ + + + + + + EnvironmentId + {f75faabe-ab95-4cc2-874a-48bde0690e72} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + Builtin.BuildSystem + + true + true + Builtin.DefaultTidyAndClazy + 6 + + + + true + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop (Qt 6) + Desktop (Qt 6) + {bb2c42c9-b15c-4e15-9289-35a041c6fb85} + 0 + 0 + 0 + + Debug + -GNinja +-DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + 0 + /home/rtk0c/Development/epistmool/ui.qt/build/Debug + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + + + Release + -GNinja +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/rtk0c/Development/epistmool/ui.qt/build-EpistmoolUI-Desktop_Qt_6-Release + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release + CMakeProjectManager.CMakeBuildConfiguration + + + RelWithDebInfo + -GNinja +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/rtk0c/Development/epistmool/ui.qt/build-EpistmoolUI-Desktop_Qt_6-RelWithDebInfo + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release with Debug Information + CMakeProjectManager.CMakeBuildConfiguration + + + MinSizeRel + -GNinja +-DCMAKE_BUILD_TYPE:STRING=MinSizeRel +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/rtk0c/Development/epistmool/ui.qt/build-EpistmoolUI-Desktop_Qt_6-MinSizeRel + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Minimum Size Release + CMakeProjectManager.CMakeBuildConfiguration + + 4 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + appEpistmoolUI + CMakeProjectManager.CMakeRunConfiguration.appEpistmoolUI + appEpistmoolUI + false + true + true + false + true + /home/rtk0c/Development/epistmool/ui.qt/build/Debug + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/ui.qt/locale/EpistmoolUI_zh_CN.ts b/ui.qt/locale/EpistmoolUI_zh_CN.ts new file mode 100644 index 0000000..630fd35 --- /dev/null +++ b/ui.qt/locale/EpistmoolUI_zh_CN.ts @@ -0,0 +1,3 @@ + + + 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