diff options
Diffstat (limited to 'ui.qt/src')
-rw-r--r-- | ui.qt/src/DatabaseClient.cpp | 5 | ||||
-rw-r--r-- | ui.qt/src/DatabaseClient.hpp | 7 | ||||
-rw-r--r-- | ui.qt/src/DatabaseServer.cpp | 5 | ||||
-rw-r--r-- | ui.qt/src/DatabaseServer.hpp | 7 | ||||
-rw-r--r-- | ui.qt/src/Document.cpp | 152 | ||||
-rw-r--r-- | ui.qt/src/Document.hpp | 72 | ||||
-rw-r--r-- | ui.qt/src/Keyword.cpp | 10 | ||||
-rw-r--r-- | ui.qt/src/Keyword.hpp | 26 | ||||
-rw-r--r-- | ui.qt/src/KnowledgeFragment.cpp | 11 | ||||
-rw-r--r-- | ui.qt/src/KnowledgeFragment.hpp | 38 | ||||
-rw-r--r-- | ui.qt/src/fwd.hpp | 13 | ||||
-rw-r--r-- | ui.qt/src/main.cpp | 35 |
12 files changed, 381 insertions, 0 deletions
diff --git a/ui.qt/src/DatabaseClient.cpp b/ui.qt/src/DatabaseClient.cpp new file mode 100644 index 0000000..430fe79 --- /dev/null +++ b/ui.qt/src/DatabaseClient.cpp @@ -0,0 +1,5 @@ +#include "DatabaseClient.hpp" + +DatabaseClient::DatabaseClient() +{ +} diff --git a/ui.qt/src/DatabaseClient.hpp b/ui.qt/src/DatabaseClient.hpp new file mode 100644 index 0000000..17c6ed7 --- /dev/null +++ b/ui.qt/src/DatabaseClient.hpp @@ -0,0 +1,7 @@ +#pragma once + +class DatabaseClient +{ +public: + DatabaseClient(); +}; diff --git a/ui.qt/src/DatabaseServer.cpp b/ui.qt/src/DatabaseServer.cpp new file mode 100644 index 0000000..a850e63 --- /dev/null +++ b/ui.qt/src/DatabaseServer.cpp @@ -0,0 +1,5 @@ +#include "DatabaseServer.hpp" + +DatabaseServer::DatabaseServer() +{ +} diff --git a/ui.qt/src/DatabaseServer.hpp b/ui.qt/src/DatabaseServer.hpp new file mode 100644 index 0000000..0cd5039 --- /dev/null +++ b/ui.qt/src/DatabaseServer.hpp @@ -0,0 +1,7 @@ +#pragma once + +class DatabaseServer +{ +public: + DatabaseServer(); +}; diff --git a/ui.qt/src/Document.cpp b/ui.qt/src/Document.cpp new file mode 100644 index 0000000..272ac4c --- /dev/null +++ b/ui.qt/src/Document.cpp @@ -0,0 +1,152 @@ +#include "Document.hpp" + +#include <QBrush> +#include <QColor> +#include <QTextCursor> +#include <QVariant> + +DocumentHandler::DocumentHandler(QObject* parent) + : QObject{ parent } +{ +} + +QQuickTextDocument* DocumentHandler::getDoc() const +{ + return mDoc; +} + +void DocumentHandler::setDoc(QQuickTextDocument* newDoc) +{ + if (mDoc != newDoc) { + auto oldDoc = mDoc; + mDoc = newDoc; + + if (oldDoc) { + disconnect(oldDoc->textDocument(), nullptr, this, nullptr); + } + 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(oldDoc); + } +} + +const QDateTime& DocumentHandler::getModifyTime() const +{ + return mModifyTime; +} + +int DocumentHandler::getCursorPos() const +{ + return mCursorPos; +} + +void DocumentHandler::setCursorPos(int newCursorPos) +{ + if (mCursorPos == newCursorPos) { + return; + } + mCursorPos = newCursorPos; + emit cursorPosChanged(); +} + +int DocumentHandler::getSelectionBegin() const +{ + return mSelectionBegin; +} + +void DocumentHandler::setSelectionBegin(int newSelectionBegin) +{ + if (mSelectionBegin == newSelectionBegin) { + return; + } + mSelectionBegin = newSelectionBegin; + emit selectionBeginChanged(); +} + +int DocumentHandler::getSelectionEnd() const +{ + return mSelectionEnd; +} + +void DocumentHandler::setSelectionEnd(int newSelectionEnd) +{ + if (mSelectionEnd == newSelectionEnd) { + return; + } + mSelectionEnd = newSelectionEnd; + emit selectionEndChanged(); +} + +QFont DocumentHandler::getActiveFont() const +{ + auto cursor = makeTextCursor(); + if (cursor.isNull()) { + return mDoc->textDocument()->defaultFont(); + } + auto format = cursor.charFormat(); + return format.font(); +} + +void DocumentHandler::setActiveFont(const QFont& font) +{ + auto cursor = makeTextCursor(); + if (!cursor.isNull() && cursor.charFormat().font() == font) { + return; + } + + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit activeFontChanged(); +} + +QColor DocumentHandler::getActiveTextColor() const +{ + auto cursor = makeTextCursor(); + if (cursor.isNull()) { + return QColor(Qt::black); + } + QTextCharFormat format = cursor.charFormat(); + return format.foreground().color(); +} + +void DocumentHandler::setActiveTextColor(const QColor& color) +{ + QTextCharFormat format; + format.setForeground(QBrush(color)); + mergeFormatOnWordOrSelection(format); + emit activeTextColorChanged(); +} + +QTextCursor DocumentHandler::makeTextCursor() const +{ + auto doc = mDoc->textDocument(); + if (!doc) { + return QTextCursor(); + } + + QTextCursor cursor(doc); + if (mSelectionBegin != mSelectionEnd) { + cursor.setPosition(mSelectionBegin); + cursor.setPosition(mSelectionEnd, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(mCursorPos); + } + return cursor; +} + +void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat& format) +{ + auto cursor = makeTextCursor(); + if (!cursor.hasSelection()) { + cursor.select(QTextCursor::WordUnderCursor); + } + cursor.mergeCharFormat(format); +} diff --git a/ui.qt/src/Document.hpp b/ui.qt/src/Document.hpp new file mode 100644 index 0000000..5ef1bba --- /dev/null +++ b/ui.qt/src/Document.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include "fwd.hpp" + +#include <QAbstractItemModel> +#include <QDateTime> +#include <QObject> +#include <QQuickTextDocument> +#include <QTextCharFormat> + +// To be instanciated in QML as the logic backend to some TextArea +class DocumentHandler : public QObject +{ + Q_OBJECT + QML_ELEMENT + + Q_PROPERTY(QQuickTextDocument* document READ getDoc WRITE setDoc NOTIFY docChanged) + Q_PROPERTY(QDateTime modifyTime READ getModifyTime NOTIFY modificationChanged) + + Q_PROPERTY(int cursorPos READ getCursorPos WRITE setCursorPos NOTIFY cursorPosChanged) + Q_PROPERTY(int selectionBegin READ getSelectionBegin WRITE setSelectionBegin NOTIFY selectionBeginChanged) + Q_PROPERTY(int selectionEnd READ getSelectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged) + + Q_PROPERTY(QFont activeFont READ getActiveFont WRITE setActiveFont NOTIFY activeFontChanged) + Q_PROPERTY(QColor activeTextColor READ getActiveTextColor WRITE setActiveTextColor NOTIFY activeTextColorChanged) + +private: + QQuickTextDocument* mDoc = nullptr; + QDateTime mModifyTime; + + int mCursorPos; + int mSelectionBegin; + int mSelectionEnd; + +public: + explicit DocumentHandler(QObject* parent = nullptr); + + QQuickTextDocument* getDoc() const; + void setDoc(QQuickTextDocument* newDoc); + + const QDateTime& getModifyTime() const; + + int getCursorPos() const; + void setCursorPos(int newCursorPos); + + int getSelectionBegin() const; + void setSelectionBegin(int newSelectionBegin); + + int getSelectionEnd() const; + void setSelectionEnd(int newSelectionEnd); + + QFont getActiveFont() const; + void setActiveFont(const QFont& font); + + QColor getActiveTextColor() const; + void setActiveTextColor(const QColor& color); + +signals: + void docChanged(QQuickTextDocument* oldDoc); + void modificationChanged(); // Redirected from the currently bound document + + void cursorPosChanged(); + void selectionBeginChanged(); + void selectionEndChanged(); + + void activeFontChanged(); + void activeTextColorChanged(); + +private: + QTextCursor makeTextCursor() const; + void mergeFormatOnWordOrSelection(const QTextCharFormat& format); +}; diff --git a/ui.qt/src/Keyword.cpp b/ui.qt/src/Keyword.cpp new file mode 100644 index 0000000..f6c18be --- /dev/null +++ b/ui.qt/src/Keyword.cpp @@ -0,0 +1,10 @@ +#include "Keyword.hpp" + +#include "KnowledgeFragment.hpp" + +Keyword::Keyword(const QString& name) + : mName(name) +{ +} + +Keyword::~Keyword() = default; diff --git a/ui.qt/src/Keyword.hpp b/ui.qt/src/Keyword.hpp new file mode 100644 index 0000000..481b5bb --- /dev/null +++ b/ui.qt/src/Keyword.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "fwd.hpp" + +#include <QString> +#include <vector> + +class Keyword +{ +private: + QString mName; + std::vector<KnowledgeId> mAssociations; + +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/src/KnowledgeFragment.cpp b/ui.qt/src/KnowledgeFragment.cpp new file mode 100644 index 0000000..3d08f6e --- /dev/null +++ b/ui.qt/src/KnowledgeFragment.cpp @@ -0,0 +1,11 @@ +#include "KnowledgeFragment.hpp" + +KnowledgeFragment::KnowledgeFragment(KnowledgeId id) + : mId{ id } +{ +} + +KnowledgeId KnowledgeFragment::getId() const +{ + return mId; +} diff --git a/ui.qt/src/KnowledgeFragment.hpp b/ui.qt/src/KnowledgeFragment.hpp new file mode 100644 index 0000000..9f4912d --- /dev/null +++ b/ui.qt/src/KnowledgeFragment.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "fwd.hpp" + +#include <QDateTime> +#include <cstddef> +#include <vector> + +struct KnowledgeId +{ + size_t id; +}; + +class KnowledgeFragment +{ +private: + QDateTime mCreateTime; + QDateTime mModifyTime; + KnowledgeId mId; + +public: + KnowledgeFragment(KnowledgeId id); + + KnowledgeId getId() const; +}; + +class KnowledgeDatabase +{ +private: + std::vector<KnowledgeFragment> mStorage; + std::vector<size_t> mIndex; // Mapping from KnowledgeId (index) to `storage` index + KnowledgeId mNextId; + +public: + KnowledgeId allocateFragment(); + bool deleteFragment(KnowledgeId id); + KnowledgeFragment* getFragment(KnowledgeId id); +}; diff --git a/ui.qt/src/fwd.hpp b/ui.qt/src/fwd.hpp new file mode 100644 index 0000000..14e0033 --- /dev/null +++ b/ui.qt/src/fwd.hpp @@ -0,0 +1,13 @@ +#pragma once + +// Document.hpp +class DocumentHandler; + +// Keyword.hpp +class Keyword; +class KeywordDatabase; + +// Knowledgefragment.cpp +struct KnowledgeId; +class KnowledgeFragment; +class KnowledgeDatabase; diff --git a/ui.qt/src/main.cpp b/ui.qt/src/main.cpp new file mode 100644 index 0000000..e8af4aa --- /dev/null +++ b/ui.qt/src/main.cpp @@ -0,0 +1,35 @@ +#include <QApplication> +#include <QLocale> +#include <QQmlApplicationEngine> +#include <QTranslator> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QTranslator translator; + 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; + QUrl url(u"qrc:/EpistmoolUI/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(); +} |