diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7e68db77..52527312 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -299,7 +299,6 @@ set(SRC_FILES
src/SSOHandler.cpp
src/SideBarActions.cpp
src/Splitter.cpp
- src/TextInputWidget.cpp
src/TrayIcon.cpp
src/UserInfoWidget.cpp
src/UserSettingsPage.cpp
@@ -505,7 +504,6 @@ qt5_wrap_cpp(MOC_HEADERS
src/SSOHandler.h
src/SideBarActions.h
src/Splitter.h
- src/TextInputWidget.h
src/TrayIcon.h
src/UserInfoWidget.h
src/UserSettingsPage.h
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 1b235a95..1fd9b9bc 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -39,7 +39,6 @@
#include "RoomList.h"
#include "SideBarActions.h"
#include "Splitter.h"
-#include "TextInputWidget.h"
#include "UserInfoWidget.h"
#include "UserSettingsPage.h"
#include "Utils.h"
@@ -138,18 +137,13 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
splitter->addWidget(content_);
splitter->restoreSizes(parent->width());
- text_input_ = new TextInputWidget(this);
- contentLayout_->addWidget(text_input_);
-
connect(this, &ChatPage::connectionLost, this, [this]() {
nhlog::net()->info("connectivity lost");
isConnected_ = false;
http::client()->shutdown();
- text_input_->disableInput();
});
connect(this, &ChatPage::connectionRestored, this, [this]() {
nhlog::net()->info("trying to re-connect");
- text_input_->enableInput();
isConnected_ = true;
// Drop all pending connections.
@@ -573,7 +567,6 @@ ChatPage::showQuickSwitcher()
connect(dialog, &QuickSwitcher::roomSelected, room_list_, &RoomList::highlightSelectedRoom);
connect(dialog, &QuickSwitcher::closing, this, [this]() {
MainWindow::instance()->hideOverlay();
- text_input_->setFocus(Qt::FocusReason::PopupFocusReason);
});
MainWindow::instance()->showTransparentOverlayModal(dialog);
diff --git a/src/ChatPage.h b/src/ChatPage.h
index 37abafa0..273ba4af 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -46,7 +46,6 @@ class QuickSwitcher;
class RoomList;
class SideBarActions;
class Splitter;
-class TextInputWidget;
class TimelineViewManager;
class UserInfoWidget;
class UserSettings;
@@ -251,8 +250,6 @@ private:
TimelineViewManager *view_manager_;
SideBarActions *sidebarActions_;
- TextInputWidget *text_input_;
-
QTimer connectivityTimer_;
std::atomic_bool isConnected_;
diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp
deleted file mode 100644
index 6d1fdc7a..00000000
--- a/src/TextInputWidget.cpp
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <QAbstractItemView>
-#include <QAbstractTextDocumentLayout>
-#include <QBuffer>
-#include <QClipboard>
-#include <QCompleter>
-#include <QFileDialog>
-#include <QMimeData>
-#include <QMimeDatabase>
-#include <QMimeType>
-#include <QPainter>
-#include <QStyleOption>
-#include <QtConcurrent>
-
-#include "Cache.h"
-#include "ChatPage.h"
-#include "CompletionModelRoles.h"
-#include "CompletionProxyModel.h"
-#include "Logging.h"
-#include "TextInputWidget.h"
-#include "Utils.h"
-#include "emoji/EmojiSearchModel.h"
-#include "emoji/Provider.h"
-#include "ui/FlatButton.h"
-#include "ui/LoadingIndicator.h"
-
-#if defined(Q_OS_MAC)
-#include "emoji/MacHelper.h"
-#endif
-
-static constexpr size_t INPUT_HISTORY_SIZE = 127;
-static constexpr int MAX_TEXTINPUT_HEIGHT = 120;
-static constexpr int ButtonHeight = 22;
-
-FilteredTextEdit::FilteredTextEdit(QWidget *parent)
- : QTextEdit{parent}
- , history_index_{0}
- , suggestionsPopup_{parent}
- , previewDialog_{parent}
-{
- setFrameStyle(QFrame::NoFrame);
- connect(document()->documentLayout(),
- &QAbstractTextDocumentLayout::documentSizeChanged,
- this,
- &FilteredTextEdit::updateGeometry);
- connect(document()->documentLayout(),
- &QAbstractTextDocumentLayout::documentSizeChanged,
- this,
- [this]() { emit heightChanged(document()->size().toSize().height()); });
- working_history_.push_back("");
- connect(this, &QTextEdit::textChanged, this, &FilteredTextEdit::textChanged);
- setAcceptRichText(false);
-
- completer_ = new QCompleter(this);
- completer_->setWidget(this);
- auto model = new emoji::EmojiSearchModel(this);
- model->sort(0, Qt::AscendingOrder);
- completer_->setModel((emoji_completion_model_ = new CompletionProxyModel(model, this)));
- emoji_completion_model_->setFilterRole(CompletionModel::SearchRole);
- completer_->setModelSorting(QCompleter::UnsortedModel);
- completer_->popup()->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- completer_->popup()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-
- connect(completer_,
- QOverload<const QModelIndex &>::of(&QCompleter::activated),
- [this](auto &index) {
- emoji_popup_open_ = false;
- auto text = index.data(CompletionModel::CompletionRole).toString();
- insertCompletion(text);
- });
-
- connect(this, &FilteredTextEdit::resultsRetrieved, this, &FilteredTextEdit::showResults);
- connect(
- &suggestionsPopup_, &SuggestionsPopup::itemSelected, this, [this](const QString &text) {
- suggestionsPopup_.hide();
-
- auto cursor = textCursor();
- const int end = cursor.position();
-
- cursor.setPosition(atTriggerPosition_, QTextCursor::MoveAnchor);
- cursor.setPosition(end, QTextCursor::KeepAnchor);
- cursor.removeSelectedText();
- cursor.insertText(text);
- });
-
- // For cycling through the suggestions by hitting tab.
- connect(this,
- &FilteredTextEdit::selectNextSuggestion,
- &suggestionsPopup_,
- &SuggestionsPopup::selectNextSuggestion);
- connect(this,
- &FilteredTextEdit::selectPreviousSuggestion,
- &suggestionsPopup_,
- &SuggestionsPopup::selectPreviousSuggestion);
- connect(this, &FilteredTextEdit::selectHoveredSuggestion, this, [this]() {
- suggestionsPopup_.selectHoveredSuggestion<UserItem>();
- });
-
- previewDialog_.hide();
-}
-
-void
-FilteredTextEdit::insertCompletion(QString completion)
-{
- // Paint the current word and replace it with 'completion'
- auto cur_text = textAfterPosition(trigger_pos_);
- auto tc = textCursor();
- tc.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, cur_text.length());
- tc.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, cur_text.length());
- tc.insertText(completion);
- setTextCursor(tc);
-}
-
-void
-FilteredTextEdit::showResults(const std::vector<SearchResult> &results)
-{
- QPoint pos;
-
- if (isAnchorValid()) {
- auto cursor = textCursor();
- cursor.setPosition(atTriggerPosition_);
- pos = viewport()->mapToGlobal(cursorRect(cursor).topLeft());
- } else {
- auto rect = cursorRect();
- pos = viewport()->mapToGlobal(rect.topLeft());
- }
-
- suggestionsPopup_.addUsers(results);
- suggestionsPopup_.move(pos.x(), pos.y() - suggestionsPopup_.height() - 10);
- suggestionsPopup_.show();
-}
-
-void
-FilteredTextEdit::keyPressEvent(QKeyEvent *event)
-{
- const bool isModifier = (event->modifiers() != Qt::NoModifier);
-
-#if defined(Q_OS_MAC)
- if (event->modifiers() == (Qt::ControlModifier | Qt::MetaModifier) &&
- event->key() == Qt::Key_Space)
- MacHelper::showEmojiWindow();
-#endif
-
- if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_U)
- QTextEdit::setText("");
-
- // calculate the new query
- if (textCursor().position() < atTriggerPosition_ || !isAnchorValid()) {
- resetAnchor();
- closeSuggestions();
- }
-
- if (suggestionsPopup_.isVisible()) {
- switch (event->key()) {
- case Qt::Key_Down:
- case Qt::Key_Tab:
- emit selectNextSuggestion();
- return;
- case Qt::Key_Enter:
- case Qt::Key_Return:
- emit selectHoveredSuggestion();
- return;
- case Qt::Key_Escape:
- closeSuggestions();
- return;
- case Qt::Key_Up:
- case Qt::Key_Backtab: {
- emit selectPreviousSuggestion();
- return;
- }
- default:
- break;
- }
- }
-
- if (emoji_popup_open_) {
- auto fake_key = (event->key() == Qt::Key_Backtab) ? Qt::Key_Up : Qt::Key_Down;
- switch (event->key()) {
- case Qt::Key_Backtab:
- case Qt::Key_Tab: {
- // Simulate up/down arrow press
- auto ev = new QKeyEvent(QEvent::KeyPress, fake_key, Qt::NoModifier);
- QCoreApplication::postEvent(completer_->popup(), ev);
- return;
- }
- default:
- break;
- }
- }
-
- switch (event->key()) {
- case Qt::Key_At:
- atTriggerPosition_ = textCursor().position();
- anchorType_ = AnchorType::Sigil;
-
- QTextEdit::keyPressEvent(event);
- break;
- case Qt::Key_Tab: {
- auto cursor = textCursor();
- const int initialPos = cursor.position();
-
- cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
- auto word = cursor.selectedText();
-
- const int startOfWord = cursor.position();
-
- // There is a word to complete.
- if (initialPos != startOfWord) {
- atTriggerPosition_ = startOfWord;
- anchorType_ = AnchorType::Tab;
-
- emit showSuggestions(word);
- } else {
- QTextEdit::keyPressEvent(event);
- }
-
- break;
- }
- case Qt::Key_Colon: {
- QTextEdit::keyPressEvent(event);
- trigger_pos_ = textCursor().position() - 1;
- emoji_completion_model_->setFilterRegExp("");
- emoji_popup_open_ = true;
- break;
- }
- case Qt::Key_Return:
- case Qt::Key_Enter:
- if (emoji_popup_open_) {
- if (!completer_->popup()->currentIndex().isValid()) {
- // No completion to select, do normal behavior
- completer_->popup()->hide();
- emoji_popup_open_ = false;
- } else {
- event->ignore();
- return;
- }
- }
-
- if (!(event->modifiers() & Qt::ShiftModifier)) {
- submit();
- } else {
- QTextEdit::keyPressEvent(event);
- }
- break;
- case Qt::Key_Up: {
- auto initial_cursor = textCursor();
- QTextEdit::keyPressEvent(event);
-
- if (textCursor() == initial_cursor && textCursor().atStart() &&
- history_index_ + 1 < working_history_.size()) {
- ++history_index_;
- setPlainText(working_history_[history_index_]);
- moveCursor(QTextCursor::End);
- } else if (textCursor() == initial_cursor) {
- // Move to the start of the text if there aren't any lines to move up to.
- initial_cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor, 1);
- setTextCursor(initial_cursor);
- }
-
- break;
- }
- case Qt::Key_Down: {
- auto initial_cursor = textCursor();
- QTextEdit::keyPressEvent(event);
-
- if (textCursor() == initial_cursor && textCursor().atEnd() && history_index_ > 0) {
- --history_index_;
- setPlainText(working_history_[history_index_]);
- moveCursor(QTextCursor::End);
- } else if (textCursor() == initial_cursor) {
- // Move to the end of the text if there aren't any lines to move down to.
- initial_cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor, 1);
- setTextCursor(initial_cursor);
- }
-
- break;
- }
- default:
- QTextEdit::keyPressEvent(event);
-
- if (isModifier)
- return;
-
- if (emoji_popup_open_ && textAfterPosition(trigger_pos_).length() > 2) {
- // Update completion
- // Don't include the trigger token in the search
- emoji_completion_model_->setFilterWildcard(
- textAfterPosition(trigger_pos_).remove(0, 1));
- completer_->complete(completerRect());
- }
-
- if (emoji_popup_open_ && (completer_->completionCount() < 1 ||
- !textAfterPosition(trigger_pos_)
- .contains(QRegularExpression(":[^\r\n\t\f\v :]+$")))) {
- // No completions for this word or another word than the completer was
- // started with
- emoji_popup_open_ = false;
- completer_->popup()->hide();
- }
-
- if (textCursor().position() == 0) {
- resetAnchor();
- closeSuggestions();
- return;
- }
-
- // Check if the current word should be autocompleted.
- auto cursor = textCursor();
- cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
- auto word = cursor.selectedText();
-
- if (hasAnchor(cursor.position(), anchorType_) && isAnchorValid()) {
- if (word.isEmpty()) {
- closeSuggestions();
- return;
- }
-
- emit showSuggestions(word);
- } else {
- resetAnchor();
- closeSuggestions();
- }
-
- break;
- }
-}
-
-QRect
-FilteredTextEdit::completerRect()
-{
- // Move left edge to the beginning of the word
- auto cursor = textCursor();
- auto rect = cursorRect();
- cursor.movePosition(
- QTextCursor::Left, QTextCursor::MoveAnchor, textAfterPosition(trigger_pos_).length());
- auto cursor_global_x = viewport()->mapToGlobal(cursorRect(cursor).topLeft()).x();
- auto rect_global_left = viewport()->mapToGlobal(rect.bottomLeft()).x();
- auto dx = qAbs(rect_global_left - cursor_global_x);
- rect.moveLeft(rect.left() - dx);
-
- auto item_height = completer_->popup()->sizeHintForRow(0);
- auto max_height = item_height * completer_->maxVisibleItems();
- auto height = (completer_->completionCount() > completer_->maxVisibleItems())
- ? max_height
- : completer_->completionCount() * item_height;
- rect.setWidth(completer_->popup()->sizeHintForColumn(0));
- rect.moveBottom(-height);
- return rect;
-}
-
-QSize
-FilteredTextEdit::sizeHint() const
-{
- ensurePolished();
- auto margins = viewportMargins();
- margins += document()->documentMargin();
- QSize size = document()->size().toSize();
- size.rwidth() += margins.left() + margins.right();
- size.rheight() += margins.top() + margins.bottom();
- return size;
-}
-
-QSize
-FilteredTextEdit::minimumSizeHint() const
-{
- ensurePolished();
- auto margins = viewportMargins();
- margins += document()->documentMargin();
- margins += contentsMargins();
- QSize size(fontMetrics().averageCharWidth() * 10,
- fontMetrics().lineSpacing() + margins.top() + margins.bottom());
- return size;
-}
-
-void
-FilteredTextEdit::submit()
-{}
-
-void
-FilteredTextEdit::textChanged()
-{
- working_history_[history_index_] = toPlainText();
-}
-
-TextInputWidget::TextInputWidget(QWidget *parent)
- : QWidget(parent)
-{
- QFont f;
- f.setPointSizeF(f.pointSizeF());
- const int fontHeight = QFontMetrics(f).height();
- const int contentHeight = static_cast<int>(fontHeight * 2.5);
- const int InputHeight = static_cast<int>(fontHeight * 1.5);
-
- setFixedHeight(contentHeight);
- setCursor(Qt::ArrowCursor);
-
- topLayout_ = new QHBoxLayout();
- topLayout_->setSpacing(0);
- topLayout_->setContentsMargins(13, 1, 13, 0);
-
- QIcon send_file_icon;
- send_file_icon.addFile(":/icons/icons/ui/paper-clip-outline.png");
-
- sendFileBtn_ = new FlatButton(this);
- sendFileBtn_->setToolTip(tr("Send a file"));
- sendFileBtn_->setIcon(send_file_icon);
- sendFileBtn_->setIconSize(QSize(ButtonHeight, ButtonHeight));
-
- spinner_ = new LoadingIndicator(this);
- spinner_->setFixedHeight(InputHeight);
- spinner_->setFixedWidth(InputHeight);
- spinner_->setObjectName("FileUploadSpinner");
- spinner_->hide();
-
- input_ = new FilteredTextEdit(this);
- input_->setFixedHeight(InputHeight);
- input_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- input_->setPlaceholderText(tr("Write a message..."));
-
- connect(input_,
- &FilteredTextEdit::heightChanged,
- this,
- [this, InputHeight, contentHeight](int height) {
- int widgetHeight =
- std::min(MAX_TEXTINPUT_HEIGHT, std::max(height, contentHeight));
- int textInputHeight =
- std::min(widgetHeight - 1, std::max(height, InputHeight));
-
- setFixedHeight(widgetHeight);
- input_->setFixedHeight(textInputHeight);
-
- emit heightChanged(widgetHeight);
- });
- connect(input_, &FilteredTextEdit::showSuggestions, this, [this](const QString &q) {
- if (q.isEmpty())
- return;
-
- QtConcurrent::run([this, q = q.toLower().toStdString()]() {
- try {
- emit input_->resultsRetrieved(cache::searchUsers(
- ChatPage::instance()->currentRoom().toStdString(), q));
- } catch (const lmdb::error &e) {
- nhlog::db()->error("Suggestion retrieval failed: {}", e.what());
- }
- });
- });
-
- sendMessageBtn_ = new FlatButton(this);
- sendMessageBtn_->setToolTip(tr("Send a message"));
-
- QIcon send_message_icon;
- send_message_icon.addFile(":/icons/icons/ui/cursor.png");
- sendMessageBtn_->setIcon(send_message_icon);
- sendMessageBtn_->setIconSize(QSize(ButtonHeight, ButtonHeight));
-
- topLayout_->addWidget(sendFileBtn_);
- topLayout_->addWidget(input_);
- topLayout_->addWidget(sendMessageBtn_);
-
- setLayout(topLayout_);
-
- connect(sendMessageBtn_, &FlatButton::clicked, input_, &FilteredTextEdit::submit);
- connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection()));
-}
-
-void
-TextInputWidget::focusInEvent(QFocusEvent *event)
-{
- input_->setFocus(event->reason());
-}
-
-void
-TextInputWidget::paintEvent(QPaintEvent *)
-{
- QStyleOption opt;
- opt.init(this);
- QPainter p(this);
-
- style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
-}
diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h
deleted file mode 100644
index 19462f70..00000000
--- a/src/TextInputWidget.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include <deque>
-#include <optional>
-
-#include <QCoreApplication>
-#include <QHBoxLayout>
-#include <QPaintEvent>
-#include <QTextEdit>
-#include <QWidget>
-
-#include "dialogs/PreviewUploadOverlay.h"
-#include "popups/SuggestionsPopup.h"
-
-struct SearchResult;
-
-class CompletionProxyModel;
-class FlatButton;
-class LoadingIndicator;
-class QCompleter;
-
-class FilteredTextEdit : public QTextEdit
-{
- Q_OBJECT
-
-public:
- explicit FilteredTextEdit(QWidget *parent = nullptr);
-
- QSize sizeHint() const override;
- QSize minimumSizeHint() const override;
-
- void submit();
-
-signals:
- void heightChanged(int height);
- void startedUpload();
-
- //! Trigger the suggestion popup.
- void showSuggestions(const QString &query);
- void resultsRetrieved(const std::vector<SearchResult> &results);
- void selectNextSuggestion();
- void selectPreviousSuggestion();
- void selectHoveredSuggestion();
-
-public slots:
- void showResults(const std::vector<SearchResult> &results);
-
-protected:
- void keyPressEvent(QKeyEvent *event) override;
- void focusOutEvent(QFocusEvent *event) override
- {
- suggestionsPopup_.hide();
- QTextEdit::focusOutEvent(event);
- }
-
-private:
- bool emoji_popup_open_ = false;
- CompletionProxyModel *emoji_completion_model_;
- std::deque<QString> true_history_, working_history_;
- int trigger_pos_; // Where emoji completer was triggered
- size_t history_index_;
- QCompleter *completer_;
-
- SuggestionsPopup suggestionsPopup_;
-
- enum class AnchorType
- {
- Tab = 0,
- Sigil = 1,
- };
-
- AnchorType anchorType_ = AnchorType::Sigil;
-
- int anchorWidth(AnchorType anchor) { return static_cast<int>(anchor); }
-
- void closeSuggestions() { suggestionsPopup_.hide(); }
- void resetAnchor() { atTriggerPosition_ = -1; }
- bool isAnchorValid() { return atTriggerPosition_ != -1; }
- bool hasAnchor(int pos, AnchorType anchor)
- {
- return pos == atTriggerPosition_ + anchorWidth(anchor);
- }
- QRect completerRect();
- QString query()
- {
- auto cursor = textCursor();
- cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
- return cursor.selectedText();
- }
- QString textAfterPosition(int pos)
- {
- auto tc = textCursor();
- tc.setPosition(pos);
- tc.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
- return tc.selectedText();
- }
-
- dialogs::PreviewUploadOverlay previewDialog_;
-
- //! Latest position of the '@' character that triggers the username completer.
- int atTriggerPosition_ = -1;
-
- void insertCompletion(QString completion);
- void textChanged();
- void afterCompletion(int);
-};
-
-class TextInputWidget : public QWidget
-{
- Q_OBJECT
-
- Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor)
-
-public:
- TextInputWidget(QWidget *parent = nullptr);
-
- QColor borderColor() const { return borderColor_; }
- void setBorderColor(QColor &color) { borderColor_ = color; }
- void disableInput()
- {
- input_->setEnabled(false);
- input_->setPlaceholderText(tr("Connection lost. Nheko is trying to re-connect..."));
- }
- void enableInput()
- {
- input_->setEnabled(true);
- input_->setPlaceholderText(tr("Write a message..."));
- }
-
-public slots:
- void focusLineEdit() { input_->setFocus(); }
-
-signals:
- void heightChanged(int height);
-
- void sendJoinRoomRequest(const QString &room);
- void sendInviteRoomRequest(const QString &userid, const QString &reason);
- void sendKickRoomRequest(const QString &userid, const QString &reason);
- void sendBanRoomRequest(const QString &userid, const QString &reason);
- void sendUnbanRoomRequest(const QString &userid, const QString &reason);
- void changeRoomNick(const QString &displayname);
-
-protected:
- void focusInEvent(QFocusEvent *event) override;
- void paintEvent(QPaintEvent *) override;
-
-private:
- QHBoxLayout *topLayout_;
- FilteredTextEdit *input_;
-
- LoadingIndicator *spinner_;
-
- FlatButton *sendFileBtn_;
- FlatButton *sendMessageBtn_;
- QColor borderColor_;
-};
|