From dd655c9679adc3be4a4215d63add761635c7bb64 Mon Sep 17 00:00:00 2001 From: talksik Date: Fri, 6 Feb 2026 13:04:16 -0800 Subject: [PATCH] feat: create text particles in a stream --- CMakeLists.txt | 2 ++ src/MainWindow.cpp | 45 ++++++++++++++++++++++++++++++++++++++++- src/MainWindow.h | 5 +++++ src/mainwindow.ui | 6 +++--- src/textinputdialog.cpp | 28 +++++++++++++++++++++++++ src/textinputdialog.h | 29 ++++++++++++++++++++++++++ 6 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 src/textinputdialog.cpp create mode 100644 src/textinputdialog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ffc361c..b021283 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ qt_add_executable(llink src/networkstreammodel.cpp src/particlelistmodel.h src/particlelistmodel.cpp + src/textinputdialog.h + src/textinputdialog.cpp ) qt_add_resources(llink diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index d42b216..3466d56 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -6,23 +6,28 @@ #include "authdialog.h" #include "authmanager.h" #include "settingsdialog.h" +#include "textinputdialog.h" #include "ui_mainwindow.h" #include #include #include #include #include +#include #include #include +#include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_trayIcon(nullptr), m_authManager(new AuthManager(this)), m_settingsDialog(nullptr), m_authDialog(nullptr), m_store(nullptr), m_networkStreamModel(nullptr), m_particleListModel(nullptr), - m_selectedParticleRow(-1), m_isDragging(false) + m_selectedParticleRow(-1), m_isDragging(false), m_textInputDialog(nullptr) { m_authDialog = new AuthDialog(this); + m_textInputDialog = new TextInputDialog(this); + connect(m_textInputDialog, &TextInputDialog::textSubmitted, this, &MainWindow::onTextMessageSubmitted); ui = new Ui::MainWindow; ui->setupUi(this); @@ -102,6 +107,9 @@ MainWindow::MainWindow(QWidget *parent) ui->topLevelParticlesView->expandAll(); }); + // DocumentSend toolbar button opens text input dialog + connect(ui->toolButton_3, &QToolButton::clicked, this, &MainWindow::showTextInputDialog); + m_authManager->tryRestoreSession(); setupTrayIcon(); @@ -181,6 +189,9 @@ void MainWindow::setupModels() connect(ui->particlesView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MainWindow::onParticleSelectionChanged); + // Install event filter to capture key presses from child views + ui->topLevelParticlesView->installEventFilter(this); + ui->particlesView->installEventFilter(this); } void MainWindow::onTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) @@ -376,6 +387,38 @@ void MainWindow::updatePingIndicator() m_pingLabel->setText("connected " + QString::number(currentPing) + "ms"); } +void MainWindow::showTextInputDialog() +{ + if (m_selectedStreamId.isEmpty()) + return; + + m_textInputDialog->show(); + m_textInputDialog->raise(); + m_textInputDialog->activateWindow(); +} + +bool MainWindow::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) + { + auto *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_T && keyEvent->modifiers() == Qt::NoModifier && !m_selectedStreamId.isEmpty()) + { + showTextInputDialog(); + return true; + } + } + return QMainWindow::eventFilter(obj, event); +} + +void MainWindow::onTextMessageSubmitted(const QString &text) +{ + if (m_selectedStreamId.isEmpty()) + return; + + m_store->createParticle(m_selectedStreamId, "text", {{"content", text}}); +} + void MainWindow::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) diff --git a/src/MainWindow.h b/src/MainWindow.h index 122cddc..8385f46 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -19,6 +19,7 @@ QT_END_NAMESPACE class AuthDialog; class SettingsDialog; +class TextInputDialog; namespace Ui { @@ -41,8 +42,10 @@ private slots: void onTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void onParticleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + void onTextMessageSubmitted(const QString &text); protected: + bool eventFilter(QObject *obj, QEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; @@ -58,12 +61,14 @@ private: AuthDialog *m_authDialog; SettingsDialog *m_settingsDialog; + TextInputDialog *m_textInputDialog; // Data and models Store *m_store; NetworkStreamModel *m_networkStreamModel; ParticleListModel *m_particleListModel; + void showTextInputDialog(); void updateStatusBar(); void updatePingIndicator(); QString m_selectedParticleId; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index bce7b20..1ffc0a2 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -247,7 +247,7 @@ 1 - asdfasdf + true @@ -282,7 +282,7 @@ - mike@inra.com + Qt::AlignmentFlag::AlignCenter @@ -292,7 +292,7 @@ - acked by: arthur, ed, sam + Qt::AlignmentFlag::AlignCenter diff --git a/src/textinputdialog.cpp b/src/textinputdialog.cpp new file mode 100644 index 0000000..f61e4b2 --- /dev/null +++ b/src/textinputdialog.cpp @@ -0,0 +1,28 @@ +#include "textinputdialog.h" +#include +#include +#include + +TextInputDialog::TextInputDialog(QWidget *parent) + : QDialog(parent), m_lineEdit(new QLineEdit(this)), m_sendButton(new QPushButton("Send", this)) +{ + setWindowTitle("Send Text Message"); + + auto *layout = new QVBoxLayout(this); + layout->addWidget(m_lineEdit); + layout->addWidget(m_sendButton); + + connect(m_lineEdit, &QLineEdit::returnPressed, this, &TextInputDialog::onSubmit); + connect(m_sendButton, &QPushButton::clicked, this, &TextInputDialog::onSubmit); +} + +void TextInputDialog::onSubmit() +{ + QString text = m_lineEdit->text().trimmed(); + if (text.isEmpty()) + return; + + emit textSubmitted(text); + m_lineEdit->clear(); + hide(); +} diff --git a/src/textinputdialog.h b/src/textinputdialog.h new file mode 100644 index 0000000..882ec17 --- /dev/null +++ b/src/textinputdialog.h @@ -0,0 +1,29 @@ +#ifndef TEXTINPUTDIALOG_H +#define TEXTINPUTDIALOG_H + +#include + +QT_BEGIN_NAMESPACE +class QLineEdit; +class QPushButton; +QT_END_NAMESPACE + +class TextInputDialog : public QDialog +{ + Q_OBJECT + +public: + explicit TextInputDialog(QWidget *parent = nullptr); + +signals: + void textSubmitted(const QString &text); + +private slots: + void onSubmit(); + +private: + QLineEdit *m_lineEdit; + QPushButton *m_sendButton; +}; + +#endif // TEXTINPUTDIALOG_H