aboutsummaryrefslogtreecommitdiff
path: root/xT/xTq.h
diff options
context:
space:
mode:
Diffstat (limited to 'xT/xTq.h')
-rw-r--r--xT/xTq.h224
1 files changed, 223 insertions, 1 deletions
diff --git a/xT/xTq.h b/xT/xTq.h
index 70a0374..eec79b0 100644
--- a/xT/xTq.h
+++ b/xT/xTq.h
@@ -1,15 +1,237 @@
#ifndef XTQ_H
#define XTQ_H
+#include <cstdint>
+#include <cstddef>
+#include <functional>
+#include <map>
+#include <string>
+#include <vector>
+
+#include <QAbstractListModel>
+#include <QColor>
+#include <QHash>
+#include <QObject>
+#include <QString>
#include <QTcpSocket>
+#include <QTextCharFormat>
+#include <QTimer>
+#include <QVariant>
#include <QtQmlIntegration/qqmlintegration.h>
+#include <QQuickTextDocument>
+
+namespace Relay {
+ struct CommandData;
+ struct EventMessage;
+ struct ResponseData;
+ enum struct ServerState : int8_t;
+ enum struct BufferKind : int8_t;
+ enum struct Rendition : int8_t;
+ struct ItemData;
+}
+
+// --- Data structures ---------------------------------------------------------
+
+struct Server {
+ Relay::ServerState state = {};
+ QString user;
+ QString user_modes;
+};
+
+struct BufferLineItem {
+ QTextCharFormat format = {};
+ QString text;
+};
+
+struct BufferLine {
+ /// Leaked from another buffer, but temporarily staying in another one.
+ bool leaked = {};
+
+ bool is_unimportant = {};
+ bool is_highlight = {};
+ Relay::Rendition rendition = {};
+ uint64_t when = {};
+ std::vector<BufferLineItem> items;
+};
+
+struct Buffer {
+ QString buffer_name;
+ bool hide_unimportant = {};
+ Relay::BufferKind kind = {};
+ QString server_name;
+ std::vector<BufferLine> lines;
+
+ // Channel:
+
+ std::vector<BufferLineItem> topic;
+ QString modes;
+
+ // Stats:
+
+ uint32_t new_messages = {};
+ uint32_t new_unimportant_messages = {};
+ bool highlighted = {};
+
+ // Input:
+
+ // The input is stored as rich text.
+ QString input;
+ int input_start = {};
+ int input_end = {};
+ std::vector<QString> history;
+ size_t history_at = {};
+};
+
+using Callback = std::function<
+ void(std::wstring error, const Relay::ResponseData *response)>;
+
+// --- Buffer list model -------------------------------------------------------
+
+class BufferListModel : public QAbstractListModel {
+ Q_OBJECT
+ QML_ELEMENT
+
+public:
+ enum Roles {
+ BufferNameRole = Qt::UserRole + 1,
+ BufferKindRole,
+ ServerNameRole,
+ NewMessagesRole,
+ HighlightedRole,
+ DisplayTextRole,
+ IsBoldRole,
+ HighlightColorRole
+ };
+
+ explicit BufferListModel(QObject *parent = nullptr);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ QHash<int, QByteArray> roleNames() const override;
+
+ void setBuffers(const std::vector<Buffer> *buffers);
+ void setCurrentBuffer(const QString &current);
+ Q_INVOKABLE int getCurrentBufferIndex() const;
+ void refresh();
+ void bufferAdded(int index);
+ void bufferRemoved(int index);
+
+signals:
+ void bufferActivated(const QString &bufferName);
+
+private:
+ const std::vector<Buffer> *buffers_ = nullptr;
+ QString current;
+};
+
+// --- Main relay connection ---------------------------------------------------
+
class RelayConnection : public QObject {
Q_OBJECT
QML_ELEMENT
+ Q_PROPERTY(QString host
+ READ host WRITE setHost NOTIFY hostChanged)
+ Q_PROPERTY(QString port
+ READ port WRITE setPort NOTIFY portChanged)
+ Q_PROPERTY(bool connected
+ READ isConnected NOTIFY connectedChanged)
+ Q_PROPERTY(QString currentBuffer
+ READ currentBuffer NOTIFY currentBufferChanged)
+ Q_PROPERTY(QString prompt
+ READ prompt NOTIFY promptChanged)
+ Q_PROPERTY(QString status
+ READ status NOTIFY statusChanged)
+ Q_PROPERTY(QString topic
+ READ topic NOTIFY topicChanged)
+ Q_PROPERTY(BufferListModel *bufferListModel
+ READ bufferListModel CONSTANT)
+
public:
- QTcpSocket *socket; ///< Buffered relay socket
+ explicit RelayConnection(QObject *parent = nullptr);
+
+ QString host() const { return host_; }
+ void setHost(const QString &host);
+
+ QString port() const { return port_; }
+ void setPort(const QString &port);
+
+ bool isConnected() const;
+
+ QString currentBuffer() const { return buffer_current; }
+ QString prompt() const;
+ QString status() const;
+ QString topic() const;
+
+ BufferListModel *bufferListModel() { return &buffer_list_model; }
+
+ Q_INVOKABLE void connectToRelay();
+ Q_INVOKABLE void disconnectFromRelay();
+ Q_INVOKABLE void activateBuffer(const QString &name);
+ Q_INVOKABLE void activatePreviousBuffer();
+ Q_INVOKABLE void activateNextBuffer();
+ Q_INVOKABLE void toggleUnimportant();
+ Q_INVOKABLE void sendInput(const QString &input);
+ Q_INVOKABLE void populateBufferDocument(QQuickTextDocument *document);
+ Q_INVOKABLE QString getInputHistoryUp();
+ Q_INVOKABLE QString getInputHistoryDown();
+ Q_INVOKABLE void requestCompletion(const QString &text, int position);
+ Q_INVOKABLE void activateLastBuffer();
+ Q_INVOKABLE void activateNextHighlighted();
+ Q_INVOKABLE void activateNextWithActivity();
+ Q_INVOKABLE void toggleBufferLog();
+ Q_INVOKABLE void saveBufferInput(
+ const QString &bufferName, const QString &input, int start, int end);
+ Q_INVOKABLE QString getBufferInput();
+ Q_INVOKABLE int getBufferInputStart();
+ Q_INVOKABLE int getBufferInputEnd();
+
+signals:
+ void hostChanged();
+ void portChanged();
+ void connectedChanged();
+ void aboutToChangeBuffer(const QString &oldBuffer);
+ void currentBufferChanged();
+ void promptChanged();
+ void statusChanged();
+ void topicChanged();
+ void iconChanged(); // TODO
+ void errorOccurred(const QString &message);
+ void beepRequested();
+ void completionResult(const QString &completion);
+ void bufferTextChanged();
+ void logViewChanged(const QString &logText);
+
+private slots:
+ void onSocketConnected();
+ void onSocketDisconnected();
+ void onSocketReadyRead();
+ void onSocketError(QAbstractSocket::SocketError error);
+
+private:
+ void relaySend(Relay::CommandData *data, Callback callback = {});
+ void relayProcessMessage(const Relay::EventMessage &m);
+
+ Buffer *bufferByName(const QString &name);
+ void refreshIcon();
+ void recheckHighlighted();
+
+ QTcpSocket *socket;
+ QString host_;
+ QString port_;
+
+ uint32_t command_seq = 0;
+ std::map<uint32_t, Callback> command_callbacks;
+
+ std::vector<Buffer> buffers;
+ QString buffer_current;
+ QString buffer_last;
+ std::map<QString, Server> servers;
+
+ BufferListModel buffer_list_model;
+
+ QTimer *date_change_timer;
};
#endif // XTQ_H