From b9dde957a83c7198e9c5941c657e785577d11ed5 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Sun, 9 Jun 2019 19:03:18 -0400 Subject: Add initial support for rich replies to nheko --- src/TextInputWidget.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/TextInputWidget.h') diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 8f634f6b..a12183d8 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -54,6 +54,7 @@ public: QSize minimumSizeHint() const override; void submit(); + void setRelatedEvent(const QString &event) { related_event_ = event; } signals: void heightChanged(int height); @@ -61,6 +62,7 @@ signals: void stoppedTyping(); void startedUpload(); void message(QString); + void reply(QString, QString); void command(QString name, QString args); void image(QSharedPointer data, const QString &filename); void audio(QSharedPointer data, const QString &filename); @@ -94,6 +96,9 @@ private: SuggestionsPopup popup_; + // Used for replies + QString related_event_; + enum class AnchorType { Tab = 0, @@ -158,13 +163,14 @@ public slots: void openFileSelection(); void hideUploadSpinner(); void focusLineEdit() { input_->setFocus(); } - void addReply(const QString &username, const QString &msg); + void addReply(const QString &username, const QString &msg, const QString &related_event); private slots: void addSelectedEmoji(const QString &emoji); signals: void sendTextMessage(QString msg); + void sendReplyMessage(QString msg, QString event_id); void sendEmoteMessage(QString msg); void heightChanged(int height); @@ -189,6 +195,9 @@ private: QHBoxLayout *topLayout_; FilteredTextEdit *input_; + // Used for replies + QString related_event_; + LoadingIndicator *spinner_; FlatButton *sendFileBtn_; -- cgit 1.5.1 From 9159b9ce22efa4972792b5400fd384457c349caa Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Tue, 11 Jun 2019 21:04:30 -0400 Subject: Initial Support for Rich Replies Add placeholder UI for showing replies in the text entry widget. Existing quoting capability has been removed (Temporarily), as it was replaced with the new reply capability. Replies sent from nheko do not currently appear correctly in the timeline (this will be fixed in a future commit). --- CMakeLists.txt | 8 +- src/QuickSwitcher.cpp | 2 +- src/QuickSwitcher.h | 2 +- src/SuggestionsPopup.cpp | 296 ---------------------------------------- src/SuggestionsPopup.h | 147 -------------------- src/TextInputWidget.cpp | 74 +++++++--- src/TextInputWidget.h | 12 +- src/popups/PopupItem.cpp | 147 ++++++++++++++++++++ src/popups/PopupItem.h | 83 +++++++++++ src/popups/ReplyPopup.cpp | 60 ++++++++ src/popups/ReplyPopup.h | 32 +++++ src/popups/SuggestionsPopup.cpp | 156 +++++++++++++++++++++ src/popups/SuggestionsPopup.h | 76 +++++++++++ 13 files changed, 626 insertions(+), 469 deletions(-) delete mode 100644 src/SuggestionsPopup.cpp delete mode 100644 src/SuggestionsPopup.h create mode 100644 src/popups/PopupItem.cpp create mode 100644 src/popups/PopupItem.h create mode 100644 src/popups/ReplyPopup.cpp create mode 100644 src/popups/ReplyPopup.h create mode 100644 src/popups/SuggestionsPopup.cpp create mode 100644 src/popups/SuggestionsPopup.h (limited to 'src/TextInputWidget.h') diff --git a/CMakeLists.txt b/CMakeLists.txt index fda60b71..321234dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,7 +237,9 @@ set(SRC_FILES src/RunGuard.cpp src/SideBarActions.cpp src/Splitter.cpp - src/SuggestionsPopup.cpp + src/popups/SuggestionsPopup.cpp + src/popups/PopupItem.cpp + src/popups/ReplyPopup.cpp src/TextInputWidget.cpp src/TopRoomBar.cpp src/TrayIcon.cpp @@ -375,7 +377,9 @@ qt5_wrap_cpp(MOC_HEADERS src/RoomList.h src/SideBarActions.h src/Splitter.h - src/SuggestionsPopup.h + src/popups/SuggestionsPopup.h + src/popups/ReplyPopup.h + src/popups/PopupItem.h src/TextInputWidget.h src/TopRoomBar.h src/TrayIcon.h diff --git a/src/QuickSwitcher.cpp b/src/QuickSwitcher.cpp index eb79a427..f8f6c001 100644 --- a/src/QuickSwitcher.cpp +++ b/src/QuickSwitcher.cpp @@ -23,7 +23,7 @@ #include #include "QuickSwitcher.h" -#include "SuggestionsPopup.h" +#include "popups/SuggestionsPopup.h" RoomSearchInput::RoomSearchInput(QWidget *parent) : TextField(parent) diff --git a/src/QuickSwitcher.h b/src/QuickSwitcher.h index 24b9adfa..05f7be07 100644 --- a/src/QuickSwitcher.h +++ b/src/QuickSwitcher.h @@ -22,7 +22,7 @@ #include #include -#include "SuggestionsPopup.h" +#include "popups/SuggestionsPopup.h" #include "ui/TextField.h" Q_DECLARE_METATYPE(std::vector) diff --git a/src/SuggestionsPopup.cpp b/src/SuggestionsPopup.cpp deleted file mode 100644 index 952d2ef3..00000000 --- a/src/SuggestionsPopup.cpp +++ /dev/null @@ -1,296 +0,0 @@ -#include -#include -#include - -#include "Config.h" -#include "SuggestionsPopup.h" -#include "Utils.h" -#include "ui/Avatar.h" -#include "ui/DropShadow.h" - -constexpr int PopupHMargin = 4; -constexpr int PopupItemMargin = 3; - -PopupItem::PopupItem(QWidget *parent) - : QWidget(parent) - , avatar_{new Avatar(this)} - , hovering_{false} -{ - setMouseTracking(true); - setAttribute(Qt::WA_Hover); - - topLayout_ = new QHBoxLayout(this); - topLayout_->setContentsMargins( - PopupHMargin, PopupItemMargin, PopupHMargin, PopupItemMargin); - - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); -} - -void -PopupItem::paintEvent(QPaintEvent *) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - - if (underMouse() || hovering_) - p.fillRect(rect(), hoverColor_); -} - -UserItem::UserItem(QWidget *parent, const QString &user_id) - : PopupItem(parent) - , userId_{user_id} -{ - auto displayName = Cache::displayName(ChatPage::instance()->currentRoom(), userId_); - - avatar_->setSize(conf::popup::avatar); - avatar_->setLetter(utils::firstChar(displayName)); - - // If it's a matrix id we use the second letter. - if (displayName.size() > 1 && displayName.at(0) == '@') - avatar_->setLetter(QChar(displayName.at(1))); - - userName_ = new QLabel(displayName, this); - - topLayout_->addWidget(avatar_); - topLayout_->addWidget(userName_, 1); - - resolveAvatar(user_id); -} - -void -UserItem::updateItem(const QString &user_id) -{ - userId_ = user_id; - - auto displayName = Cache::displayName(ChatPage::instance()->currentRoom(), userId_); - - // If it's a matrix id we use the second letter. - if (displayName.size() > 1 && displayName.at(0) == '@') - avatar_->setLetter(QChar(displayName.at(1))); - else - avatar_->setLetter(utils::firstChar(displayName)); - - userName_->setText(displayName); - resolveAvatar(user_id); -} - -void -UserItem::resolveAvatar(const QString &user_id) -{ - AvatarProvider::resolve( - ChatPage::instance()->currentRoom(), userId_, this, [this, user_id](const QImage &img) { - // The user on the widget when the avatar is resolved, - // might be different from the user that made the call. - if (user_id == userId_) - avatar_->setImage(img); - else - // We try to resolve the avatar again. - resolveAvatar(userId_); - }); -} - -void -UserItem::mousePressEvent(QMouseEvent *event) -{ - if (event->buttons() != Qt::RightButton) - emit clicked( - Cache::displayName(ChatPage::instance()->currentRoom(), selectedText())); - - QWidget::mousePressEvent(event); -} - -RoomItem::RoomItem(QWidget *parent, const RoomSearchResult &res) - : PopupItem(parent) - , roomId_{QString::fromStdString(res.room_id)} -{ - auto name = QFontMetrics(QFont()).elidedText( - QString::fromStdString(res.info.name), Qt::ElideRight, parentWidget()->width() - 10); - - avatar_->setSize(conf::popup::avatar + 6); - avatar_->setLetter(utils::firstChar(name)); - - roomName_ = new QLabel(name, this); - roomName_->setMargin(0); - - topLayout_->addWidget(avatar_); - topLayout_->addWidget(roomName_, 1); - - if (!res.img.isNull()) - avatar_->setImage(res.img); -} - -void -RoomItem::updateItem(const RoomSearchResult &result) -{ - roomId_ = QString::fromStdString(std::move(result.room_id)); - - auto name = - QFontMetrics(QFont()).elidedText(QString::fromStdString(std::move(result.info.name)), - Qt::ElideRight, - parentWidget()->width() - 10); - - roomName_->setText(name); - - if (!result.img.isNull()) - avatar_->setImage(result.img); - else - avatar_->setLetter(utils::firstChar(name)); -} - -void -RoomItem::mousePressEvent(QMouseEvent *event) -{ - if (event->buttons() != Qt::RightButton) - emit clicked(selectedText()); - - QWidget::mousePressEvent(event); -} - -SuggestionsPopup::SuggestionsPopup(QWidget *parent) - : QWidget(parent) -{ - setAttribute(Qt::WA_ShowWithoutActivating, true); - setWindowFlags(Qt::ToolTip | Qt::NoDropShadowWindowHint); - - layout_ = new QVBoxLayout(this); - layout_->setMargin(0); - layout_->setSpacing(0); -} - -void -SuggestionsPopup::addRooms(const std::vector &rooms) -{ - if (rooms.empty()) { - hide(); - return; - } - - const size_t layoutCount = layout_->count(); - const size_t roomCount = rooms.size(); - - // Remove the extra widgets from the layout. - if (roomCount < layoutCount) - removeLayoutItemsAfter(roomCount - 1); - - for (size_t i = 0; i < roomCount; ++i) { - auto item = layout_->itemAt(i); - - // Create a new widget if there isn't already one in that - // layout position. - if (!item) { - auto room = new RoomItem(this, rooms.at(i)); - connect(room, &RoomItem::clicked, this, &SuggestionsPopup::itemSelected); - layout_->addWidget(room); - } else { - // Update the current widget with the new data. - auto room = qobject_cast(item->widget()); - if (room) - room->updateItem(rooms.at(i)); - } - } - - resetSelection(); - adjustSize(); - - resize(geometry().width(), 40 * rooms.size()); - - selectNextSuggestion(); -} - -void -SuggestionsPopup::addUsers(const QVector &users) -{ - if (users.isEmpty()) { - hide(); - return; - } - - const size_t layoutCount = layout_->count(); - const size_t userCount = users.size(); - - // Remove the extra widgets from the layout. - if (userCount < layoutCount) - removeLayoutItemsAfter(userCount - 1); - - for (size_t i = 0; i < userCount; ++i) { - auto item = layout_->itemAt(i); - - // Create a new widget if there isn't already one in that - // layout position. - if (!item) { - auto user = new UserItem(this, users.at(i).user_id); - connect(user, &UserItem::clicked, this, &SuggestionsPopup::itemSelected); - layout_->addWidget(user); - } else { - // Update the current widget with the new data. - auto userWidget = qobject_cast(item->widget()); - if (userWidget) - userWidget->updateItem(users.at(i).user_id); - } - } - - resetSelection(); - adjustSize(); - - selectNextSuggestion(); -} - -void -SuggestionsPopup::hoverSelection() -{ - resetHovering(); - setHovering(selectedItem_); - update(); -} - -void -SuggestionsPopup::selectNextSuggestion() -{ - selectedItem_++; - if (selectedItem_ >= layout_->count()) - selectFirstItem(); - - hoverSelection(); -} - -void -SuggestionsPopup::selectPreviousSuggestion() -{ - selectedItem_--; - if (selectedItem_ < 0) - selectLastItem(); - - hoverSelection(); -} - -void -SuggestionsPopup::resetHovering() -{ - for (int i = 0; i < layout_->count(); ++i) { - const auto item = qobject_cast(layout_->itemAt(i)->widget()); - - if (item) - item->setHovering(false); - } -} - -void -SuggestionsPopup::setHovering(int pos) -{ - const auto &item = layout_->itemAt(pos); - const auto &widget = qobject_cast(item->widget()); - - if (widget) - widget->setHovering(true); -} - -void -SuggestionsPopup::paintEvent(QPaintEvent *) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} diff --git a/src/SuggestionsPopup.h b/src/SuggestionsPopup.h deleted file mode 100644 index 72d6c7eb..00000000 --- a/src/SuggestionsPopup.h +++ /dev/null @@ -1,147 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "AvatarProvider.h" -#include "Cache.h" -#include "ChatPage.h" - -class Avatar; -struct SearchResult; - -class PopupItem : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor) - Q_PROPERTY(bool hovering READ hovering WRITE setHovering) - -public: - PopupItem(QWidget *parent); - - QString selectedText() const { return QString(); } - QColor hoverColor() const { return hoverColor_; } - void setHoverColor(QColor &color) { hoverColor_ = color; } - - bool hovering() const { return hovering_; } - void setHovering(const bool hover) { hovering_ = hover; }; - -protected: - void paintEvent(QPaintEvent *event) override; - -signals: - void clicked(const QString &text); - -protected: - QHBoxLayout *topLayout_; - Avatar *avatar_; - QColor hoverColor_; - - //! Set if the item is currently being - //! hovered during tab completion (cycling). - bool hovering_; -}; - -class UserItem : public PopupItem -{ - Q_OBJECT - -public: - UserItem(QWidget *parent, const QString &user_id); - QString selectedText() const { return userId_; } - void updateItem(const QString &user_id); - -protected: - void mousePressEvent(QMouseEvent *event) override; - -private: - void resolveAvatar(const QString &user_id); - - QLabel *userName_; - QString userId_; -}; - -class RoomItem : public PopupItem -{ - Q_OBJECT - -public: - RoomItem(QWidget *parent, const RoomSearchResult &res); - QString selectedText() const { return roomId_; } - void updateItem(const RoomSearchResult &res); - -protected: - void mousePressEvent(QMouseEvent *event) override; - -private: - QLabel *roomName_; - QString roomId_; - RoomSearchResult info_; -}; - -class SuggestionsPopup : public QWidget -{ - Q_OBJECT - -public: - explicit SuggestionsPopup(QWidget *parent = nullptr); - - template - void selectHoveredSuggestion() - { - const auto item = layout_->itemAt(selectedItem_); - if (!item) - return; - - const auto &widget = qobject_cast(item->widget()); - emit itemSelected( - Cache::displayName(ChatPage::instance()->currentRoom(), widget->selectedText())); - - resetSelection(); - } - -public slots: - void addUsers(const QVector &users); - void addRooms(const std::vector &rooms); - - //! Move to the next available suggestion item. - void selectNextSuggestion(); - //! Move to the previous available suggestion item. - void selectPreviousSuggestion(); - //! Remove hovering from all items. - void resetHovering(); - //! Set hovering to the item in the given layout position. - void setHovering(int pos); - -protected: - void paintEvent(QPaintEvent *event) override; - -signals: - void itemSelected(const QString &user); - -private: - void hoverSelection(); - void resetSelection() { selectedItem_ = -1; } - void selectFirstItem() { selectedItem_ = 0; } - void selectLastItem() { selectedItem_ = layout_->count() - 1; } - void removeLayoutItemsAfter(size_t startingPos) - { - size_t posToRemove = layout_->count() - 1; - - QLayoutItem *item; - while (startingPos <= posToRemove && (item = layout_->takeAt(posToRemove)) != 0) { - delete item->widget(); - delete item; - - posToRemove = layout_->count() - 1; - } - } - - QVBoxLayout *layout_; - - //! Counter for tab completion (cycling). - int selectedItem_ = -1; -}; diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 340c6f7c..b4251a0e 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -48,7 +48,8 @@ static constexpr int ButtonHeight = 22; FilteredTextEdit::FilteredTextEdit(QWidget *parent) : QTextEdit{parent} , history_index_{0} - , popup_{parent} + , suggestionsPopup_{parent} + , replyPopup_{parent} , previewDialog_{parent} { setFrameStyle(QFrame::NoFrame); @@ -75,29 +76,34 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent) &FilteredTextEdit::uploadData); connect(this, &FilteredTextEdit::resultsRetrieved, this, &FilteredTextEdit::showResults); - connect(&popup_, &SuggestionsPopup::itemSelected, this, [this](const QString &text) { - popup_.hide(); + connect(&replyPopup_, &ReplyPopup::userSelected, this, [this](const QString &text) { + // TODO: Show user avatar window. + nhlog::ui()->info("User selected: " + text.toStdString()); + }); + connect( + &suggestionsPopup_, &SuggestionsPopup::itemSelected, this, [this](const QString &text) { + suggestionsPopup_.hide(); - auto cursor = textCursor(); - const int end = cursor.position(); + auto cursor = textCursor(); + const int end = cursor.position(); - cursor.setPosition(atTriggerPosition_, QTextCursor::MoveAnchor); - cursor.setPosition(end, QTextCursor::KeepAnchor); - cursor.removeSelectedText(); - cursor.insertText(text); - }); + 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, - &popup_, + &suggestionsPopup_, &SuggestionsPopup::selectNextSuggestion); connect(this, &FilteredTextEdit::selectPreviousSuggestion, - &popup_, + &suggestionsPopup_, &SuggestionsPopup::selectPreviousSuggestion); connect(this, &FilteredTextEdit::selectHoveredSuggestion, this, [this]() { - popup_.selectHoveredSuggestion(); + suggestionsPopup_.selectHoveredSuggestion(); }); previewDialog_.hide(); @@ -117,9 +123,9 @@ FilteredTextEdit::showResults(const QVector &results) pos = viewport()->mapToGlobal(rect.topLeft()); } - popup_.addUsers(results); - popup_.move(pos.x(), pos.y() - popup_.height() - 10); - popup_.show(); + suggestionsPopup_.addUsers(results); + suggestionsPopup_.move(pos.x(), pos.y() - suggestionsPopup_.height() - 10); + suggestionsPopup_.show(); } void @@ -146,7 +152,7 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event) closeSuggestions(); } - if (popup_.isVisible()) { + if (suggestionsPopup_.isVisible()) { switch (event->key()) { case Qt::Key_Down: case Qt::Key_Tab: @@ -169,6 +175,19 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event) } } + if (replyPopup_.isVisible()) { + switch (event->key()) + { + case Qt::Key_Escape: + closeReply(); + return; + + default: + break; + } + } + + switch (event->key()) { case Qt::Key_At: atTriggerPosition_ = textCursor().position(); @@ -419,6 +438,24 @@ FilteredTextEdit::submit() clear(); } +void +FilteredTextEdit::showReplyPopup(const QString &user, const QString &msg, const QString &event_id) +{ + 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()); + } + replyPopup_.setReplyContent(user, msg, event_id); + replyPopup_.move(pos.x(), pos.y() - replyPopup_.height() - 10); + replyPopup_.show(); +} + void FilteredTextEdit::textChanged() { @@ -666,9 +703,10 @@ TextInputWidget::paintEvent(QPaintEvent *) void TextInputWidget::addReply(const QString &username, const QString &msg, const QString &replied_event) { - input_->setText(QString("> %1: %2\n\n").arg(username).arg(msg)); + // input_->setText(QString("> %1: %2\n\n").arg(username).arg(msg)); input_->setFocus(); + input_->showReplyPopup(username, msg, replied_event); auto cursor = input_->textCursor(); cursor.movePosition(QTextCursor::End); input_->setTextCursor(cursor); diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index a12183d8..2936340b 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -28,7 +28,8 @@ #include #include -#include "SuggestionsPopup.h" +#include "popups/SuggestionsPopup.h" +#include "popups/ReplyPopup.h" #include "dialogs/PreviewUploadOverlay.h" #include "emoji/PickButton.h" @@ -55,6 +56,7 @@ public: void submit(); void setRelatedEvent(const QString &event) { related_event_ = event; } + void showReplyPopup(const QString &user, const QString &msg, const QString &event_id); signals: void heightChanged(int height); @@ -85,7 +87,7 @@ protected: void insertFromMimeData(const QMimeData *source) override; void focusOutEvent(QFocusEvent *event) override { - popup_.hide(); + suggestionsPopup_.hide(); QTextEdit::focusOutEvent(event); } @@ -94,7 +96,8 @@ private: size_t history_index_; QTimer *typingTimer_; - SuggestionsPopup popup_; + SuggestionsPopup suggestionsPopup_; + ReplyPopup replyPopup_; // Used for replies QString related_event_; @@ -109,7 +112,8 @@ private: int anchorWidth(AnchorType anchor) { return static_cast(anchor); } - void closeSuggestions() { popup_.hide(); } + void closeSuggestions() { suggestionsPopup_.hide(); } + void closeReply() { replyPopup_.hide(); } void resetAnchor() { atTriggerPosition_ = -1; } bool isAnchorValid() { return atTriggerPosition_ != -1; } bool hasAnchor(int pos, AnchorType anchor) diff --git a/src/popups/PopupItem.cpp b/src/popups/PopupItem.cpp new file mode 100644 index 00000000..b10cd32e --- /dev/null +++ b/src/popups/PopupItem.cpp @@ -0,0 +1,147 @@ +#include +#include +#include + +#include "PopupItem.h" +#include "../Utils.h" +#include "../ui/Avatar.h" + +constexpr int PopupHMargin = 4; +constexpr int PopupItemMargin = 3; + +PopupItem::PopupItem(QWidget *parent) + : QWidget(parent) + , avatar_{new Avatar(this)} + , hovering_{false} +{ + setMouseTracking(true); + setAttribute(Qt::WA_Hover); + + topLayout_ = new QHBoxLayout(this); + topLayout_->setContentsMargins( + PopupHMargin, PopupItemMargin, PopupHMargin, PopupItemMargin); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); +} + +void +PopupItem::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + + if (underMouse() || hovering_) + p.fillRect(rect(), hoverColor_); +} + +UserItem::UserItem(QWidget *parent, const QString &user_id) + : PopupItem(parent) + , userId_{user_id} +{ + auto displayName = Cache::displayName(ChatPage::instance()->currentRoom(), userId_); + + avatar_->setSize(conf::popup::avatar); + avatar_->setLetter(utils::firstChar(displayName)); + + // If it's a matrix id we use the second letter. + if (displayName.size() > 1 && displayName.at(0) == '@') + avatar_->setLetter(QChar(displayName.at(1))); + + userName_ = new QLabel(displayName, this); + + topLayout_->addWidget(avatar_); + topLayout_->addWidget(userName_, 1); + + resolveAvatar(user_id); +} + +void +UserItem::updateItem(const QString &user_id) +{ + userId_ = user_id; + + auto displayName = Cache::displayName(ChatPage::instance()->currentRoom(), userId_); + + // If it's a matrix id we use the second letter. + if (displayName.size() > 1 && displayName.at(0) == '@') + avatar_->setLetter(QChar(displayName.at(1))); + else + avatar_->setLetter(utils::firstChar(displayName)); + + userName_->setText(displayName); + resolveAvatar(user_id); +} + +void +UserItem::resolveAvatar(const QString &user_id) +{ + AvatarProvider::resolve( + ChatPage::instance()->currentRoom(), userId_, this, [this, user_id](const QImage &img) { + // The user on the widget when the avatar is resolved, + // might be different from the user that made the call. + if (user_id == userId_) + avatar_->setImage(img); + else + // We try to resolve the avatar again. + resolveAvatar(userId_); + }); +} + +void +UserItem::mousePressEvent(QMouseEvent *event) +{ + if (event->buttons() != Qt::RightButton) + emit clicked( + Cache::displayName(ChatPage::instance()->currentRoom(), selectedText())); + + QWidget::mousePressEvent(event); +} + +RoomItem::RoomItem(QWidget *parent, const RoomSearchResult &res) + : PopupItem(parent) + , roomId_{QString::fromStdString(res.room_id)} +{ + auto name = QFontMetrics(QFont()).elidedText( + QString::fromStdString(res.info.name), Qt::ElideRight, parentWidget()->width() - 10); + + avatar_->setSize(conf::popup::avatar + 6); + avatar_->setLetter(utils::firstChar(name)); + + roomName_ = new QLabel(name, this); + roomName_->setMargin(0); + + topLayout_->addWidget(avatar_); + topLayout_->addWidget(roomName_, 1); + + if (!res.img.isNull()) + avatar_->setImage(res.img); +} + +void +RoomItem::updateItem(const RoomSearchResult &result) +{ + roomId_ = QString::fromStdString(std::move(result.room_id)); + + auto name = + QFontMetrics(QFont()).elidedText(QString::fromStdString(std::move(result.info.name)), + Qt::ElideRight, + parentWidget()->width() - 10); + + roomName_->setText(name); + + if (!result.img.isNull()) + avatar_->setImage(result.img); + else + avatar_->setLetter(utils::firstChar(name)); +} + +void +RoomItem::mousePressEvent(QMouseEvent *event) +{ + if (event->buttons() != Qt::RightButton) + emit clicked(selectedText()); + + QWidget::mousePressEvent(event); +} \ No newline at end of file diff --git a/src/popups/PopupItem.h b/src/popups/PopupItem.h new file mode 100644 index 00000000..1fc54bf7 --- /dev/null +++ b/src/popups/PopupItem.h @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include +#include + +#include "../AvatarProvider.h" +#include "../Cache.h" +#include "../ChatPage.h" + +class Avatar; +struct SearchResult; + +class PopupItem : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor) + Q_PROPERTY(bool hovering READ hovering WRITE setHovering) + +public: + PopupItem(QWidget *parent); + + QString selectedText() const { return QString(); } + QColor hoverColor() const { return hoverColor_; } + void setHoverColor(QColor &color) { hoverColor_ = color; } + + bool hovering() const { return hovering_; } + void setHovering(const bool hover) { hovering_ = hover; }; + +protected: + void paintEvent(QPaintEvent *event) override; + +signals: + void clicked(const QString &text); + +protected: + QHBoxLayout *topLayout_; + Avatar *avatar_; + QColor hoverColor_; + + //! Set if the item is currently being + //! hovered during tab completion (cycling). + bool hovering_; +}; + +class UserItem : public PopupItem +{ + Q_OBJECT + +public: + UserItem(QWidget *parent, const QString &user_id); + QString selectedText() const { return userId_; } + void updateItem(const QString &user_id); + +protected: + void mousePressEvent(QMouseEvent *event) override; + +private: + void resolveAvatar(const QString &user_id); + + QLabel *userName_; + QString userId_; +}; + +class RoomItem : public PopupItem +{ + Q_OBJECT + +public: + RoomItem(QWidget *parent, const RoomSearchResult &res); + QString selectedText() const { return roomId_; } + void updateItem(const RoomSearchResult &res); + +protected: + void mousePressEvent(QMouseEvent *event) override; + +private: + QLabel *roomName_; + QString roomId_; + RoomSearchResult info_; +}; \ No newline at end of file diff --git a/src/popups/ReplyPopup.cpp b/src/popups/ReplyPopup.cpp new file mode 100644 index 00000000..a883739f --- /dev/null +++ b/src/popups/ReplyPopup.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#include "../Config.h" +#include "../Utils.h" +#include "../ui/Avatar.h" +#include "../ui/DropShadow.h" +#include "ReplyPopup.h" + +ReplyPopup::ReplyPopup(QWidget *parent) + : QWidget(parent) +{ + setAttribute(Qt::WA_ShowWithoutActivating, true); + setWindowFlags(Qt::ToolTip | Qt::NoDropShadowWindowHint); + + layout_ = new QVBoxLayout(this); + layout_->setMargin(0); + layout_->setSpacing(0); +} + +void +ReplyPopup::setReplyContent(const QString &user, const QString &msg, const QString &srcEvent) +{ + QLayoutItem *child; + while ((child = layout_->takeAt(0)) != 0) { + delete child->widget(); + delete child; + } + // Create a new widget if there isn't already one in that + // layout position. + // if (!item) { + auto userItem = new UserItem(this, user); + auto *text = new QLabel(this); + text->setText(msg); + auto *event = new QLabel(this); + event->setText(srcEvent); + connect(userItem, &UserItem::clicked, this, &ReplyPopup::userSelected); + layout_->addWidget(userItem); + layout_->addWidget(text); + layout_->addWidget(event); + // } else { + // Update the current widget with the new data. + // auto userWidget = qobject_cast(item->widget()); + // if (userWidget) + // userWidget->updateItem(users.at(i).user_id); + // } + + adjustSize(); +} + +void +ReplyPopup::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} diff --git a/src/popups/ReplyPopup.h b/src/popups/ReplyPopup.h new file mode 100644 index 00000000..d8355e53 --- /dev/null +++ b/src/popups/ReplyPopup.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include +#include + +#include "../AvatarProvider.h" +#include "../Cache.h" +#include "../ChatPage.h" +#include "PopupItem.h" + +class ReplyPopup : public QWidget +{ + Q_OBJECT + +public: + explicit ReplyPopup(QWidget *parent = nullptr); + +public slots: + void setReplyContent(const QString &user, const QString &msg, const QString &srcEvent); + +protected: + void paintEvent(QPaintEvent *event) override; + +signals: + void userSelected(const QString &user); + +private: + QVBoxLayout *layout_; + +}; diff --git a/src/popups/SuggestionsPopup.cpp b/src/popups/SuggestionsPopup.cpp new file mode 100644 index 00000000..6861a76a --- /dev/null +++ b/src/popups/SuggestionsPopup.cpp @@ -0,0 +1,156 @@ +#include +#include +#include + +#include "../Config.h" +#include "SuggestionsPopup.h" +#include "../Utils.h" +#include "../ui/Avatar.h" +#include "../ui/DropShadow.h" + +SuggestionsPopup::SuggestionsPopup(QWidget *parent) + : QWidget(parent) +{ + setAttribute(Qt::WA_ShowWithoutActivating, true); + setWindowFlags(Qt::ToolTip | Qt::NoDropShadowWindowHint); + + layout_ = new QVBoxLayout(this); + layout_->setMargin(0); + layout_->setSpacing(0); +} + +void +SuggestionsPopup::addRooms(const std::vector &rooms) +{ + if (rooms.empty()) { + hide(); + return; + } + + const size_t layoutCount = layout_->count(); + const size_t roomCount = rooms.size(); + + // Remove the extra widgets from the layout. + if (roomCount < layoutCount) + removeLayoutItemsAfter(roomCount - 1); + + for (size_t i = 0; i < roomCount; ++i) { + auto item = layout_->itemAt(i); + + // Create a new widget if there isn't already one in that + // layout position. + if (!item) { + auto room = new RoomItem(this, rooms.at(i)); + connect(room, &RoomItem::clicked, this, &SuggestionsPopup::itemSelected); + layout_->addWidget(room); + } else { + // Update the current widget with the new data. + auto room = qobject_cast(item->widget()); + if (room) + room->updateItem(rooms.at(i)); + } + } + + resetSelection(); + adjustSize(); + + resize(geometry().width(), 40 * rooms.size()); + + selectNextSuggestion(); +} + +void +SuggestionsPopup::addUsers(const QVector &users) +{ + if (users.isEmpty()) { + hide(); + return; + } + + const size_t layoutCount = layout_->count(); + const size_t userCount = users.size(); + + // Remove the extra widgets from the layout. + if (userCount < layoutCount) + removeLayoutItemsAfter(userCount - 1); + + for (size_t i = 0; i < userCount; ++i) { + auto item = layout_->itemAt(i); + + // Create a new widget if there isn't already one in that + // layout position. + if (!item) { + auto user = new UserItem(this, users.at(i).user_id); + connect(user, &UserItem::clicked, this, &SuggestionsPopup::itemSelected); + layout_->addWidget(user); + } else { + // Update the current widget with the new data. + auto userWidget = qobject_cast(item->widget()); + if (userWidget) + userWidget->updateItem(users.at(i).user_id); + } + } + + resetSelection(); + adjustSize(); + + selectNextSuggestion(); +} + +void +SuggestionsPopup::hoverSelection() +{ + resetHovering(); + setHovering(selectedItem_); + update(); +} + +void +SuggestionsPopup::selectNextSuggestion() +{ + selectedItem_++; + if (selectedItem_ >= layout_->count()) + selectFirstItem(); + + hoverSelection(); +} + +void +SuggestionsPopup::selectPreviousSuggestion() +{ + selectedItem_--; + if (selectedItem_ < 0) + selectLastItem(); + + hoverSelection(); +} + +void +SuggestionsPopup::resetHovering() +{ + for (int i = 0; i < layout_->count(); ++i) { + const auto item = qobject_cast(layout_->itemAt(i)->widget()); + + if (item) + item->setHovering(false); + } +} + +void +SuggestionsPopup::setHovering(int pos) +{ + const auto &item = layout_->itemAt(pos); + const auto &widget = qobject_cast(item->widget()); + + if (widget) + widget->setHovering(true); +} + +void +SuggestionsPopup::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} diff --git a/src/popups/SuggestionsPopup.h b/src/popups/SuggestionsPopup.h new file mode 100644 index 00000000..4fbb97b3 --- /dev/null +++ b/src/popups/SuggestionsPopup.h @@ -0,0 +1,76 @@ +#pragma once + +#include +#include +#include +#include + +#include "../AvatarProvider.h" +#include "../Cache.h" +#include "../ChatPage.h" +#include "PopupItem.h" + + +class SuggestionsPopup : public QWidget +{ + Q_OBJECT + +public: + explicit SuggestionsPopup(QWidget *parent = nullptr); + + template + void selectHoveredSuggestion() + { + const auto item = layout_->itemAt(selectedItem_); + if (!item) + return; + + const auto &widget = qobject_cast(item->widget()); + emit itemSelected( + Cache::displayName(ChatPage::instance()->currentRoom(), widget->selectedText())); + + resetSelection(); + } + +public slots: + void addUsers(const QVector &users); + void addRooms(const std::vector &rooms); + + //! Move to the next available suggestion item. + void selectNextSuggestion(); + //! Move to the previous available suggestion item. + void selectPreviousSuggestion(); + //! Remove hovering from all items. + void resetHovering(); + //! Set hovering to the item in the given layout position. + void setHovering(int pos); + +protected: + void paintEvent(QPaintEvent *event) override; + +signals: + void itemSelected(const QString &user); + +private: + void hoverSelection(); + void resetSelection() { selectedItem_ = -1; } + void selectFirstItem() { selectedItem_ = 0; } + void selectLastItem() { selectedItem_ = layout_->count() - 1; } + void removeLayoutItemsAfter(size_t startingPos) + { + size_t posToRemove = layout_->count() - 1; + + QLayoutItem *item; + while (startingPos <= posToRemove && (item = layout_->takeAt(posToRemove)) != 0) { + delete item->widget(); + delete item; + + posToRemove = layout_->count() - 1; + } + } + + QVBoxLayout *layout_; + + //! Counter for tab completion (cycling). + int selectedItem_ = -1; +}; -- cgit 1.5.1 From 1d4966d5fd916f21bdbbad8080eec69bb2c817d6 Mon Sep 17 00:00:00 2001 From: redsky17 Date: Tue, 11 Jun 2019 23:36:46 -0400 Subject: Add style for reply popup. Fix ALL of the linting issues --- resources/styles/nheko-dark.qss | 4 ++++ resources/styles/nheko.qss | 4 ++++ src/ChatPage.h | 4 +++- src/TextInputWidget.cpp | 6 ++---- src/TextInputWidget.h | 4 ++-- src/popups/PopupItem.cpp | 2 +- src/popups/ReplyPopup.cpp | 4 ++-- src/popups/ReplyPopup.h | 1 - src/popups/SuggestionsPopup.cpp | 2 +- src/popups/SuggestionsPopup.h | 1 - src/timeline/TimelineView.h | 4 +++- src/timeline/TimelineViewManager.cpp | 3 +-- 12 files changed, 23 insertions(+), 16 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/resources/styles/nheko-dark.qss b/resources/styles/nheko-dark.qss index 5567f32c..c55960f9 100644 --- a/resources/styles/nheko-dark.qss +++ b/resources/styles/nheko-dark.qss @@ -41,6 +41,10 @@ SuggestionsPopup { background-color: #202228; } +ReplyPopup { + background-color: #202228; +} + PopupItem { background-color: #202228; qproperty-hoverColor: rgba(45, 49, 57, 120); diff --git a/resources/styles/nheko.qss b/resources/styles/nheko.qss index 58e83c22..c352956a 100644 --- a/resources/styles/nheko.qss +++ b/resources/styles/nheko.qss @@ -46,6 +46,10 @@ SuggestionsPopup { background-color: white; } +ReplyPopup { + background-color: white; +} + PopupItem { background-color: white; qproperty-hoverColor: rgba(192, 193, 195, 120); diff --git a/src/ChatPage.h b/src/ChatPage.h index 09e7a2c6..f70f5bdd 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -83,7 +83,9 @@ signals: void connectionLost(); void connectionRestored(); - void messageReply(const QString &username, const QString &msg, const QString &related_event); + void messageReply(const QString &username, + const QString &msg, + const QString &related_event); void notificationsRetrieved(const mtx::responses::Notifications &); diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 7971ab43..dc41b4d3 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -176,18 +176,16 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event) } if (replyPopup_.isVisible()) { - switch (event->key()) - { + switch (event->key()) { case Qt::Key_Escape: closeReply(); return; - + default: break; } } - switch (event->key()) { case Qt::Key_At: atTriggerPosition_ = textCursor().position(); diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 2936340b..c462de05 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -28,10 +28,10 @@ #include #include -#include "popups/SuggestionsPopup.h" -#include "popups/ReplyPopup.h" #include "dialogs/PreviewUploadOverlay.h" #include "emoji/PickButton.h" +#include "popups/ReplyPopup.h" +#include "popups/SuggestionsPopup.h" namespace dialogs { class PreviewUploadOverlay; diff --git a/src/popups/PopupItem.cpp b/src/popups/PopupItem.cpp index b10cd32e..94de3a92 100644 --- a/src/popups/PopupItem.cpp +++ b/src/popups/PopupItem.cpp @@ -2,9 +2,9 @@ #include #include -#include "PopupItem.h" #include "../Utils.h" #include "../ui/Avatar.h" +#include "PopupItem.h" constexpr int PopupHMargin = 4; constexpr int PopupItemMargin = 3; diff --git a/src/popups/ReplyPopup.cpp b/src/popups/ReplyPopup.cpp index a883739f..04c3cea5 100644 --- a/src/popups/ReplyPopup.cpp +++ b/src/popups/ReplyPopup.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include #include @@ -32,7 +32,7 @@ ReplyPopup::setReplyContent(const QString &user, const QString &msg, const QStri // layout position. // if (!item) { auto userItem = new UserItem(this, user); - auto *text = new QLabel(this); + auto *text = new QLabel(this); text->setText(msg); auto *event = new QLabel(this); event->setText(srcEvent); diff --git a/src/popups/ReplyPopup.h b/src/popups/ReplyPopup.h index d8355e53..57c2bc8a 100644 --- a/src/popups/ReplyPopup.h +++ b/src/popups/ReplyPopup.h @@ -28,5 +28,4 @@ signals: private: QVBoxLayout *layout_; - }; diff --git a/src/popups/SuggestionsPopup.cpp b/src/popups/SuggestionsPopup.cpp index 6861a76a..ba1f77b9 100644 --- a/src/popups/SuggestionsPopup.cpp +++ b/src/popups/SuggestionsPopup.cpp @@ -3,10 +3,10 @@ #include #include "../Config.h" -#include "SuggestionsPopup.h" #include "../Utils.h" #include "../ui/Avatar.h" #include "../ui/DropShadow.h" +#include "SuggestionsPopup.h" SuggestionsPopup::SuggestionsPopup(QWidget *parent) : QWidget(parent) diff --git a/src/popups/SuggestionsPopup.h b/src/popups/SuggestionsPopup.h index 4fbb97b3..1ef720b2 100644 --- a/src/popups/SuggestionsPopup.h +++ b/src/popups/SuggestionsPopup.h @@ -10,7 +10,6 @@ #include "../ChatPage.h" #include "PopupItem.h" - class SuggestionsPopup : public QWidget { Q_OBJECT diff --git a/src/timeline/TimelineView.h b/src/timeline/TimelineView.h index 450b5dfa..db6087eb 100644 --- a/src/timeline/TimelineView.h +++ b/src/timeline/TimelineView.h @@ -121,7 +121,9 @@ public: // Add new events at the end of the timeline. void addEvents(const mtx::responses::Timeline &timeline); - void addUserMessage(mtx::events::MessageType ty, const QString &body, const QString &related_event); + void addUserMessage(mtx::events::MessageType ty, + const QString &body, + const QString &related_event); void addUserMessage(mtx::events::MessageType ty, const QString &msg); template diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 10c2d747..1ce3794f 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -79,8 +79,7 @@ TimelineViewManager::queueEmoteMessage(const QString &msg) } void -TimelineViewManager::queueReplyMessage(const QString &reply, - const QString &related_event) +TimelineViewManager::queueReplyMessage(const QString &reply, const QString &related_event) { if (active_room_.isEmpty()) return; -- cgit 1.5.1 From 129beb57c9525439d04fc2bf74f4ccaed30369c9 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Thu, 13 Jun 2019 22:33:04 -0400 Subject: Further Improve Reply Functionality Quoted replies now include matrix.to links for the event and the user. UI Rendering has been (slightly) improved... still very WIP. Restructured the reply structure in the code for future usability improvements. --- src/ChatPage.cpp | 4 +- src/ChatPage.h | 5 +- src/TextInputWidget.cpp | 30 ++++++------ src/TextInputWidget.h | 17 ++++--- src/Utils.cpp | 14 ++++++ src/Utils.h | 13 ++++++ src/popups/PopupItem.cpp | 10 ++++ src/popups/PopupItem.h | 1 + src/popups/ReplyPopup.cpp | 88 ++++++++++++++++++++++++++---------- src/popups/ReplyPopup.h | 16 ++++++- src/timeline/TimelineItem.cpp | 8 +++- src/timeline/TimelineView.cpp | 31 +++++++------ src/timeline/TimelineView.h | 5 +- src/timeline/TimelineViewManager.cpp | 5 +- src/timeline/TimelineViewManager.h | 4 +- 15 files changed, 177 insertions(+), 74 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 5b838259..f7dbf7ca 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -265,9 +265,9 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) SLOT(queueTextMessage(const QString &))); connect(text_input_, - SIGNAL(sendReplyMessage(const QString &, const QString &)), + SIGNAL(sendReplyMessage(const QString &, const RelatedInfo &)), view_manager_, - SLOT(queueReplyMessage(const QString &, const QString &))); + SLOT(queueReplyMessage(const QString &, const RelatedInfo &))); connect(text_input_, SIGNAL(sendEmoteMessage(const QString &)), diff --git a/src/ChatPage.h b/src/ChatPage.h index f70f5bdd..6e6f5aed 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -30,6 +30,7 @@ #include "Cache.h" #include "CommunitiesList.h" #include "MatrixClient.h" +#include "Utils.h" #include "notifications/Manager.h" class OverlayModal; @@ -83,9 +84,7 @@ signals: void connectionLost(); void connectionRestored(); - void messageReply(const QString &username, - const QString &msg, - const QString &related_event); + void messageReply(const RelatedInfo &related); void notificationsRetrieved(const mtx::responses::Notifications &); diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index dc41b4d3..8becf5ce 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -93,6 +93,8 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent) cursor.insertText(text); }); + connect(&replyPopup_, &ReplyPopup::cancel, this, [this]() { closeReply(); }); + // For cycling through the suggestions by hitting tab. connect(this, &FilteredTextEdit::selectNextSuggestion, @@ -219,6 +221,7 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event) if (!(event->modifiers() & Qt::ShiftModifier)) { stopTyping(); submit(); + closeReply(); } else { QTextEdit::keyPressEvent(event); } @@ -415,8 +418,8 @@ FilteredTextEdit::submit() auto name = text.mid(1, command_end - 1); auto args = text.mid(command_end + 1); if (name.isEmpty() || name == "/") { - if (!related_event_.isEmpty()) { - reply(args, related_event_); + if (!related_.related_event.empty()) { + reply(args, related_); } else { message(args); } @@ -424,14 +427,14 @@ FilteredTextEdit::submit() command(name, args); } } else { - if (!related_event_.isEmpty()) { - reply(std::move(text), std::move(related_event_)); + if (!related_.related_event.empty()) { + reply(std::move(text), std::move(related_)); } else { message(std::move(text)); } } - related_event_ = ""; + related_ = {}; clear(); } @@ -439,16 +442,8 @@ FilteredTextEdit::submit() void FilteredTextEdit::showReplyPopup(const QString &user, const QString &msg, const QString &event_id) { - QPoint pos; + QPoint pos = viewport()->mapToGlobal(this->pos()); - if (isAnchorValid()) { - auto cursor = textCursor(); - cursor.setPosition(atTriggerPosition_); - pos = viewport()->mapToGlobal(cursorRect(cursor).topLeft()); - } else { - auto rect = cursorRect(); - pos = viewport()->mapToGlobal(rect.topLeft()); - } replyPopup_.setReplyContent(user, msg, event_id); replyPopup_.move(pos.x(), pos.y() - replyPopup_.height() - 10); replyPopup_.show(); @@ -699,14 +694,15 @@ TextInputWidget::paintEvent(QPaintEvent *) } void -TextInputWidget::addReply(const QString &username, const QString &msg, const QString &replied_event) +TextInputWidget::addReply(const RelatedInfo &related) { // input_->setText(QString("> %1: %2\n\n").arg(username).arg(msg)); input_->setFocus(); - input_->showReplyPopup(username, msg, replied_event); + input_->showReplyPopup( + related.quoted_user, related.quoted_body, QString::fromStdString(related.related_event)); auto cursor = input_->textCursor(); cursor.movePosition(QTextCursor::End); input_->setTextCursor(cursor); - input_->setRelatedEvent(replied_event); + input_->setRelated(related); } diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index c462de05..f68560e9 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -28,6 +28,7 @@ #include #include +#include "Utils.h" #include "dialogs/PreviewUploadOverlay.h" #include "emoji/PickButton.h" #include "popups/ReplyPopup.h" @@ -55,7 +56,7 @@ public: QSize minimumSizeHint() const override; void submit(); - void setRelatedEvent(const QString &event) { related_event_ = event; } + void setRelated(const RelatedInfo &related) { related_ = related; } void showReplyPopup(const QString &user, const QString &msg, const QString &event_id); signals: @@ -64,7 +65,7 @@ signals: void stoppedTyping(); void startedUpload(); void message(QString); - void reply(QString, QString); + void reply(QString, const RelatedInfo &); void command(QString name, QString args); void image(QSharedPointer data, const QString &filename); void audio(QSharedPointer data, const QString &filename); @@ -100,7 +101,7 @@ private: ReplyPopup replyPopup_; // Used for replies - QString related_event_; + RelatedInfo related_; enum class AnchorType { @@ -113,7 +114,11 @@ private: int anchorWidth(AnchorType anchor) { return static_cast(anchor); } void closeSuggestions() { suggestionsPopup_.hide(); } - void closeReply() { replyPopup_.hide(); } + void closeReply() + { + replyPopup_.hide(); + related_ = {}; + } void resetAnchor() { atTriggerPosition_ = -1; } bool isAnchorValid() { return atTriggerPosition_ != -1; } bool hasAnchor(int pos, AnchorType anchor) @@ -167,14 +172,14 @@ public slots: void openFileSelection(); void hideUploadSpinner(); void focusLineEdit() { input_->setFocus(); } - void addReply(const QString &username, const QString &msg, const QString &related_event); + void addReply(const RelatedInfo &related); private slots: void addSelectedEmoji(const QString &emoji); signals: void sendTextMessage(QString msg); - void sendReplyMessage(QString msg, QString event_id); + void sendReplyMessage(QString msg, const RelatedInfo &related); void sendEmoteMessage(QString msg); void heightChanged(int height); diff --git a/src/Utils.cpp b/src/Utils.cpp index f8fdfaf9..690a9a9a 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -314,6 +314,20 @@ utils::markdownToHtml(const QString &text) return result; } +QString +utils::getFormattedQuoteBody(const RelatedInfo &related, const QString &html) +{ + return QString("
In reply " + "to%3
%4
") + .arg(QString::fromStdString(related.related_event), + related.quoted_user, + related.quoted_user, + related.quoted_body) + + html; +} + QString utils::linkColor() { diff --git a/src/Utils.h b/src/Utils.h index 8672e7d4..bf941c4c 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -18,6 +18,15 @@ class QComboBox; +// Contains information about related events for +// outgoing messages +struct RelatedInfo +{ + QString quoted_body; + std::string related_event; + QString quoted_user; +}; + namespace utils { using TimelineEvent = mtx::events::collections::TimelineEvents; @@ -225,6 +234,10 @@ linkifyMessage(const QString &body); QString markdownToHtml(const QString &text); +//! Generate a Rich Reply quote message +QString +getFormattedQuoteBody(const RelatedInfo &related, const QString &html); + //! Retrieve the color of the links based on the current theme. QString linkColor(); diff --git a/src/popups/PopupItem.cpp b/src/popups/PopupItem.cpp index 94de3a92..f905983a 100644 --- a/src/popups/PopupItem.cpp +++ b/src/popups/PopupItem.cpp @@ -36,6 +36,16 @@ PopupItem::paintEvent(QPaintEvent *) p.fillRect(rect(), hoverColor_); } +UserItem::UserItem(QWidget *parent) + : PopupItem(parent) +{ + userName_ = new QLabel("Placeholder", this); + avatar_->setSize(conf::popup::avatar); + avatar_->setLetter("P"); + topLayout_->addWidget(avatar_); + topLayout_->addWidget(userName_, 1); +} + UserItem::UserItem(QWidget *parent, const QString &user_id) : PopupItem(parent) , userId_{user_id} diff --git a/src/popups/PopupItem.h b/src/popups/PopupItem.h index 1fc54bf7..cab73a9d 100644 --- a/src/popups/PopupItem.h +++ b/src/popups/PopupItem.h @@ -50,6 +50,7 @@ class UserItem : public PopupItem Q_OBJECT public: + UserItem(QWidget *parent); UserItem(QWidget *parent, const QString &user_id); QString selectedText() const { return userId_; } void updateItem(const QString &user_id); diff --git a/src/popups/ReplyPopup.cpp b/src/popups/ReplyPopup.cpp index 04c3cea5..3c7c482a 100644 --- a/src/popups/ReplyPopup.cpp +++ b/src/popups/ReplyPopup.cpp @@ -11,41 +11,69 @@ ReplyPopup::ReplyPopup(QWidget *parent) : QWidget(parent) + , userItem_{0} + , msgLabel_{0} + , eventLabel_{0} { setAttribute(Qt::WA_ShowWithoutActivating, true); setWindowFlags(Qt::ToolTip | Qt::NoDropShadowWindowHint); - layout_ = new QVBoxLayout(this); - layout_->setMargin(0); - layout_->setSpacing(0); + mainLayout_ = new QVBoxLayout(this); + mainLayout_->setMargin(0); + mainLayout_->setSpacing(0); + + topLayout_ = new QHBoxLayout(); + topLayout_->setSpacing(0); + topLayout_->setContentsMargins(13, 1, 13, 0); + + userItem_ = new UserItem(this); + connect(userItem_, &UserItem::clicked, this, &ReplyPopup::userSelected); + topLayout_->addWidget(userItem_); + + buttonLayout_ = new QHBoxLayout(); + buttonLayout_->setSpacing(0); + buttonLayout_->setMargin(0); + + topLayout_->addLayout(buttonLayout_); + QFont f; + f.setPointSizeF(f.pointSizeF()); + const int fontHeight = QFontMetrics(f).height(); + buttonSize_ = std::min(fontHeight, 20); + + closeBtn_ = new FlatButton(this); + closeBtn_->setToolTip(tr("Logout")); + closeBtn_->setCornerRadius(buttonSize_ / 2); + closeBtn_->setText("X"); + + QIcon icon; + icon.addFile(":/icons/icons/ui/remove-symbol.png"); + + closeBtn_->setIcon(icon); + closeBtn_->setIconSize(QSize(buttonSize_, buttonSize_)); + connect(closeBtn_, &FlatButton::clicked, this, [this]() { emit cancel(); }); + + buttonLayout_->addWidget(closeBtn_); + + topLayout_->addLayout(buttonLayout_); + + mainLayout_->addLayout(topLayout_); + msgLabel_ = new QLabel(this); + mainLayout_->addWidget(msgLabel_); + eventLabel_ = new QLabel(this); + mainLayout_->addWidget(eventLabel_); + + setLayout(mainLayout_); } void ReplyPopup::setReplyContent(const QString &user, const QString &msg, const QString &srcEvent) { - QLayoutItem *child; - while ((child = layout_->takeAt(0)) != 0) { - delete child->widget(); - delete child; - } - // Create a new widget if there isn't already one in that - // layout position. - // if (!item) { - auto userItem = new UserItem(this, user); - auto *text = new QLabel(this); - text->setText(msg); - auto *event = new QLabel(this); - event->setText(srcEvent); - connect(userItem, &UserItem::clicked, this, &ReplyPopup::userSelected); - layout_->addWidget(userItem); - layout_->addWidget(text); - layout_->addWidget(event); - // } else { // Update the current widget with the new data. - // auto userWidget = qobject_cast(item->widget()); - // if (userWidget) - // userWidget->updateItem(users.at(i).user_id); - // } + userItem_->updateItem(user); + + msgLabel_->setText(msg); + + eventLabel_->setText(srcEvent); adjustSize(); } @@ -58,3 +86,13 @@ ReplyPopup::paintEvent(QPaintEvent *) QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } + +void +ReplyPopup::mousePressEvent(QMouseEvent *event) +{ + if (event->buttons() != Qt::RightButton) { + emit clicked(eventLabel_->text()); + } + + QWidget::mousePressEvent(event); +} diff --git a/src/popups/ReplyPopup.h b/src/popups/ReplyPopup.h index 57c2bc8a..829f707b 100644 --- a/src/popups/ReplyPopup.h +++ b/src/popups/ReplyPopup.h @@ -3,11 +3,13 @@ #include #include #include +#include #include #include "../AvatarProvider.h" #include "../Cache.h" #include "../ChatPage.h" +#include "../ui/FlatButton.h" #include "PopupItem.h" class ReplyPopup : public QWidget @@ -22,10 +24,22 @@ public slots: protected: void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; signals: void userSelected(const QString &user); + void clicked(const QString &text); + void cancel(); private: - QVBoxLayout *layout_; + QHBoxLayout *topLayout_; + QVBoxLayout *mainLayout_; + QHBoxLayout *buttonLayout_; + + UserItem *userItem_; + FlatButton *closeBtn_; + QLabel *msgLabel_; + QLabel *eventLabel_; + + int buttonSize_; }; diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index dd09ec78..bf5b1b53 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -874,8 +874,12 @@ TimelineItem::replyAction() if (!body_) return; - emit ChatPage::instance()->messageReply( - Cache::displayName(room_id_, descriptionMsg_.userid), body_->toPlainText(), eventId()); + RelatedInfo related; + related.quoted_body = body_->toPlainText(); + related.quoted_user = descriptionMsg_.userid; + related.related_event = eventId().toStdString(); + + emit ChatPage::instance()->messageReply(related); } void diff --git a/src/timeline/TimelineView.cpp b/src/timeline/TimelineView.cpp index 6d947c15..fc89fd38 100644 --- a/src/timeline/TimelineView.cpp +++ b/src/timeline/TimelineView.cpp @@ -692,7 +692,7 @@ TimelineView::updatePendingMessage(const std::string &txn_id, const QString &eve void TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body, - const QString &related_event) + const RelatedInfo &related = RelatedInfo()) { auto with_sender = (lastSender_ != local_user_) || isDateDifference(lastMsgTimestamp_); @@ -700,13 +700,11 @@ TimelineView::addUserMessage(mtx::events::MessageType ty, new TimelineItem(ty, local_user_, body, with_sender, room_id_, scroll_widget_); PendingMessage message; - message.ty = ty; - message.txn_id = http::client()->generate_txn_id(); - message.body = body; - message.widget = view_item; - if (!related_event.isEmpty()) { - message.related_event = related_event.toStdString(); - } + message.ty = ty; + message.txn_id = http::client()->generate_txn_id(); + message.body = body; + message.widget = view_item; + message.related = related; try { message.is_encrypted = cache::client()->isRoomEncrypted(room_id_.toStdString()); @@ -730,7 +728,7 @@ TimelineView::addUserMessage(mtx::events::MessageType ty, void TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body) { - addUserMessage(ty, body, ""); + addUserMessage(ty, body, RelatedInfo()); } void @@ -1273,13 +1271,20 @@ toRoomMessage(const PendingMessage &m) auto html = utils::markdownToHtml(m.body); mtx::events::msg::Text text; + text.body = m.body.trimmed().toStdString(); - if (html != m.body.trimmed().toHtmlEscaped()) - text.formatted_body = html.toStdString(); + if (html != m.body.trimmed().toHtmlEscaped()) { + if (!m.related.quoted_body.isEmpty()) { + text.formatted_body = + utils::getFormattedQuoteBody(m.related, html).toStdString(); + } else { + text.formatted_body = html.toStdString(); + } + } - if (!m.related_event.empty()) { - text.relates_to.in_reply_to.event_id = m.related_event; + if (!m.related.related_event.empty()) { + text.relates_to.in_reply_to.event_id = m.related.related_event; } return text; diff --git a/src/timeline/TimelineView.h b/src/timeline/TimelineView.h index db6087eb..35796efd 100644 --- a/src/timeline/TimelineView.h +++ b/src/timeline/TimelineView.h @@ -30,6 +30,7 @@ #include #include +#include "../Utils.h" #include "MatrixClient.h" #include "timeline/TimelineItem.h" @@ -63,7 +64,7 @@ struct PendingMessage { mtx::events::MessageType ty; std::string txn_id; - std::string related_event; + RelatedInfo related; QString body; QString filename; QString mime; @@ -123,7 +124,7 @@ public: void addEvents(const mtx::responses::Timeline &timeline); void addUserMessage(mtx::events::MessageType ty, const QString &body, - const QString &related_event); + const RelatedInfo &related); void addUserMessage(mtx::events::MessageType ty, const QString &msg); template diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 1ce3794f..86505481 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -23,6 +23,7 @@ #include "Cache.h" #include "Logging.h" +#include "Utils.h" #include "timeline/TimelineView.h" #include "timeline/TimelineViewManager.h" #include "timeline/widgets/AudioItem.h" @@ -79,7 +80,7 @@ TimelineViewManager::queueEmoteMessage(const QString &msg) } void -TimelineViewManager::queueReplyMessage(const QString &reply, const QString &related_event) +TimelineViewManager::queueReplyMessage(const QString &reply, const RelatedInfo &related) { if (active_room_.isEmpty()) return; @@ -87,7 +88,7 @@ TimelineViewManager::queueReplyMessage(const QString &reply, const QString &rela auto room_id = active_room_; auto view = views_[room_id]; - view->addUserMessage(mtx::events::MessageType::Text, reply, related_event); + view->addUserMessage(mtx::events::MessageType::Text, reply, related); } void diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 0ac6d67e..b52136d9 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -22,6 +22,8 @@ #include +#include "Utils.h" + class QFile; class RoomInfoListItem; @@ -63,7 +65,7 @@ public slots: void setHistoryView(const QString &room_id); void queueTextMessage(const QString &msg); - void queueReplyMessage(const QString &reply, const QString &related_event); + void queueReplyMessage(const QString &reply, const RelatedInfo &related); void queueEmoteMessage(const QString &msg); void queueImageMessage(const QString &roomid, const QString &filename, -- cgit 1.5.1 From cfd6c5703a7ca4a22fe1b1e78713b33f32f1a085 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Fri, 14 Jun 2019 20:45:37 -0400 Subject: Further UI Updates to Rich Replies --- src/TextInputWidget.cpp | 8 ++++---- src/TextInputWidget.h | 2 +- src/popups/ReplyPopup.cpp | 16 ++++++++++------ src/popups/ReplyPopup.h | 6 ++++-- src/timeline/TimelineItem.cpp | 2 ++ src/timeline/TimelineView.cpp | 10 ++++++++-- 6 files changed, 29 insertions(+), 15 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 8becf5ce..1ae26c2d 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -440,12 +440,13 @@ FilteredTextEdit::submit() } void -FilteredTextEdit::showReplyPopup(const QString &user, const QString &msg, const QString &event_id) +FilteredTextEdit::showReplyPopup(const RelatedInfo &related) { QPoint pos = viewport()->mapToGlobal(this->pos()); - replyPopup_.setReplyContent(user, msg, event_id); + replyPopup_.setReplyContent(related); replyPopup_.move(pos.x(), pos.y() - replyPopup_.height() - 10); + replyPopup_.setFixedWidth(this->parentWidget()->width()); replyPopup_.show(); } @@ -699,8 +700,7 @@ TextInputWidget::addReply(const RelatedInfo &related) // input_->setText(QString("> %1: %2\n\n").arg(username).arg(msg)); input_->setFocus(); - input_->showReplyPopup( - related.quoted_user, related.quoted_body, QString::fromStdString(related.related_event)); + input_->showReplyPopup(related); auto cursor = input_->textCursor(); cursor.movePosition(QTextCursor::End); input_->setTextCursor(cursor); diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index f68560e9..4a726364 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -57,7 +57,7 @@ public: void submit(); void setRelated(const RelatedInfo &related) { related_ = related; } - void showReplyPopup(const QString &user, const QString &msg, const QString &event_id); + void showReplyPopup(const RelatedInfo &related); signals: void heightChanged(int height); diff --git a/src/popups/ReplyPopup.cpp b/src/popups/ReplyPopup.cpp index 3c7c482a..0ebf7c88 100644 --- a/src/popups/ReplyPopup.cpp +++ b/src/popups/ReplyPopup.cpp @@ -7,6 +7,7 @@ #include "../Utils.h" #include "../ui/Avatar.h" #include "../ui/DropShadow.h" +#include "../ui/TextLabel.h" #include "ReplyPopup.h" ReplyPopup::ReplyPopup(QWidget *parent) @@ -42,7 +43,7 @@ ReplyPopup::ReplyPopup(QWidget *parent) closeBtn_ = new FlatButton(this); closeBtn_->setToolTip(tr("Logout")); - closeBtn_->setCornerRadius(buttonSize_ / 2); + closeBtn_->setCornerRadius(buttonSize_ / 4); closeBtn_->setText("X"); QIcon icon; @@ -57,7 +58,8 @@ ReplyPopup::ReplyPopup(QWidget *parent) topLayout_->addLayout(buttonLayout_); mainLayout_->addLayout(topLayout_); - msgLabel_ = new QLabel(this); + msgLabel_ = new TextLabel(this); + msgLabel_->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextBrowserInteraction); mainLayout_->addWidget(msgLabel_); eventLabel_ = new QLabel(this); mainLayout_->addWidget(eventLabel_); @@ -66,14 +68,16 @@ ReplyPopup::ReplyPopup(QWidget *parent) } void -ReplyPopup::setReplyContent(const QString &user, const QString &msg, const QString &srcEvent) +ReplyPopup::setReplyContent(const RelatedInfo &related) { // Update the current widget with the new data. - userItem_->updateItem(user); + userItem_->updateItem(related.quoted_user); - msgLabel_->setText(msg); + msgLabel_->setText(utils::getFormattedQuoteBody(related, "") + .replace("", "") + .replace("", "")); - eventLabel_->setText(srcEvent); + // eventLabel_->setText(srcEvent); adjustSize(); } diff --git a/src/popups/ReplyPopup.h b/src/popups/ReplyPopup.h index 829f707b..b28cd0cf 100644 --- a/src/popups/ReplyPopup.h +++ b/src/popups/ReplyPopup.h @@ -9,7 +9,9 @@ #include "../AvatarProvider.h" #include "../Cache.h" #include "../ChatPage.h" +#include "../Utils.h" #include "../ui/FlatButton.h" +#include "../ui/TextLabel.h" #include "PopupItem.h" class ReplyPopup : public QWidget @@ -20,7 +22,7 @@ public: explicit ReplyPopup(QWidget *parent = nullptr); public slots: - void setReplyContent(const QString &user, const QString &msg, const QString &srcEvent); + void setReplyContent(const RelatedInfo &related); protected: void paintEvent(QPaintEvent *event) override; @@ -38,7 +40,7 @@ private: UserItem *userItem_; FlatButton *closeBtn_; - QLabel *msgLabel_; + TextLabel *msgLabel_; QLabel *eventLabel_; int buttonSize_; diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index bf5b1b53..1094bde5 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -316,6 +316,8 @@ TimelineItem::TimelineItem(mtx::events::MessageType ty, } formatted_body = utils::linkifyMessage(formatted_body); + formatted_body.replace("mx-reply", "div"); + nhlog::ui()->info("formatted_body: {}", formatted_body.toStdString()); generateTimestamp(timestamp); diff --git a/src/timeline/TimelineView.cpp b/src/timeline/TimelineView.cpp index fc89fd38..18b73eb0 100644 --- a/src/timeline/TimelineView.cpp +++ b/src/timeline/TimelineView.cpp @@ -696,15 +696,21 @@ TimelineView::addUserMessage(mtx::events::MessageType ty, { auto with_sender = (lastSender_ != local_user_) || isDateDifference(lastMsgTimestamp_); + QString full_body; + if (related.related_event.empty()) { + full_body = body; + } else { + full_body = utils::getFormattedQuoteBody(related, body); + } TimelineItem *view_item = - new TimelineItem(ty, local_user_, body, with_sender, room_id_, scroll_widget_); + new TimelineItem(ty, local_user_, full_body, with_sender, room_id_, scroll_widget_); PendingMessage message; message.ty = ty; message.txn_id = http::client()->generate_txn_id(); message.body = body; - message.widget = view_item; message.related = related; + message.widget = view_item; try { message.is_encrypted = cache::client()->isRoomEncrypted(room_id_.toStdString()); -- cgit 1.5.1 From cefe5fe71945c89b7b65c6ed2cb127a404cf62f5 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 22 Jul 2019 02:38:44 +0200 Subject: Fix copy and pasting image from clipboard If the QMimeData contains an image, it actually has a mime type of application/x-qt-image. At least in some cases accessing the image/* data returns a 0 length array. Accessing the data via ->imageData works however. So we use that as our accessor and pass it to the preview dialog. --- src/TextInputWidget.cpp | 5 +++-- src/TextInputWidget.h | 4 ---- src/dialogs/PreviewUploadOverlay.cpp | 22 ++++++++++++++++++++++ src/dialogs/PreviewUploadOverlay.h | 2 ++ 4 files changed, 27 insertions(+), 6 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 1ae26c2d..f723c01a 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -306,8 +306,9 @@ FilteredTextEdit::insertFromMimeData(const QMimeData *source) const auto audio = formats.filter("audio/", Qt::CaseInsensitive); const auto video = formats.filter("video/", Qt::CaseInsensitive); - if (!image.empty()) { - showPreview(source, image); + if (source->hasImage()) { + QImage img = qvariant_cast(source->imageData()); + previewDialog_.setPreview(img, image.front()); } else if (!audio.empty()) { showPreview(source, audio); } else if (!video.empty()) { diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 4a726364..71f794d1 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -34,10 +34,6 @@ #include "popups/ReplyPopup.h" #include "popups/SuggestionsPopup.h" -namespace dialogs { -class PreviewUploadOverlay; -} - struct SearchResult; class FlatButton; diff --git a/src/dialogs/PreviewUploadOverlay.cpp b/src/dialogs/PreviewUploadOverlay.cpp index c404799e..31d01214 100644 --- a/src/dialogs/PreviewUploadOverlay.cpp +++ b/src/dialogs/PreviewUploadOverlay.cpp @@ -134,6 +134,28 @@ PreviewUploadOverlay::setLabels(const QString &type, const QString &mime, uint64 } } +void +PreviewUploadOverlay::setPreview(const QImage &src, const QString &mime) +{ + auto const &split = mime.split('/'); + auto const &type = split[1]; + + QBuffer buffer(&data_); + buffer.open(QIODevice::WriteOnly); + if (src.save(&buffer, type.toStdString().c_str())) + titleLabel_.setText(QString{tr(DEFAULT)}.arg("image")); + else + titleLabel_.setText(QString{tr(ERR_MSG)}.arg(type)); + + mediaType_ = split[0]; + filePath_ = "clipboard." + type; + image_.convertFromImage(src); + isImage_ = true; + + titleLabel_.setText(QString{tr(DEFAULT)}.arg("image")); + init(); +} + void PreviewUploadOverlay::setPreview(const QByteArray data, const QString &mime) { diff --git a/src/dialogs/PreviewUploadOverlay.h b/src/dialogs/PreviewUploadOverlay.h index 8099d9c2..11cd49bc 100644 --- a/src/dialogs/PreviewUploadOverlay.h +++ b/src/dialogs/PreviewUploadOverlay.h @@ -17,6 +17,7 @@ #pragma once +#include #include #include #include @@ -33,6 +34,7 @@ class PreviewUploadOverlay : public QWidget public: PreviewUploadOverlay(QWidget *parent = nullptr); + void setPreview(const QImage &src, const QString &mime); void setPreview(const QByteArray data, const QString &mime); void setPreview(const QString &path); -- cgit 1.5.1 From 43d7fe0d358edd1983257350817f7e76132c8dc8 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 5 Dec 2019 15:31:53 +0100 Subject: Implement sending encrypted files --- src/ChatPage.cpp | 206 ++++++++--------------------------- src/ChatPage.h | 21 +--- src/TextInputWidget.cpp | 28 ++--- src/TextInputWidget.h | 12 +- src/timeline/TimelineViewManager.cpp | 19 +++- src/timeline/TimelineViewManager.h | 5 + 6 files changed, 79 insertions(+), 212 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 091a9fa0..d6f6940b 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -54,6 +54,8 @@ constexpr int CHECK_CONNECTIVITY_INTERVAL = 15'000; constexpr int RETRY_TIMEOUT = 5'000; constexpr size_t MAX_ONETIME_KEYS = 50; +Q_DECLARE_METATYPE(boost::optional) + ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) : QWidget(parent) , isConnected_(true) @@ -62,6 +64,9 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) { setObjectName("chatPage"); + qRegisterMetaType>( + "boost::optional"); + topLayout_ = new QHBoxLayout(this); topLayout_->setSpacing(0); topLayout_->setMargin(0); @@ -299,9 +304,9 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect( text_input_, - &TextInputWidget::uploadImage, + &TextInputWidget::uploadMedia, this, - [this](QSharedPointer dev, const QString &fn) { + [this](QSharedPointer dev, QString mimeClass, const QString &fn) { QMimeDatabase db; QMimeType mime = db.mimeTypeForData(dev.data()); @@ -311,9 +316,18 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) return; } - auto bin = dev->peek(dev->size()); - auto payload = std::string(bin.data(), bin.size()); - auto dimensions = QImageReader(dev.data()).size(); + auto bin = dev->peek(dev->size()); + auto payload = std::string(bin.data(), bin.size()); + boost::optional encryptedFile; + if (cache::client()->isRoomEncrypted(current_room_.toStdString())) { + mtx::crypto::BinaryBuf buf; + std::tie(buf, encryptedFile) = mtx::crypto::encrypt_file(payload); + payload = mtx::crypto::to_string(buf); + } + + QSize dimensions; + if (mimeClass == "image") + dimensions = QImageReader(dev.data()).size(); http::client()->upload( payload, @@ -322,193 +336,61 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) [this, room_id = current_room_, filename = fn, - mime = mime.name(), - size = payload.size(), + encryptedFile, + mimeClass, + mime = mime.name(), + size = payload.size(), dimensions](const mtx::responses::ContentURI &res, mtx::http::RequestErr err) { if (err) { emit uploadFailed( - tr("Failed to upload image. Please try again.")); - nhlog::net()->warn("failed to upload image: {} {} ({})", + tr("Failed to upload media. Please try again.")); + nhlog::net()->warn("failed to upload media: {} {} ({})", err->matrix_error.error, to_string(err->matrix_error.errcode), static_cast(err->status_code)); return; } - emit imageUploaded(room_id, + emit mediaUploaded(room_id, filename, + encryptedFile, QString::fromStdString(res.content_uri), + mimeClass, mime, size, dimensions); }); }); - connect(text_input_, - &TextInputWidget::uploadFile, - this, - [this](QSharedPointer dev, const QString &fn) { - QMimeDatabase db; - QMimeType mime = db.mimeTypeForData(dev.data()); - - if (!dev->open(QIODevice::ReadOnly)) { - emit uploadFailed( - QString("Error while reading media: %1").arg(dev->errorString())); - return; - } - - auto bin = dev->readAll(); - auto payload = std::string(bin.data(), bin.size()); - - http::client()->upload( - payload, - mime.name().toStdString(), - QFileInfo(fn).fileName().toStdString(), - [this, - room_id = current_room_, - filename = fn, - mime = mime.name(), - size = payload.size()](const mtx::responses::ContentURI &res, - mtx::http::RequestErr err) { - if (err) { - emit uploadFailed( - tr("Failed to upload file. Please try again.")); - nhlog::net()->warn("failed to upload file: {} ({})", - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - emit fileUploaded(room_id, - filename, - QString::fromStdString(res.content_uri), - mime, - size); - }); - }); - - connect(text_input_, - &TextInputWidget::uploadAudio, - this, - [this](QSharedPointer dev, const QString &fn) { - QMimeDatabase db; - QMimeType mime = db.mimeTypeForData(dev.data()); - - if (!dev->open(QIODevice::ReadOnly)) { - emit uploadFailed( - QString("Error while reading media: %1").arg(dev->errorString())); - return; - } - - auto bin = dev->readAll(); - auto payload = std::string(bin.data(), bin.size()); - - http::client()->upload( - payload, - mime.name().toStdString(), - QFileInfo(fn).fileName().toStdString(), - [this, - room_id = current_room_, - filename = fn, - mime = mime.name(), - size = payload.size()](const mtx::responses::ContentURI &res, - mtx::http::RequestErr err) { - if (err) { - emit uploadFailed( - tr("Failed to upload audio. Please try again.")); - nhlog::net()->warn("failed to upload audio: {} ({})", - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - emit audioUploaded(room_id, - filename, - QString::fromStdString(res.content_uri), - mime, - size); - }); - }); - connect(text_input_, - &TextInputWidget::uploadVideo, - this, - [this](QSharedPointer dev, const QString &fn) { - QMimeDatabase db; - QMimeType mime = db.mimeTypeForData(dev.data()); - - if (!dev->open(QIODevice::ReadOnly)) { - emit uploadFailed( - QString("Error while reading media: %1").arg(dev->errorString())); - return; - } - - auto bin = dev->readAll(); - auto payload = std::string(bin.data(), bin.size()); - - http::client()->upload( - payload, - mime.name().toStdString(), - QFileInfo(fn).fileName().toStdString(), - [this, - room_id = current_room_, - filename = fn, - mime = mime.name(), - size = payload.size()](const mtx::responses::ContentURI &res, - mtx::http::RequestErr err) { - if (err) { - emit uploadFailed( - tr("Failed to upload video. Please try again.")); - nhlog::net()->warn("failed to upload video: {} ({})", - err->matrix_error.error, - static_cast(err->status_code)); - return; - } - - emit videoUploaded(room_id, - filename, - QString::fromStdString(res.content_uri), - mime, - size); - }); - }); - connect(this, &ChatPage::uploadFailed, this, [this](const QString &msg) { text_input_->hideUploadSpinner(); emit showNotification(msg); }); connect(this, - &ChatPage::imageUploaded, + &ChatPage::mediaUploaded, this, [this](QString roomid, QString filename, + boost::optional encryptedFile, QString url, + QString mimeClass, QString mime, qint64 dsize, QSize dimensions) { text_input_->hideUploadSpinner(); - view_manager_->queueImageMessage( - roomid, filename, url, mime, dsize, dimensions); - }); - connect(this, - &ChatPage::fileUploaded, - this, - [this](QString roomid, QString filename, QString url, QString mime, qint64 dsize) { - text_input_->hideUploadSpinner(); - view_manager_->queueFileMessage(roomid, filename, url, mime, dsize); - }); - connect(this, - &ChatPage::audioUploaded, - this, - [this](QString roomid, QString filename, QString url, QString mime, qint64 dsize) { - text_input_->hideUploadSpinner(); - view_manager_->queueAudioMessage(roomid, filename, url, mime, dsize); - }); - connect(this, - &ChatPage::videoUploaded, - this, - [this](QString roomid, QString filename, QString url, QString mime, qint64 dsize) { - text_input_->hideUploadSpinner(); - view_manager_->queueVideoMessage(roomid, filename, url, mime, dsize); + + if (mimeClass == "image") + view_manager_->queueImageMessage( + roomid, filename, encryptedFile, url, mime, dsize, dimensions); + else if (mimeClass == "audio") + view_manager_->queueAudioMessage( + roomid, filename, encryptedFile, url, mime, dsize); + else if (mimeClass == "video") + view_manager_->queueVideoMessage( + roomid, filename, encryptedFile, url, mime, dsize); + else + view_manager_->queueFileMessage( + roomid, filename, encryptedFile, url, mime, dsize); }); connect(room_list_, &RoomList::roomAvatarChanged, this, &ChatPage::updateTopBarAvatar); diff --git a/src/ChatPage.h b/src/ChatPage.h index 1898f1a7..20e156af 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -18,7 +18,9 @@ #pragma once #include +#include #include +#include #include #include @@ -94,27 +96,14 @@ signals: const QPoint widgetPos); void uploadFailed(const QString &msg); - void imageUploaded(const QString &roomid, + void mediaUploaded(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, + const QString &mimeClass, const QString &mime, qint64 dsize, const QSize &dimensions); - void fileUploaded(const QString &roomid, - const QString &filename, - const QString &url, - const QString &mime, - qint64 dsize); - void audioUploaded(const QString &roomid, - const QString &filename, - const QString &url, - const QString &mime, - qint64 dsize); - void videoUploaded(const QString &roomid, - const QString &filename, - const QString &url, - const QString &mime, - qint64 dsize); void contentLoaded(); void closing(); diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index f723c01a..66700dbc 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -458,21 +458,16 @@ FilteredTextEdit::textChanged() } void -FilteredTextEdit::uploadData(const QByteArray data, const QString &media, const QString &filename) +FilteredTextEdit::uploadData(const QByteArray data, + const QString &mediaType, + const QString &filename) { QSharedPointer buffer{new QBuffer{this}}; buffer->setData(data); emit startedUpload(); - if (media == "image") - emit image(buffer, filename); - else if (media == "audio") - emit audio(buffer, filename); - else if (media == "video") - emit video(buffer, filename); - else - emit file(buffer, filename); + emit media(buffer, mediaType, filename); } void @@ -580,10 +575,7 @@ TextInputWidget::TextInputWidget(QWidget *parent) connect(input_, &FilteredTextEdit::message, this, &TextInputWidget::sendTextMessage); connect(input_, &FilteredTextEdit::reply, this, &TextInputWidget::sendReplyMessage); connect(input_, &FilteredTextEdit::command, this, &TextInputWidget::command); - connect(input_, &FilteredTextEdit::image, this, &TextInputWidget::uploadImage); - connect(input_, &FilteredTextEdit::audio, this, &TextInputWidget::uploadAudio); - connect(input_, &FilteredTextEdit::video, this, &TextInputWidget::uploadVideo); - connect(input_, &FilteredTextEdit::file, this, &TextInputWidget::uploadFile); + connect(input_, &FilteredTextEdit::media, this, &TextInputWidget::uploadMedia); connect(emojiBtn_, SIGNAL(emojiSelected(const QString &)), this, @@ -642,14 +634,8 @@ TextInputWidget::openFileSelection() const auto format = mime.name().split("/")[0]; QSharedPointer file{new QFile{fileName, this}}; - if (format == "image") - emit uploadImage(file, fileName); - else if (format == "audio") - emit uploadAudio(file, fileName); - else if (format == "video") - emit uploadVideo(file, fileName); - else - emit uploadFile(file, fileName); + + emit uploadMedia(file, format, fileName); showUploadSpinner(); } diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 71f794d1..d498be72 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -63,10 +63,7 @@ signals: void message(QString); void reply(QString, const RelatedInfo &); void command(QString name, QString args); - void image(QSharedPointer data, const QString &filename); - void audio(QSharedPointer data, const QString &filename); - void video(QSharedPointer data, const QString &filename); - void file(QSharedPointer data, const QString &filename); + void media(QSharedPointer data, QString mimeClass, const QString &filename); //! Trigger the suggestion popup. void showSuggestions(const QString &query); @@ -179,10 +176,9 @@ signals: void sendEmoteMessage(QString msg); void heightChanged(int height); - void uploadImage(const QSharedPointer data, const QString &filename); - void uploadFile(const QSharedPointer data, const QString &filename); - void uploadAudio(const QSharedPointer data, const QString &filename); - void uploadVideo(const QSharedPointer data, const QString &filename); + void uploadMedia(const QSharedPointer data, + QString mimeClass, + const QString &filename); void sendJoinRoomRequest(const QString &room); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 25f72a6d..6e18d111 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -222,6 +222,7 @@ TimelineViewManager::queueEmoteMessage(const QString &msg) void TimelineViewManager::queueImageMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize, @@ -234,27 +235,32 @@ TimelineViewManager::queueImageMessage(const QString &roomid, image.url = url.toStdString(); image.info.h = dimensions.height(); image.info.w = dimensions.width(); + image.file = file; models.value(roomid)->sendMessage(image); } void -TimelineViewManager::queueFileMessage(const QString &roomid, - const QString &filename, - const QString &url, - const QString &mime, - uint64_t dsize) +TimelineViewManager::queueFileMessage( + const QString &roomid, + const QString &filename, + const boost::optional &encryptedFile, + const QString &url, + const QString &mime, + uint64_t dsize) { mtx::events::msg::File file; file.info.mimetype = mime.toStdString(); file.info.size = dsize; file.body = filename.toStdString(); file.url = url.toStdString(); + file.file = encryptedFile; models.value(roomid)->sendMessage(file); } void TimelineViewManager::queueAudioMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize) @@ -264,12 +270,14 @@ TimelineViewManager::queueAudioMessage(const QString &roomid, audio.info.size = dsize; audio.body = filename.toStdString(); audio.url = url.toStdString(); + audio.file = file; models.value(roomid)->sendMessage(audio); } void TimelineViewManager::queueVideoMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize) @@ -279,5 +287,6 @@ TimelineViewManager::queueVideoMessage(const QString &roomid, video.info.size = dsize; video.body = filename.toStdString(); video.url = url.toStdString(); + video.file = file; models.value(roomid)->sendMessage(video); } diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 1cb0de44..9e8de616 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -5,6 +5,7 @@ #include #include +#include #include #include "Cache.h" @@ -55,22 +56,26 @@ public slots: void queueEmoteMessage(const QString &msg); void queueImageMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize, const QSize &dimensions); void queueFileMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize); void queueAudioMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize); void queueVideoMessage(const QString &roomid, const QString &filename, + const boost::optional &file, const QString &url, const QString &mime, uint64_t dsize); -- cgit 1.5.1 From 4ca8da9a892ad614a4a79d0a63a938d0f4a869ae Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 12 Jan 2020 16:39:01 +0100 Subject: Allow replying with an image --- deps/CMakeLists.txt | 4 +- src/ChatPage.cpp | 89 +++++++++++++++++++----------------- src/ChatPage.h | 3 +- src/TextInputWidget.cpp | 37 +++++++-------- src/TextInputWidget.h | 39 ++++++++-------- src/timeline/TimelineViewManager.cpp | 68 +++++++++++++++------------ src/timeline/TimelineViewManager.h | 15 +++--- 7 files changed, 135 insertions(+), 120 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 23a9ed25..f4d454a0 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -46,10 +46,10 @@ set(BOOST_SHA256 set( MTXCLIENT_URL - https://github.com/Nheko-Reborn/mtxclient/archive/9fda08b222dc4f9f59da18ed8370698643131cdd.zip + https://github.com/Nheko-Reborn/mtxclient/archive/6d2a02b6079c9d888c28cd24504618aaadb7fa97.zip ) set(MTXCLIENT_HASH - 9a9da7a9e0ede51d36238b54be03782892d47233a1ba2ce7d36614ad2ed6a6c1) + 30811e076ee1fee22ba5d5d92c94a5425ff714a7ccb245ff4ac64fecb04dc539) set( TWEENY_URL https://github.com/mobius3/tweeny/archive/b94ce07cfb02a0eb8ac8aaf66137dabdaea857cf.tar.gz diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index ad07efdd..777709be 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -56,6 +56,7 @@ constexpr int RETRY_TIMEOUT = 5'000; constexpr size_t MAX_ONETIME_KEYS = 50; Q_DECLARE_METATYPE(std::optional) +Q_DECLARE_METATYPE(std::optional) ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) : QWidget(parent) @@ -65,8 +66,8 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) { setObjectName("chatPage"); - qRegisterMetaType>( - "std::optional"); + qRegisterMetaType>(); + qRegisterMetaType>(); topLayout_ = new QHBoxLayout(this); topLayout_->setSpacing(0); @@ -287,19 +288,14 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) SLOT(showUnreadMessageNotification(int))); connect(text_input_, - SIGNAL(sendTextMessage(const QString &)), + &TextInputWidget::sendTextMessage, view_manager_, - SLOT(queueTextMessage(const QString &))); + &TimelineViewManager::queueTextMessage); connect(text_input_, - SIGNAL(sendReplyMessage(const QString &, const RelatedInfo &)), + &TextInputWidget::sendEmoteMessage, view_manager_, - SLOT(queueReplyMessage(const QString &, const RelatedInfo &))); - - connect(text_input_, - SIGNAL(sendEmoteMessage(const QString &)), - view_manager_, - SLOT(queueEmoteMessage(const QString &))); + &TimelineViewManager::queueEmoteMessage); connect(text_input_, &TextInputWidget::sendJoinRoomRequest, this, &ChatPage::joinRoom); @@ -307,7 +303,10 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) text_input_, &TextInputWidget::uploadMedia, this, - [this](QSharedPointer dev, QString mimeClass, const QString &fn) { + [this](QSharedPointer dev, + QString mimeClass, + const QString &fn, + const std::optional &related) { QMimeDatabase db; QMimeType mime = db.mimeTypeForData(dev.data()); @@ -341,7 +340,8 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) mimeClass, mime = mime.name(), size = payload.size(), - dimensions](const mtx::responses::ContentURI &res, mtx::http::RequestErr err) { + dimensions, + related](const mtx::responses::ContentURI &res, mtx::http::RequestErr err) { if (err) { emit uploadFailed( tr("Failed to upload media. Please try again.")); @@ -359,7 +359,8 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) mimeClass, mime, size, - dimensions); + dimensions, + related); }); }); @@ -367,35 +368,37 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) text_input_->hideUploadSpinner(); emit showNotification(msg); }); - connect(this, - &ChatPage::mediaUploaded, - this, - [this](QString roomid, - QString filename, - std::optional encryptedFile, - QString url, - QString mimeClass, - QString mime, - qint64 dsize, - QSize dimensions) { - text_input_->hideUploadSpinner(); - - if (encryptedFile) - encryptedFile->url = url.toStdString(); - - if (mimeClass == "image") - view_manager_->queueImageMessage( - roomid, filename, encryptedFile, url, mime, dsize, dimensions); - else if (mimeClass == "audio") - view_manager_->queueAudioMessage( - roomid, filename, encryptedFile, url, mime, dsize); - else if (mimeClass == "video") - view_manager_->queueVideoMessage( - roomid, filename, encryptedFile, url, mime, dsize); - else - view_manager_->queueFileMessage( - roomid, filename, encryptedFile, url, mime, dsize); - }); + connect( + this, + &ChatPage::mediaUploaded, + this, + [this](QString roomid, + QString filename, + std::optional encryptedFile, + QString url, + QString mimeClass, + QString mime, + qint64 dsize, + QSize dimensions, + const std::optional &related) { + text_input_->hideUploadSpinner(); + + if (encryptedFile) + encryptedFile->url = url.toStdString(); + + if (mimeClass == "image") + view_manager_->queueImageMessage( + roomid, filename, encryptedFile, url, mime, dsize, dimensions, related); + else if (mimeClass == "audio") + view_manager_->queueAudioMessage( + roomid, filename, encryptedFile, url, mime, dsize, related); + else if (mimeClass == "video") + view_manager_->queueVideoMessage( + roomid, filename, encryptedFile, url, mime, dsize, related); + else + view_manager_->queueFileMessage( + roomid, filename, encryptedFile, url, mime, dsize, related); + }); connect(room_list_, &RoomList::roomAvatarChanged, this, &ChatPage::updateTopBarAvatar); diff --git a/src/ChatPage.h b/src/ChatPage.h index 9e88dcc6..e4c0ef16 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -109,7 +109,8 @@ signals: const QString &mimeClass, const QString &mime, qint64 dsize, - const QSize &dimensions); + const QSize &dimensions, + const std::optional &related); void contentLoaded(); void closing(); diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index b481a57c..b6b51980 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -419,33 +419,25 @@ FilteredTextEdit::submit() auto name = text.mid(1, command_end - 1); auto args = text.mid(command_end + 1); if (name.isEmpty() || name == "/") { - if (!related_.related_event.empty()) { - reply(args, related_); - } else { - message(args); - } + message(args, related); } else { command(name, args); } } else { - if (!related_.related_event.empty()) { - reply(std::move(text), std::move(related_)); - } else { - message(std::move(text)); - } + message(std::move(text), std::move(related)); } - related_ = {}; + related = {}; clear(); } void -FilteredTextEdit::showReplyPopup(const RelatedInfo &related) +FilteredTextEdit::showReplyPopup(const RelatedInfo &related_) { QPoint pos = viewport()->mapToGlobal(this->pos()); - replyPopup_.setReplyContent(related); + replyPopup_.setReplyContent(related_); replyPopup_.move(pos.x(), pos.y() - replyPopup_.height() - 10); replyPopup_.setFixedWidth(this->parentWidget()->width()); replyPopup_.show(); @@ -467,7 +459,9 @@ FilteredTextEdit::uploadData(const QByteArray data, emit startedUpload(); - emit media(buffer, mediaType, filename); + emit media(buffer, mediaType, filename, related); + related = {}; + closeReply(); } void @@ -573,7 +567,6 @@ TextInputWidget::TextInputWidget(QWidget *parent) connect(sendMessageBtn_, &FlatButton::clicked, input_, &FilteredTextEdit::submit); connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection())); connect(input_, &FilteredTextEdit::message, this, &TextInputWidget::sendTextMessage); - connect(input_, &FilteredTextEdit::reply, this, &TextInputWidget::sendReplyMessage); connect(input_, &FilteredTextEdit::command, this, &TextInputWidget::command); connect(input_, &FilteredTextEdit::media, this, &TextInputWidget::uploadMedia); connect(emojiBtn_, @@ -609,14 +602,16 @@ void TextInputWidget::command(QString command, QString args) { if (command == "me") { - sendEmoteMessage(args); + sendEmoteMessage(args, input_->related); } else if (command == "join") { sendJoinRoomRequest(args); } else if (command == "shrug") { - sendTextMessage("¯\\_(ツ)_/¯"); + sendTextMessage("¯\\_(ツ)_/¯", input_->related); } else if (command == "fliptable") { - sendTextMessage("(╯°□°)╯︵ ┻━┻"); + sendTextMessage("(╯°□°)╯︵ ┻━┻", input_->related); } + + input_->related = std::nullopt; } void @@ -635,7 +630,9 @@ TextInputWidget::openFileSelection() QSharedPointer file{new QFile{fileName, this}}; - emit uploadMedia(file, format, fileName); + emit uploadMedia(file, format, fileName, input_->related); + input_->related = {}; + input_->closeReply(); showUploadSpinner(); } @@ -691,5 +688,5 @@ TextInputWidget::addReply(const RelatedInfo &related) auto cursor = input_->textCursor(); cursor.movePosition(QTextCursor::End); input_->setTextCursor(cursor); - input_->setRelated(related); + input_->related = related; } diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index d498be72..6641d97c 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -52,18 +53,27 @@ public: QSize minimumSizeHint() const override; void submit(); - void setRelated(const RelatedInfo &related) { related_ = related; } - void showReplyPopup(const RelatedInfo &related); + void showReplyPopup(const RelatedInfo &related_); + void closeReply() + { + replyPopup_.hide(); + related = {}; + } + + // Used for replies + std::optional related; signals: void heightChanged(int height); void startedTyping(); void stoppedTyping(); void startedUpload(); - void message(QString); - void reply(QString, const RelatedInfo &); + void message(QString, const std::optional &); void command(QString name, QString args); - void media(QSharedPointer data, QString mimeClass, const QString &filename); + void media(QSharedPointer data, + QString mimeClass, + const QString &filename, + const std::optional &related); //! Trigger the suggestion popup. void showSuggestions(const QString &query); @@ -93,9 +103,6 @@ private: SuggestionsPopup suggestionsPopup_; ReplyPopup replyPopup_; - // Used for replies - RelatedInfo related_; - enum class AnchorType { Tab = 0, @@ -107,11 +114,6 @@ private: int anchorWidth(AnchorType anchor) { return static_cast(anchor); } void closeSuggestions() { suggestionsPopup_.hide(); } - void closeReply() - { - replyPopup_.hide(); - related_ = {}; - } void resetAnchor() { atTriggerPosition_ = -1; } bool isAnchorValid() { return atTriggerPosition_ != -1; } bool hasAnchor(int pos, AnchorType anchor) @@ -171,14 +173,14 @@ private slots: void addSelectedEmoji(const QString &emoji); signals: - void sendTextMessage(QString msg); - void sendReplyMessage(QString msg, const RelatedInfo &related); - void sendEmoteMessage(QString msg); + void sendTextMessage(const QString &msg, const std::optional &related); + void sendEmoteMessage(QString msg, const std::optional &related); void heightChanged(int height); void uploadMedia(const QSharedPointer data, QString mimeClass, - const QString &filename); + const QString &filename, + const std::optional &related); void sendJoinRoomRequest(const QString &room); @@ -196,9 +198,6 @@ private: QHBoxLayout *topLayout_; FilteredTextEdit *input_; - // Used for replies - QString related_event_; - LoadingIndicator *spinner_; FlatButton *sendFileBtn_; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 8cb204a6..cd2b4a7b 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -170,38 +170,30 @@ TimelineViewManager::initWithMessages(const std::map &related) { mtx::events::msg::Text text = {}; text.body = msg.trimmed().toStdString(); text.format = "org.matrix.custom.html"; text.formatted_body = utils::markdownToHtml(msg).toStdString(); - if (timeline_) - timeline_->sendMessage(text); -} - -void -TimelineViewManager::queueReplyMessage(const QString &reply, const RelatedInfo &related) -{ - mtx::events::msg::Text text = {}; - - QString body; - bool firstLine = true; - for (const auto &line : related.quoted_body.split("\n")) { - if (firstLine) { - firstLine = false; - body = QString("> <%1> %2\n").arg(related.quoted_user).arg(line); - } else { - body = QString("%1\n> %2\n").arg(body).arg(line); + if (related) { + QString body; + bool firstLine = true; + for (const auto &line : related->quoted_body.split("\n")) { + if (firstLine) { + firstLine = false; + body = QString("> <%1> %2\n").arg(related->quoted_user).arg(line); + } else { + body = QString("%1\n> %2\n").arg(body).arg(line); + } } - } - text.body = QString("%1\n%2").arg(body).arg(reply).toStdString(); - text.format = "org.matrix.custom.html"; - text.formatted_body = - utils::getFormattedQuoteBody(related, utils::markdownToHtml(reply)).toStdString(); - text.relates_to.in_reply_to.event_id = related.related_event; + text.body = QString("%1\n%2").arg(body).arg(msg).toStdString(); + text.formatted_body = + utils::getFormattedQuoteBody(*related, utils::markdownToHtml(msg)).toStdString(); + text.relates_to.in_reply_to.event_id = related->related_event; + } if (timeline_) timeline_->sendMessage(text); @@ -229,7 +221,8 @@ TimelineViewManager::queueImageMessage(const QString &roomid, const QString &url, const QString &mime, uint64_t dsize, - const QSize &dimensions) + const QSize &dimensions, + const std::optional &related) { mtx::events::msg::Image image; image.info.mimetype = mime.toStdString(); @@ -239,6 +232,10 @@ TimelineViewManager::queueImageMessage(const QString &roomid, image.info.h = dimensions.height(); image.info.w = dimensions.width(); image.file = file; + + if (related) + image.relates_to.in_reply_to.event_id = related->related_event; + models.value(roomid)->sendMessage(image); } @@ -249,7 +246,8 @@ TimelineViewManager::queueFileMessage( const std::optional &encryptedFile, const QString &url, const QString &mime, - uint64_t dsize) + uint64_t dsize, + const std::optional &related) { mtx::events::msg::File file; file.info.mimetype = mime.toStdString(); @@ -257,6 +255,10 @@ TimelineViewManager::queueFileMessage( file.body = filename.toStdString(); file.url = url.toStdString(); file.file = encryptedFile; + + if (related) + file.relates_to.in_reply_to.event_id = related->related_event; + models.value(roomid)->sendMessage(file); } @@ -266,7 +268,8 @@ TimelineViewManager::queueAudioMessage(const QString &roomid, const std::optional &file, const QString &url, const QString &mime, - uint64_t dsize) + uint64_t dsize, + const std::optional &related) { mtx::events::msg::Audio audio; audio.info.mimetype = mime.toStdString(); @@ -274,6 +277,10 @@ TimelineViewManager::queueAudioMessage(const QString &roomid, audio.body = filename.toStdString(); audio.url = url.toStdString(); audio.file = file; + + if (related) + audio.relates_to.in_reply_to.event_id = related->related_event; + models.value(roomid)->sendMessage(audio); } @@ -283,7 +290,8 @@ TimelineViewManager::queueVideoMessage(const QString &roomid, const std::optional &file, const QString &url, const QString &mime, - uint64_t dsize) + uint64_t dsize, + const std::optional &related) { mtx::events::msg::Video video; video.info.mimetype = mime.toStdString(); @@ -291,5 +299,9 @@ TimelineViewManager::queueVideoMessage(const QString &roomid, video.body = filename.toStdString(); video.url = url.toStdString(); video.file = file; + + if (related) + video.relates_to.in_reply_to.event_id = related->related_event; + models.value(roomid)->sendMessage(video); } diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 587aa14e..63075649 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -51,8 +51,7 @@ public slots: void setHistoryView(const QString &room_id); void updateColorPalette(); - void queueTextMessage(const QString &msg); - void queueReplyMessage(const QString &reply, const RelatedInfo &related); + void queueTextMessage(const QString &msg, const std::optional &related); void queueEmoteMessage(const QString &msg); void queueImageMessage(const QString &roomid, const QString &filename, @@ -60,25 +59,29 @@ public slots: const QString &url, const QString &mime, uint64_t dsize, - const QSize &dimensions); + const QSize &dimensions, + const std::optional &related); void queueFileMessage(const QString &roomid, const QString &filename, const std::optional &file, const QString &url, const QString &mime, - uint64_t dsize); + uint64_t dsize, + const std::optional &related); void queueAudioMessage(const QString &roomid, const QString &filename, const std::optional &file, const QString &url, const QString &mime, - uint64_t dsize); + uint64_t dsize, + const std::optional &related); void queueVideoMessage(const QString &roomid, const QString &filename, const std::optional &file, const QString &url, const QString &mime, - uint64_t dsize); + uint64_t dsize, + const std::optional &related); private: #ifdef USE_QUICK_VIEW -- cgit 1.5.1 From b0ff1baa1d1c38523b5479a5191a5559f4c21bf6 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 29 Jan 2020 00:30:53 +0100 Subject: Add command for invite,kick,ban and unban --- CMakeLists.txt | 2 +- resources/langs/nheko_de.ts | 101 +++++++++++++++++++++++++++++++++++------ resources/langs/nheko_el.ts | 101 +++++++++++++++++++++++++++++++++++------ resources/langs/nheko_en.ts | 101 +++++++++++++++++++++++++++++++++++------ resources/langs/nheko_fi.ts | 101 +++++++++++++++++++++++++++++++++++------ resources/langs/nheko_fr.ts | 101 +++++++++++++++++++++++++++++++++++------ resources/langs/nheko_nl.ts | 101 +++++++++++++++++++++++++++++++++++------ resources/langs/nheko_pl.ts | 101 +++++++++++++++++++++++++++++++++++------ resources/langs/nheko_ru.ts | 101 +++++++++++++++++++++++++++++++++++------ resources/langs/nheko_zh_CN.ts | 101 +++++++++++++++++++++++++++++++++++------ src/ChatPage.cpp | 99 ++++++++++++++++++++++++++++++++++++---- src/TextInputWidget.cpp | 8 ++++ src/TextInputWidget.h | 4 ++ 13 files changed, 877 insertions(+), 145 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/CMakeLists.txt b/CMakeLists.txt index d5faa4a9..c2496f2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -333,7 +333,7 @@ if(USE_BUNDLED_MTXCLIENT) FetchContent_Declare( MatrixClient GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git - GIT_TAG 1fd59de2a37e6b547db8e5b52114f3f10171ef2f + GIT_TAG 03b5008a05f895e91e3968de7b68db50f6c41b2a ) FetchContent_MakeAvailable(MatrixClient) else() diff --git a/resources/langs/nheko_de.ts b/resources/langs/nheko_de.ts index e4271a6e..32526797 100644 --- a/resources/langs/nheko_de.ts +++ b/resources/langs/nheko_de.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. Medienupload fehlgeschlagen. Bitte versuche es erneut. @@ -25,17 +71,37 @@ - + Please try to login again: %1 Bitte melde dich erneut an: %1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 Raum konnte nicht erstellt werden: %1 - + + Room %1 created + + + + Failed to leave room: %1 Konnte den Raum nicht verlassen: %1 @@ -385,7 +451,7 @@ Emoji - + Select a file Datei auswählen @@ -403,7 +469,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted -- verschlüsselter Event (keine Schlüssel zur Entschlüsselung gefunden) -- @@ -646,42 +712,47 @@ UserSettingsPage - + Minimize to tray Ins Benachrichtigungsfeld minimieren - + Start in tray Im Benachrichtigungsfeld starten - + Group's sidebar Gruppen-Seitenleiste - + Circular Avatars Runde Profilbilder - + Typing notifications Schreibbenachrichtigungen - + Read receipts Lesebestätigungen - + + Send messages as markdown + + + + Desktop notifications Desktopbenachrichtigungen - + Scale factor Skalierungsfaktor @@ -741,7 +812,7 @@ ALLGEMEINES - + Open Sessions File Öffne Sessions Datei diff --git a/resources/langs/nheko_el.ts b/resources/langs/nheko_el.ts index 982a14ac..4344c568 100644 --- a/resources/langs/nheko_el.ts +++ b/resources/langs/nheko_el.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. @@ -25,17 +71,37 @@ - + Please try to login again: %1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 - + + Room %1 created + + + + Failed to leave room: %1 @@ -385,7 +451,7 @@ - + Select a file Διάλεξε ένα αρχείο @@ -403,7 +469,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -646,42 +712,47 @@ UserSettingsPage - + Minimize to tray Ελαχιστοποίηση - + Start in tray - + Group's sidebar - + Circular Avatars - + Typing notifications - + Read receipts - + + Send messages as markdown + + + + Desktop notifications - + Scale factor @@ -741,7 +812,7 @@ ΓΕΝΙΚΑ - + Open Sessions File diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index 60b1fe3d..fee87ffb 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. @@ -25,17 +71,37 @@ - + Please try to login again: %1 Please try to login again: %1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 Room creation failed: %1 - + + Room %1 created + + + + Failed to leave room: %1 Failed to leave room: %1 @@ -385,7 +451,7 @@ Emoji - + Select a file Select a file @@ -403,7 +469,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted -- Encrypted Event (No keys found for decryption) -- @@ -646,42 +712,47 @@ UserSettingsPage - + Minimize to tray Minimize to tray - + Start in tray Start in tray - + Group's sidebar Group's sidebar - + Circular Avatars - + Typing notifications Typing notifications - + Read receipts Read receipts - + + Send messages as markdown + + + + Desktop notifications Desktop notifications - + Scale factor Scale factor @@ -741,7 +812,7 @@ GENERAL - + Open Sessions File Open Sessions File diff --git a/resources/langs/nheko_fi.ts b/resources/langs/nheko_fi.ts index b4b184c9..f6e2756c 100644 --- a/resources/langs/nheko_fi.ts +++ b/resources/langs/nheko_fi.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. @@ -25,17 +71,37 @@ - + Please try to login again: %1 Ole hyvä ja yritä kirjautua sisään uudelleen: %1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 Huoneen luominen epäonnistui: %1 - + + Room %1 created + + + + Failed to leave room: %1 Huoneesta poistuminen epäonnistui: %1 @@ -385,7 +451,7 @@ Emoji - + Select a file Valitse tiedosto @@ -403,7 +469,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted -- Salattu viesti (salauksen purkuavaimia ei löydetty) -- @@ -646,42 +712,47 @@ UserSettingsPage - + Minimize to tray Pienennä ilmoitusalueelle - + Start in tray Aloita ilmoitusalueella - + Group's sidebar Ryhmäsivupalkki - + Circular Avatars - + Typing notifications Kirjoitusilmoitukset - + Read receipts Lukukuittaukset - + + Send messages as markdown + + + + Desktop notifications Työpöytäilmoitukset - + Scale factor Mittakerroin @@ -741,7 +812,7 @@ YLEISET ASETUKSET - + Open Sessions File Avaa Istuntoavaintiedosto diff --git a/resources/langs/nheko_fr.ts b/resources/langs/nheko_fr.ts index c713dcb1..89dd8cdd 100644 --- a/resources/langs/nheko_fr.ts +++ b/resources/langs/nheko_fr.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. @@ -25,17 +71,37 @@ - + Please try to login again: %1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 - + + Room %1 created + + + + Failed to leave room: %1 @@ -386,7 +452,7 @@ - + Select a file Sélectionnez un fichier @@ -404,7 +470,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -647,42 +713,47 @@ UserSettingsPage - + Minimize to tray Réduire à la barre des tâches - + Start in tray Démarrer dans la barre des tâches - + Group's sidebar Barre latérale des groupes - + Circular Avatars - + Typing notifications Notifications d'écriture - + Read receipts Accusés de lecture - + + Send messages as markdown + + + + Desktop notifications - + Scale factor @@ -742,7 +813,7 @@ GÉNÉRAL - + Open Sessions File diff --git a/resources/langs/nheko_nl.ts b/resources/langs/nheko_nl.ts index 82b0f881..2aa5de74 100644 --- a/resources/langs/nheko_nl.ts +++ b/resources/langs/nheko_nl.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. @@ -25,17 +71,37 @@ - + Please try to login again: %1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 - + + Room %1 created + + + + Failed to leave room: %1 @@ -385,7 +451,7 @@ - + Select a file Kies een bestand @@ -403,7 +469,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -646,42 +712,47 @@ UserSettingsPage - + Minimize to tray Minimaliseren naar systeemvak - + Start in tray Geminimaliseerd opstarten - + Group's sidebar Zijbalk van groep - + Circular Avatars - + Typing notifications Meldingen bij typen van berichten - + Read receipts Leesbevestigingen - + + Send messages as markdown + + + + Desktop notifications - + Scale factor @@ -741,7 +812,7 @@ ALGEMEEN - + Open Sessions File diff --git a/resources/langs/nheko_pl.ts b/resources/langs/nheko_pl.ts index 6fb2133b..88dfe2b9 100644 --- a/resources/langs/nheko_pl.ts +++ b/resources/langs/nheko_pl.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. @@ -25,17 +71,37 @@ - + Please try to login again: %1 Spróbuj zalogować się ponownie: %1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 Tworzenie pokoju nie powiodło się: %1 - + + Room %1 created + + + + Failed to leave room: %1 Nie udało się opuścić pokoju: %1 @@ -385,7 +451,7 @@ Emoji - + Select a file Wybierz plik @@ -403,7 +469,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -647,42 +713,47 @@ UserSettingsPage - + Minimize to tray Zminimalizuj do paska zadań - + Start in tray Rozpocznij na pasku zadań - + Group's sidebar Pasek boczny grupy - + Circular Avatars - + Typing notifications Powiadomienia o pisaniu - + Read receipts Potwierdzenia przeczytania - + + Send messages as markdown + + + + Desktop notifications Powiadomienia na pulpicie - + Scale factor @@ -742,7 +813,7 @@ OGÓLNE - + Open Sessions File diff --git a/resources/langs/nheko_ru.ts b/resources/langs/nheko_ru.ts index 1b84074f..07e169f7 100644 --- a/resources/langs/nheko_ru.ts +++ b/resources/langs/nheko_ru.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. @@ -25,17 +71,37 @@ - + Please try to login again: %1 Повторите попытку входа: %1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 Не удалось создать комнату: %1 - + + Room %1 created + + + + Failed to leave room: %1 Не удалось покинуть комнату: %1 @@ -385,7 +451,7 @@ - + Select a file Выберите файл @@ -403,7 +469,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -647,42 +713,47 @@ UserSettingsPage - + Minimize to tray Сворачивать в системную панель - + Start in tray Запускать в системной панели - + Group's sidebar Боковая панель групп - + Circular Avatars - + Typing notifications Сообщать о наборе сообщения - + Read receipts Подтверждать прочтение - + + Send messages as markdown + + + + Desktop notifications Уведомления на рабочем столе - + Scale factor Масштаб @@ -742,7 +813,7 @@ ГЛАВНОЕ - + Open Sessions File Открыть файл сеансов diff --git a/resources/langs/nheko_zh_CN.ts b/resources/langs/nheko_zh_CN.ts index f8b19434..c7e42fba 100644 --- a/resources/langs/nheko_zh_CN.ts +++ b/resources/langs/nheko_zh_CN.ts @@ -4,7 +4,53 @@ ChatPage - + + Failed to invite user: %1 + + + + + + Invited user: %1 + + + + + Failed to invite %1 to %2: %3 + + + + + Failed to kick %1 to %2: %3 + + + + + Kicked user: %1 + + + + + Failed to ban %1 in %2: %3 + + + + + Banned user: %1 + + + + + Failed to unban %1 in %2: %3 + + + + + Unbanned user: %1 + + + + Failed to upload media. Please try again. @@ -25,17 +71,37 @@ - + Please try to login again: %1 请尝试再次登录:%1 - + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + Room creation failed: %1 创建聊天室失败:%1 - + + Room %1 created + + + + Failed to leave room: %1 离开聊天室失败:%1 @@ -385,7 +451,7 @@ - + Select a file 选择一个文件 @@ -403,7 +469,7 @@ TimelineModel - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted @@ -645,42 +711,47 @@ UserSettingsPage - + Minimize to tray 最小化至托盘 - + Start in tray 在托盘启动 - + Group's sidebar 群组侧边栏 - + Circular Avatars - + Typing notifications 打字通知 - + Read receipts 阅读回执 - + + Send messages as markdown + + + + Desktop notifications 桌面通知 - + Scale factor @@ -740,7 +811,7 @@ 通用 - + Open Sessions File 打开会话文件 diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index c7739281..a337baac 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -208,12 +208,11 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) mtx::http::RequestErr err) { if (err) { emit showNotification( - QString("Failed to invite user: %1").arg(user)); + tr("Failed to invite user: %1").arg(user)); return; } - emit showNotification( - QString("Invited user: %1").arg(user)); + emit showNotification(tr("Invited user: %1").arg(user)); }); }); } @@ -280,6 +279,89 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(text_input_, &TextInputWidget::sendJoinRoomRequest, this, &ChatPage::joinRoom); + // invites and bans via quick command + connect(text_input_, + &TextInputWidget::sendInviteRoomRequest, + this, + [this](QString userid, QString reason) { + http::client()->invite_user( + current_room_.toStdString(), + userid.toStdString(), + [this, userid, room = current_room_](const mtx::responses::Empty &, + mtx::http::RequestErr err) { + if (err) { + emit showNotification(tr("Failed to invite %1 to %2: %3") + .arg(userid) + .arg(room) + .arg(QString::fromStdString( + err->matrix_error.error))); + } else + emit showNotification(tr("Invited user: %1").arg(userid)); + }, + reason.trimmed().toStdString()); + }); + connect(text_input_, + &TextInputWidget::sendKickRoomRequest, + this, + [this](QString userid, QString reason) { + http::client()->kick_user( + current_room_.toStdString(), + userid.toStdString(), + [this, userid, room = current_room_](const mtx::responses::Empty &, + mtx::http::RequestErr err) { + if (err) { + emit showNotification(tr("Failed to kick %1 to %2: %3") + .arg(userid) + .arg(room) + .arg(QString::fromStdString( + err->matrix_error.error))); + } else + emit showNotification(tr("Kicked user: %1").arg(userid)); + }, + reason.trimmed().toStdString()); + }); + connect(text_input_, + &TextInputWidget::sendBanRoomRequest, + this, + [this](QString userid, QString reason) { + http::client()->ban_user( + current_room_.toStdString(), + userid.toStdString(), + [this, userid, room = current_room_](const mtx::responses::Empty &, + mtx::http::RequestErr err) { + if (err) { + emit showNotification(tr("Failed to ban %1 in %2: %3") + .arg(userid) + .arg(room) + .arg(QString::fromStdString( + err->matrix_error.error))); + } else + emit showNotification(tr("Banned user: %1").arg(userid)); + }, + reason.trimmed().toStdString()); + }); + connect( + text_input_, + &TextInputWidget::sendUnbanRoomRequest, + this, + [this](QString userid, QString reason) { + http::client()->unban_user( + current_room_.toStdString(), + userid.toStdString(), + [this, userid, room = current_room_](const mtx::responses::Empty &, + mtx::http::RequestErr err) { + if (err) { + emit showNotification( + tr("Failed to unban %1 in %2: %3") + .arg(userid) + .arg(room) + .arg(QString::fromStdString(err->matrix_error.error))); + } else + emit showNotification(tr("Unbanned user: %1").arg(userid)); + }, + reason.trimmed().toStdString()); + }); + connect( text_input_, &TextInputWidget::uploadMedia, @@ -998,19 +1080,18 @@ ChatPage::joinRoom(const QString &room) room_id, [this, room_id](const nlohmann::json &, mtx::http::RequestErr err) { if (err) { emit showNotification( - QString("Failed to join room: %1") + tr("Failed to join room: %1") .arg(QString::fromStdString(err->matrix_error.error))); return; } - emit showNotification("You joined the room"); + emit tr("You joined the room"); // We remove any invites with the same room_id. try { cache::removeInvite(room_id); } catch (const lmdb::error &e) { - emit showNotification( - QString("Failed to remove invite: %1").arg(e.what())); + emit showNotification(tr("Failed to remove invite: %1").arg(e.what())); } }); } @@ -1033,8 +1114,8 @@ ChatPage::createRoom(const mtx::requests::CreateRoom &req) return; } - emit showNotification(QString("Room %1 created") - .arg(QString::fromStdString(res.room_id.to_string()))); + emit showNotification( + tr("Room %1 created").arg(QString::fromStdString(res.room_id.to_string()))); }); } diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index b6b51980..52686c0f 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -605,6 +605,14 @@ TextInputWidget::command(QString command, QString args) sendEmoteMessage(args, input_->related); } else if (command == "join") { sendJoinRoomRequest(args); + } else if (command == "invite") { + sendInviteRoomRequest(args.section(' ', 0, 0), args.section(' ', 1, -1)); + } else if (command == "kick") { + sendKickRoomRequest(args.section(' ', 0, 0), args.section(' ', 1, -1)); + } else if (command == "ban") { + sendBanRoomRequest(args.section(' ', 0, 0), args.section(' ', 1, -1)); + } else if (command == "unban") { + sendUnbanRoomRequest(args.section(' ', 0, 0), args.section(' ', 1, -1)); } else if (command == "shrug") { sendTextMessage("¯\\_(ツ)_/¯", input_->related); } else if (command == "fliptable") { diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 6641d97c..4bdb2509 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -183,6 +183,10 @@ signals: const std::optional &related); 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 startedTyping(); void stoppedTyping(); -- cgit 1.5.1 From 4cd260bfcfcbf88a6efb8bf5a1abf3d37fb06463 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 31 Jan 2020 06:12:02 +0100 Subject: Optimize includes a bit --- CMakeLists.txt | 1 + src/ChatPage.cpp | 4 +- src/CommunitiesList.cpp | 11 +++-- src/CommunitiesList.h | 5 ++ src/CommunitiesListItem.cpp | 3 ++ src/CommunitiesListItem.h | 7 +-- src/LoginPage.cpp | 1 + src/MainWindow.cpp | 3 +- src/RegisterPage.cpp | 1 + src/RoomInfoListItem.cpp | 6 +-- src/RoomList.cpp | 6 +-- src/SideBarActions.cpp | 8 ++-- src/SideBarActions.h | 2 +- src/Splitter.cpp | 22 +++++++-- src/Splitter.h | 16 ++++++- src/TextInputWidget.cpp | 5 +- src/TextInputWidget.h | 1 - src/TopRoomBar.cpp | 26 +++++++++- src/TopRoomBar.h | 35 +++++--------- src/TrayIcon.cpp | 2 + src/TrayIcon.h | 5 +- src/UserInfoWidget.cpp | 5 +- src/UserSettingsPage.cpp | 1 + src/Utils.cpp | 32 ++++++++----- src/Utils.h | 33 +------------ src/WelcomePage.cpp | 1 + src/dialogs/MemberList.cpp | 3 +- src/dialogs/UserProfile.cpp | 3 +- src/emoji/ItemDelegate.cpp | 1 - src/emoji/Panel.cpp | 1 + src/popups/UserMentions.h | 7 +-- src/timeline/TimelineModel.h | 8 ++-- src/ui/DropShadow.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++ src/ui/DropShadow.h | 100 ++------------------------------------- src/ui/FlatButton.cpp | 2 + src/ui/FlatButton.h | 2 - src/ui/FloatingButton.cpp | 1 + src/ui/LoadingIndicator.cpp | 5 +- src/ui/LoadingIndicator.h | 6 +-- src/ui/OverlayWidget.cpp | 4 +- src/ui/OverlayWidget.h | 4 +- 41 files changed, 271 insertions(+), 228 deletions(-) create mode 100644 src/ui/DropShadow.cpp (limited to 'src/TextInputWidget.h') diff --git a/CMakeLists.txt b/CMakeLists.txt index 96a6aec6..fe00d570 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,6 +256,7 @@ set(SRC_FILES # UI components src/ui/Avatar.cpp src/ui/Badge.cpp + src/ui/DropShadow.cpp src/ui/LoadingIndicator.cpp src/ui/InfoMessage.cpp src/ui/FlatButton.cpp diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 2191c6de..e54892a6 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -84,7 +84,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) // SideBar sideBar_ = new QFrame(this); sideBar_->setObjectName("sideBar"); - sideBar_->setMinimumWidth(utils::calculateSidebarSizes(QFont{}).normal); + sideBar_->setMinimumWidth(::splitter::calculateSidebarSizes(QFont{}).normal); sideBarLayout_ = new QVBoxLayout(sideBar_); sideBarLayout_->setSpacing(0); sideBarLayout_->setMargin(0); @@ -1307,7 +1307,7 @@ ChatPage::timelineWidth() bool ChatPage::isSideBarExpanded() { - const auto sz = utils::calculateSidebarSizes(QFont{}); + const auto sz = splitter::calculateSidebarSizes(QFont{}); return sideBar_->size().width() > sz.normal; } diff --git a/src/CommunitiesList.cpp b/src/CommunitiesList.cpp index 4ea99408..2d97594a 100644 --- a/src/CommunitiesList.cpp +++ b/src/CommunitiesList.cpp @@ -2,7 +2,9 @@ #include "Cache.h" #include "Logging.h" #include "MatrixClient.h" -#include "Utils.h" +#include "Splitter.h" + +#include #include @@ -20,7 +22,7 @@ CommunitiesList::CommunitiesList(QWidget *parent) topLayout_->setSpacing(0); topLayout_->setMargin(0); - const auto sideBarSizes = utils::calculateSidebarSizes(QFont{}); + const auto sideBarSizes = splitter::calculateSidebarSizes(QFont{}); setFixedWidth(sideBarSizes.groups); scrollArea_ = new QScrollArea(this); @@ -185,7 +187,8 @@ void CommunitiesList::updateCommunityAvatar(const QString &community_id, const QPixmap &img) { if (!communityExists(community_id)) { - qWarning() << "Avatar update on nonexistent community" << community_id; + nhlog::ui()->warn("Avatar update on nonexistent community {}", + community_id.toStdString()); return; } @@ -196,7 +199,7 @@ void CommunitiesList::highlightSelectedCommunity(const QString &community_id) { if (!communityExists(community_id)) { - qDebug() << "CommunitiesList: clicked unknown community"; + nhlog::ui()->debug("CommunitiesList: clicked unknown community"); return; } diff --git a/src/CommunitiesList.h b/src/CommunitiesList.h index 49eaeaf6..e8042666 100644 --- a/src/CommunitiesList.h +++ b/src/CommunitiesList.h @@ -8,6 +8,11 @@ #include "CommunitiesListItem.h" #include "ui/Theme.h" +namespace mtx::responses { +struct GroupProfile; +struct JoinedGroups; +} + class CommunitiesList : public QWidget { Q_OBJECT diff --git a/src/CommunitiesListItem.cpp b/src/CommunitiesListItem.cpp index 324482d3..274271e5 100644 --- a/src/CommunitiesListItem.cpp +++ b/src/CommunitiesListItem.cpp @@ -1,4 +1,7 @@ #include "CommunitiesListItem.h" + +#include + #include "Utils.h" #include "ui/Painter.h" #include "ui/Ripple.h" diff --git a/src/CommunitiesListItem.h b/src/CommunitiesListItem.h index d4d7e9c6..0cc5d60c 100644 --- a/src/CommunitiesListItem.h +++ b/src/CommunitiesListItem.h @@ -1,17 +1,14 @@ #pragma once -#include -#include -#include #include #include -#include - #include "Config.h" #include "ui/Theme.h" class RippleOverlay; +class QPainter; +class QMouseEvent; class CommunitiesListItem : public QWidget { diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp index 0e7a18d4..c244db28 100644 --- a/src/LoginPage.cpp +++ b/src/LoginPage.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include #include #include diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index a24266fa..d400ad8e 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -31,6 +31,7 @@ #include "MainWindow.h" #include "MatrixClient.h" #include "RegisterPage.h" +#include "Splitter.h" #include "TrayIcon.h" #include "UserSettingsPage.h" #include "Utils.h" @@ -191,7 +192,7 @@ MainWindow::resizeEvent(QResizeEvent *event) void MainWindow::adjustSideBars() { - const auto sz = utils::calculateSidebarSizes(QFont{}); + const auto sz = splitter::calculateSidebarSizes(QFont{}); const uint64_t timelineWidth = chat_page_->timelineWidth(); const uint64_t minAvailableWidth = sz.collapsePoint + sz.groups; diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp index fdb0f43a..942fd1b8 100644 --- a/src/RegisterPage.cpp +++ b/src/RegisterPage.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include #include #include diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp index 926e1359..822a7a55 100644 --- a/src/RoomInfoListItem.cpp +++ b/src/RoomInfoListItem.cpp @@ -16,7 +16,6 @@ */ #include -#include #include #include #include @@ -26,6 +25,7 @@ #include "Cache.h" #include "Config.h" #include "RoomInfoListItem.h" +#include "Splitter.h" #include "Utils.h" #include "ui/Menu.h" #include "ui/Ripple.h" @@ -116,7 +116,7 @@ RoomInfoListItem::resizeEvent(QResizeEvent *) QPainterPath path; path.addRect(0, 0, width(), height()); - const auto sidebarSizes = utils::calculateSidebarSizes(QFont{}); + const auto sidebarSizes = splitter::calculateSidebarSizes(QFont{}); if (width() > sidebarSizes.small) setToolTip(""); @@ -165,7 +165,7 @@ RoomInfoListItem::paintEvent(QPaintEvent *event) // Description line with the default font. int bottom_y = wm.maxHeight - wm.padding - metrics.ascent() / 2; - const auto sidebarSizes = utils::calculateSidebarSizes(QFont{}); + const auto sidebarSizes = splitter::calculateSidebarSizes(QFont{}); if (width() > sidebarSizes.small) { QFont headingFont; diff --git a/src/RoomList.cpp b/src/RoomList.cpp index 6434489e..b90c8fa4 100644 --- a/src/RoomList.cpp +++ b/src/RoomList.cpp @@ -17,18 +17,14 @@ #include -#include -#include #include +#include #include -#include "Cache.h" #include "Logging.h" #include "MainWindow.h" -#include "MatrixClient.h" #include "RoomInfoListItem.h" #include "RoomList.h" -#include "UserSettingsPage.h" #include "Utils.h" #include "ui/OverlayModal.h" diff --git a/src/SideBarActions.cpp b/src/SideBarActions.cpp index 2f447cd8..4934ec05 100644 --- a/src/SideBarActions.cpp +++ b/src/SideBarActions.cpp @@ -1,15 +1,15 @@ -#include #include +#include +#include #include #include "Config.h" #include "MainWindow.h" #include "SideBarActions.h" -#include "Utils.h" +#include "Splitter.h" #include "ui/FlatButton.h" #include "ui/Menu.h" -#include "ui/OverlayModal.h" SideBarActions::SideBarActions(QWidget *parent) : QWidget{parent} @@ -93,7 +93,7 @@ SideBarActions::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); - const auto sidebarSizes = utils::calculateSidebarSizes(QFont{}); + const auto sidebarSizes = splitter::calculateSidebarSizes(QFont{}); if (width() <= sidebarSizes.small) { roomDirectory_->hide(); diff --git a/src/SideBarActions.h b/src/SideBarActions.h index ce96cba8..662750b3 100644 --- a/src/SideBarActions.h +++ b/src/SideBarActions.h @@ -2,7 +2,6 @@ #include #include -#include #include namespace mtx { @@ -13,6 +12,7 @@ struct CreateRoom; class Menu; class FlatButton; +class QResizeEvent; class SideBarActions : public QWidget { diff --git a/src/Splitter.cpp b/src/Splitter.cpp index ddb1dc1c..32c67425 100644 --- a/src/Splitter.cpp +++ b/src/Splitter.cpp @@ -16,19 +16,20 @@ */ #include -#include #include #include #include #include "Config.h" +#include "Logging.h" #include "Splitter.h" +#include "Utils.h" constexpr auto MaxWidth = (1 << 24) - 1; Splitter::Splitter(QWidget *parent) : QSplitter(parent) - , sz_{utils::calculateSidebarSizes(QFont{})} + , sz_{splitter::calculateSidebarSizes(QFont{})} { connect(this, &QSplitter::splitterMoved, this, &Splitter::onSplitterMoved); setChildrenCollapsible(false); @@ -80,7 +81,7 @@ Splitter::onSplitterMoved(int pos, int index) auto s = sizes(); if (s.count() < 2) { - qWarning() << "Splitter needs at least two children"; + nhlog::ui()->warn("Splitter needs at least two children"); return; } @@ -165,3 +166,18 @@ Splitter::showFullRoomList() left->show(); left->setMaximumWidth(MaxWidth); } + +splitter::SideBarSizes +splitter::calculateSidebarSizes(const QFont &f) +{ + const auto height = static_cast(QFontMetrics{f}.lineSpacing()); + + SideBarSizes sz; + sz.small = std::ceil(3.5 * height + height / 4.0); + sz.normal = std::ceil(16 * height); + sz.groups = std::ceil(3 * height); + sz.collapsePoint = 2 * sz.normal; + + return sz; +} + diff --git a/src/Splitter.h b/src/Splitter.h index 14d6773e..36c9f4fb 100644 --- a/src/Splitter.h +++ b/src/Splitter.h @@ -17,9 +17,21 @@ #pragma once -#include "Utils.h" #include +namespace splitter { +struct SideBarSizes +{ + int small; + int normal; + int groups; + int collapsePoint; +}; + +SideBarSizes +calculateSidebarSizes(const QFont &f); +} + class Splitter : public QSplitter { Q_OBJECT @@ -45,5 +57,5 @@ private: int leftMoveCount_ = 0; int rightMoveCount_ = 0; - utils::SideBarSizes sz_; + splitter::SideBarSizes sz_; }; diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 502456bf..7be50ab5 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -16,12 +16,9 @@ */ #include -#include #include #include -#include #include -#include #include #include #include @@ -31,7 +28,7 @@ #include "Cache.h" #include "ChatPage.h" -#include "Config.h" +#include "Logging.h" #include "TextInputWidget.h" #include "Utils.h" #include "ui/FlatButton.h" diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 4bdb2509..a430aa5c 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/src/TopRoomBar.cpp b/src/TopRoomBar.cpp index 712fe9aa..ffd57d50 100644 --- a/src/TopRoomBar.cpp +++ b/src/TopRoomBar.cpp @@ -15,8 +15,16 @@ * along with this program. If not, see . */ -#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include "Config.h" #include "MainWindow.h" @@ -210,3 +218,19 @@ TopRoomBar::updateRoomTopic(QString topic) topicLabel_->setHtml(topic); update(); } + +void +TopRoomBar::mousePressEvent(QMouseEvent *) +{ + if (roomSettings_ != nullptr) + roomSettings_->trigger(); +} + +void +TopRoomBar::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} diff --git a/src/TopRoomBar.h b/src/TopRoomBar.h index 3243064e..5ab25f39 100644 --- a/src/TopRoomBar.h +++ b/src/TopRoomBar.h @@ -17,17 +17,9 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include class Avatar; class FlatButton; @@ -35,6 +27,12 @@ class Menu; class TextLabel; class OverlayModal; +class QPainter; +class QLabel; +class QIcon; +class QHBoxLayout; +class QVBoxLayout; + class TopRoomBar : public QWidget { Q_OBJECT @@ -67,19 +65,8 @@ signals: void mentionsClicked(const QPoint &pos); protected: - void mousePressEvent(QMouseEvent *) override - { - if (roomSettings_ != nullptr) - roomSettings_->trigger(); - } - - void paintEvent(QPaintEvent *) override - { - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - } + void mousePressEvent(QMouseEvent *) override; + void paintEvent(QPaintEvent *) override; private: QHBoxLayout *topLayout_ = nullptr; diff --git a/src/TrayIcon.cpp b/src/TrayIcon.cpp index 8f62e563..6ab011d1 100644 --- a/src/TrayIcon.cpp +++ b/src/TrayIcon.cpp @@ -15,9 +15,11 @@ * along with this program. If not, see . */ +#include #include #include #include +#include #include #include "TrayIcon.h" diff --git a/src/TrayIcon.h b/src/TrayIcon.h index a3536cc3..6cb26b87 100644 --- a/src/TrayIcon.h +++ b/src/TrayIcon.h @@ -17,13 +17,14 @@ #pragma once -#include #include #include -#include #include #include +class QAction; +class QPainter; + class MsgCountComposedIcon : public QIconEngine { public: diff --git a/src/UserInfoWidget.cpp b/src/UserInfoWidget.cpp index 7a910340..2e21d41f 100644 --- a/src/UserInfoWidget.cpp +++ b/src/UserInfoWidget.cpp @@ -16,14 +16,15 @@ * along with this program. If not, see . */ +#include #include #include #include "Config.h" #include "MainWindow.h" +#include "Splitter.h" #include "UserInfoWidget.h" -#include "Utils.h" #include "ui/Avatar.h" #include "ui/FlatButton.h" #include "ui/OverlayModal.h" @@ -108,7 +109,7 @@ UserInfoWidget::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); - const auto sz = utils::calculateSidebarSizes(QFont{}); + const auto sz = splitter::calculateSidebarSizes(QFont{}); if (width() <= sz.small) { topLayout_->setContentsMargins(0, 0, logoutButtonSize_, 0); diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index b73f80a1..a0f37c26 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Utils.cpp b/src/Utils.cpp index 00796a53..55eebbc9 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -22,6 +22,25 @@ using TimelineEvent = mtx::events::collections::TimelineEvents; QHash authorColors_; +template +static DescInfo +createDescriptionInfo(const Event &event, const QString &localUser, const QString &room_id) +{ + const auto msg = std::get(event); + const auto sender = QString::fromStdString(msg.sender); + + const auto username = cache::displayName(room_id, sender); + const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts); + + return DescInfo{ + QString::fromStdString(msg.event_id), + sender, + utils::messageDescription( + username, QString::fromStdString(msg.content.body).trimmed(), sender == localUser), + utils::descriptiveTime(ts), + ts}; +} + QString utils::localUser() { @@ -633,16 +652,3 @@ utils::restoreCombobox(QComboBox *combo, const QString &value) } } -utils::SideBarSizes -utils::calculateSidebarSizes(const QFont &f) -{ - const auto height = static_cast(QFontMetrics{f}.lineSpacing()); - - SideBarSizes sz; - sz.small = std::ceil(3.5 * height + height / 4.0); - sz.normal = std::ceil(16 * height); - sz.groups = std::ceil(3 * height); - sz.collapsePoint = 2 * sz.normal; - - return sz; -} diff --git a/src/Utils.h b/src/Utils.h index ea0df21f..a3854dd8 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -2,8 +2,6 @@ #include -#include "RoomInfoListItem.h" - #include #include #include @@ -12,6 +10,8 @@ #include +struct DescInfo; + namespace cache { // Forward declarations to prevent dependency on Cache.h, since this header is included often! QString @@ -166,25 +166,6 @@ messageDescription(const QString &username = "", } } -template -DescInfo -createDescriptionInfo(const Event &event, const QString &localUser, const QString &room_id) -{ - const auto msg = std::get(event); - const auto sender = QString::fromStdString(msg.sender); - - const auto username = cache::displayName(room_id, sender); - const auto ts = QDateTime::fromMSecsSinceEpoch(msg.origin_server_ts); - - return DescInfo{QString::fromStdString(msg.event_id), - sender, - messageDescription(username, - QString::fromStdString(msg.content.body).trimmed(), - sender == localUser), - utils::descriptiveTime(ts), - ts}; -} - //! Scale down an image to fit to the given width & height limitations. QPixmap scaleDown(uint64_t maxWidth, uint64_t maxHeight, const QPixmap &source); @@ -326,14 +307,4 @@ centerWidget(QWidget *widget, QWidget *parent); void restoreCombobox(QComboBox *combo, const QString &value); -struct SideBarSizes -{ - int small; - int normal; - int groups; - int collapsePoint; -}; - -SideBarSizes -calculateSidebarSizes(const QFont &f); } diff --git a/src/WelcomePage.cpp b/src/WelcomePage.cpp index 8c3f6487..e4b0e1c6 100644 --- a/src/WelcomePage.cpp +++ b/src/WelcomePage.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "Config.h" diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp index dfb3d984..54e7bf96 100644 --- a/src/dialogs/MemberList.cpp +++ b/src/dialogs/MemberList.cpp @@ -13,6 +13,7 @@ #include "Cache.h" #include "ChatPage.h" #include "Config.h" +#include "Logging.h" #include "Utils.h" #include "ui/Avatar.h" @@ -116,7 +117,7 @@ MemberList::MemberList(const QString &room_id, QWidget *parent) try { addUsers(cache::getMembers(room_id_.toStdString())); } catch (const lmdb::error &e) { - qCritical() << e.what(); + nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what()); } auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this); diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp index 755e8395..273ffd54 100644 --- a/src/dialogs/UserProfile.cpp +++ b/src/dialogs/UserProfile.cpp @@ -1,13 +1,12 @@ #include #include #include -#include #include #include -#include "AvatarProvider.h" #include "Cache.h" #include "ChatPage.h" +#include "Logging.h" #include "MatrixClient.h" #include "Utils.h" #include "dialogs/UserProfile.h" diff --git a/src/emoji/ItemDelegate.cpp b/src/emoji/ItemDelegate.cpp index 890e334a..afa01625 100644 --- a/src/emoji/ItemDelegate.cpp +++ b/src/emoji/ItemDelegate.cpp @@ -15,7 +15,6 @@ * along with this program. If not, see . */ -#include #include #include diff --git a/src/emoji/Panel.cpp b/src/emoji/Panel.cpp index 49ff40c5..e3b966b4 100644 --- a/src/emoji/Panel.cpp +++ b/src/emoji/Panel.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include #include #include #include diff --git a/src/popups/UserMentions.h b/src/popups/UserMentions.h index d3877462..42bdcd60 100644 --- a/src/popups/UserMentions.h +++ b/src/popups/UserMentions.h @@ -2,19 +2,14 @@ #include -#include -#include #include #include #include -#include #include #include #include #include -#include -#include "Logging.h" namespace popups { @@ -47,4 +42,4 @@ private: QScrollArea *all_scroll_area_; QWidget *all_scroll_widget_; }; -} \ No newline at end of file +} diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 44cf79f4..fb32f0fb 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -6,16 +6,18 @@ #include #include -#include -#include #include #include "CacheCryptoStructs.h" -#include "Logging.h" namespace mtx::http { using RequestErr = const std::optional &; } +namespace mtx::responses { +struct Timeline; +struct Messages; +struct ClaimKeys; +} namespace qml_mtx_events { Q_NAMESPACE diff --git a/src/ui/DropShadow.cpp b/src/ui/DropShadow.cpp new file mode 100644 index 00000000..93baa02d --- /dev/null +++ b/src/ui/DropShadow.cpp @@ -0,0 +1,110 @@ +#include "DropShadow.h" + +#include +#include + + + void DropShadow::draw(QPainter &painter, + qint16 margin, + qreal radius, + QColor start, + QColor end, + qreal startPosition, + qreal endPosition0, + qreal endPosition1, + qreal width, + qreal height) + { + painter.setPen(Qt::NoPen); + + QLinearGradient gradient; + gradient.setColorAt(startPosition, start); + gradient.setColorAt(endPosition0, end); + + // Right + QPointF right0(width - margin, height / 2); + QPointF right1(width, height / 2); + gradient.setStart(right0); + gradient.setFinalStop(right1); + painter.setBrush(QBrush(gradient)); + // Deprecated in 5.13: painter.drawRoundRect( + // QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - + // margin)), 0.0, 0.0); + painter.drawRoundedRect( + QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)), + 0.0, + 0.0); + + // Left + QPointF left0(margin, height / 2); + QPointF left1(0, height / 2); + gradient.setStart(left0); + gradient.setFinalStop(left1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect( + QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0); + + // Top + QPointF top0(width / 2, margin); + QPointF top1(width / 2, 0); + gradient.setStart(top0); + gradient.setFinalStop(top1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect( + QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0); + + // Bottom + QPointF bottom0(width / 2, height - margin); + QPointF bottom1(width / 2, height); + gradient.setStart(bottom0); + gradient.setFinalStop(bottom1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect( + QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)), + 0.0, + 0.0); + + // BottomRight + QPointF bottomright0(width - margin, height - margin); + QPointF bottomright1(width, height); + gradient.setStart(bottomright0); + gradient.setFinalStop(bottomright1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); + + // BottomLeft + QPointF bottomleft0(margin, height - margin); + QPointF bottomleft1(0, height); + gradient.setStart(bottomleft0); + gradient.setFinalStop(bottomleft1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); + + // TopLeft + QPointF topleft0(margin, margin); + QPointF topleft1(0, 0); + gradient.setStart(topleft0); + gradient.setFinalStop(topleft1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(topleft0, topleft1), 0.0, 0.0); + + // TopRight + QPointF topright0(width - margin, margin); + QPointF topright1(width, 0); + gradient.setStart(topright0); + gradient.setFinalStop(topright1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(topright0, topright1), 0.0, 0.0); + + // Widget + painter.setBrush(QBrush("#FFFFFF")); + painter.setRenderHint(QPainter::Antialiasing); + painter.drawRoundedRect( + QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)), + radius, + radius); + } diff --git a/src/ui/DropShadow.h b/src/ui/DropShadow.h index 60fc697b..6997e1a0 100644 --- a/src/ui/DropShadow.h +++ b/src/ui/DropShadow.h @@ -1,8 +1,8 @@ #pragma once #include -#include -#include + +class QPainter; class DropShadow { @@ -16,99 +16,5 @@ public: qreal endPosition0, qreal endPosition1, qreal width, - qreal height) - { - painter.setPen(Qt::NoPen); - - QLinearGradient gradient; - gradient.setColorAt(startPosition, start); - gradient.setColorAt(endPosition0, end); - - // Right - QPointF right0(width - margin, height / 2); - QPointF right1(width, height / 2); - gradient.setStart(right0); - gradient.setFinalStop(right1); - painter.setBrush(QBrush(gradient)); - // Deprecated in 5.13: painter.drawRoundRect( - // QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - - // margin)), 0.0, 0.0); - painter.drawRoundedRect( - QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)), - 0.0, - 0.0); - - // Left - QPointF left0(margin, height / 2); - QPointF left1(0, height / 2); - gradient.setStart(left0); - gradient.setFinalStop(left1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0); - - // Top - QPointF top0(width / 2, margin); - QPointF top1(width / 2, 0); - gradient.setStart(top0); - gradient.setFinalStop(top1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0); - - // Bottom - QPointF bottom0(width / 2, height - margin); - QPointF bottom1(width / 2, height); - gradient.setStart(bottom0); - gradient.setFinalStop(bottom1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)), - 0.0, - 0.0); - - // BottomRight - QPointF bottomright0(width - margin, height - margin); - QPointF bottomright1(width, height); - gradient.setStart(bottomright0); - gradient.setFinalStop(bottomright1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); - - // BottomLeft - QPointF bottomleft0(margin, height - margin); - QPointF bottomleft1(0, height); - gradient.setStart(bottomleft0); - gradient.setFinalStop(bottomleft1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); - - // TopLeft - QPointF topleft0(margin, margin); - QPointF topleft1(0, 0); - gradient.setStart(topleft0); - gradient.setFinalStop(topleft1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(topleft0, topleft1), 0.0, 0.0); - - // TopRight - QPointF topright0(width - margin, margin); - QPointF topright1(width, 0); - gradient.setStart(topright0); - gradient.setFinalStop(topright1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(topright0, topright1), 0.0, 0.0); - - // Widget - painter.setBrush(QBrush("#FFFFFF")); - painter.setRenderHint(QPainter::Antialiasing); - painter.drawRoundedRect( - QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)), - radius, - radius); - } + qreal height); }; diff --git a/src/ui/FlatButton.cpp b/src/ui/FlatButton.cpp index a828f582..6660c58d 100644 --- a/src/ui/FlatButton.cpp +++ b/src/ui/FlatButton.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/src/ui/FlatButton.h b/src/ui/FlatButton.h index 9c2bf425..d29903c2 100644 --- a/src/ui/FlatButton.h +++ b/src/ui/FlatButton.h @@ -1,7 +1,5 @@ #pragma once -#include -#include #include #include diff --git a/src/ui/FloatingButton.cpp b/src/ui/FloatingButton.cpp index 74dcd482..f3a09ccd 100644 --- a/src/ui/FloatingButton.cpp +++ b/src/ui/FloatingButton.cpp @@ -1,3 +1,4 @@ +#include #include #include "FloatingButton.h" diff --git a/src/ui/LoadingIndicator.cpp b/src/ui/LoadingIndicator.cpp index c8337089..d2b1240d 100644 --- a/src/ui/LoadingIndicator.cpp +++ b/src/ui/LoadingIndicator.cpp @@ -1,7 +1,8 @@ #include "LoadingIndicator.h" -#include -#include +#include +#include +#include LoadingIndicator::LoadingIndicator(QWidget *parent) : QWidget(parent) diff --git a/src/ui/LoadingIndicator.h b/src/ui/LoadingIndicator.h index e8de0aec..1585098e 100644 --- a/src/ui/LoadingIndicator.h +++ b/src/ui/LoadingIndicator.h @@ -1,11 +1,11 @@ #pragma once #include -#include -#include -#include #include +class QPainter; +class QTimer; +class QPaintEvent; class LoadingIndicator : public QWidget { Q_OBJECT diff --git a/src/ui/OverlayWidget.cpp b/src/ui/OverlayWidget.cpp index ccac0116..a32d86b6 100644 --- a/src/ui/OverlayWidget.cpp +++ b/src/ui/OverlayWidget.cpp @@ -1,5 +1,7 @@ #include "OverlayWidget.h" -#include + +#include +#include OverlayWidget::OverlayWidget(QWidget *parent) : QWidget(parent) diff --git a/src/ui/OverlayWidget.h b/src/ui/OverlayWidget.h index 6662479d..ed3ef52d 100644 --- a/src/ui/OverlayWidget.h +++ b/src/ui/OverlayWidget.h @@ -1,10 +1,10 @@ #pragma once #include -#include -#include #include +class QPainter; + class OverlayWidget : public QWidget { Q_OBJECT -- cgit 1.5.1 From 127fb9370b8e131ad460b27aaa72de178e929096 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 31 Jan 2020 16:08:30 +0100 Subject: Remove metatypes from headers --- src/Cache.cpp | 11 +++++------ src/Cache.h | 2 +- src/Cache_p.h | 6 +++--- src/LoginPage.cpp | 1 + src/MatrixClient.cpp | 20 ++++++++++++++++++++ src/MatrixClient.h | 18 ------------------ src/QuickSwitcher.cpp | 2 ++ src/QuickSwitcher.h | 2 -- src/RegisterPage.cpp | 2 ++ src/RoomList.h | 3 --- src/TextInputWidget.cpp | 2 +- src/TextInputWidget.h | 4 ++-- src/dialogs/UserProfile.cpp | 2 ++ src/dialogs/UserProfile.h | 2 -- src/popups/SuggestionsPopup.cpp | 4 ++-- src/popups/SuggestionsPopup.h | 4 +--- 16 files changed, 42 insertions(+), 43 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/src/Cache.cpp b/src/Cache.cpp index f6f8052d..dfd7475c 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -80,7 +80,7 @@ using CachedReceipts = std::multimap>; Q_DECLARE_METATYPE(SearchResult) -Q_DECLARE_METATYPE(QVector) +Q_DECLARE_METATYPE(std::vector) Q_DECLARE_METATYPE(RoomMember) Q_DECLARE_METATYPE(mtx::responses::Timeline) Q_DECLARE_METATYPE(RoomSearchResult) @@ -1834,7 +1834,7 @@ Cache::searchRooms(const std::string &query, std::uint8_t max_items) return results; } -QVector +std::vector Cache::searchUsers(const std::string &room_id, const std::string &query, std::uint8_t max_items) { std::multimap> items; @@ -1857,7 +1857,7 @@ Cache::searchUsers(const std::string &room_id, const std::string &query, std::ui else if (items.size() > 0) std::advance(end, items.size()); - QVector results; + std::vector results; for (auto it = items.begin(); it != end; it++) { const auto user = it->second; results.push_back(SearchResult{QString::fromStdString(user.first), @@ -2390,12 +2390,11 @@ void init(const QString &user_id) { qRegisterMetaType(); - qRegisterMetaType>(); + qRegisterMetaType>(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType>(); - qRegisterMetaType>(); qRegisterMetaType>(); qRegisterMetaType>(); @@ -2734,7 +2733,7 @@ calculateRoomReadStatus() instance_->calculateRoomReadStatus(); } -QVector +std::vector searchUsers(const std::string &room_id, const std::string &query, std::uint8_t max_items) { return instance_->searchUsers(room_id, query, max_items); diff --git a/src/Cache.h b/src/Cache.h index a8991eb5..69b3ef2d 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -218,7 +218,7 @@ calculateRoomReadStatus(const std::string &room_id); void calculateRoomReadStatus(); -QVector +std::vector searchUsers(const std::string &room_id, const std::string &query, std::uint8_t max_items = 5); std::vector searchRooms(const std::string &query, std::uint8_t max_items = 5); diff --git a/src/Cache_p.h b/src/Cache_p.h index 32f2a67d..b76a512f 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -172,9 +172,9 @@ public: bool calculateRoomReadStatus(const std::string &room_id); void calculateRoomReadStatus(); - QVector searchUsers(const std::string &room_id, - const std::string &query, - std::uint8_t max_items = 5); + std::vector searchUsers(const std::string &room_id, + const std::string &query, + std::uint8_t max_items = 5); std::vector searchRooms(const std::string &query, std::uint8_t max_items = 5); diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp index c244db28..c06137c9 100644 --- a/src/LoginPage.cpp +++ b/src/LoginPage.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "Config.h" #include "Logging.h" diff --git a/src/MatrixClient.cpp b/src/MatrixClient.cpp index 12d7ac91..b69ba480 100644 --- a/src/MatrixClient.cpp +++ b/src/MatrixClient.cpp @@ -2,6 +2,26 @@ #include +#include +#include +#include + +#include "nlohmann/json.hpp" +#include + +Q_DECLARE_METATYPE(mtx::responses::Login) +Q_DECLARE_METATYPE(mtx::responses::Messages) +Q_DECLARE_METATYPE(mtx::responses::Notifications) +Q_DECLARE_METATYPE(mtx::responses::Rooms) +Q_DECLARE_METATYPE(mtx::responses::Sync) +Q_DECLARE_METATYPE(mtx::responses::JoinedGroups) +Q_DECLARE_METATYPE(mtx::responses::GroupProfile) + +Q_DECLARE_METATYPE(nlohmann::json) +Q_DECLARE_METATYPE(std::string) +Q_DECLARE_METATYPE(std::vector) +Q_DECLARE_METATYPE(std::vector) + namespace { auto client_ = std::make_shared(); } diff --git a/src/MatrixClient.h b/src/MatrixClient.h index c77b1183..4db51095 100644 --- a/src/MatrixClient.h +++ b/src/MatrixClient.h @@ -1,25 +1,7 @@ #pragma once -#include -#include -#include - -#include "nlohmann/json.hpp" -#include #include -Q_DECLARE_METATYPE(mtx::responses::Login) -Q_DECLARE_METATYPE(mtx::responses::Messages) -Q_DECLARE_METATYPE(mtx::responses::Notifications) -Q_DECLARE_METATYPE(mtx::responses::Rooms) -Q_DECLARE_METATYPE(mtx::responses::Sync) -Q_DECLARE_METATYPE(mtx::responses::JoinedGroups) -Q_DECLARE_METATYPE(mtx::responses::GroupProfile) -Q_DECLARE_METATYPE(std::string) -Q_DECLARE_METATYPE(nlohmann::json) -Q_DECLARE_METATYPE(std::vector) -Q_DECLARE_METATYPE(std::vector) - namespace http { mtx::http::Client * client(); diff --git a/src/QuickSwitcher.cpp b/src/QuickSwitcher.cpp index 53dd21e0..05a9f431 100644 --- a/src/QuickSwitcher.cpp +++ b/src/QuickSwitcher.cpp @@ -26,6 +26,8 @@ #include "QuickSwitcher.h" #include "popups/SuggestionsPopup.h" +Q_DECLARE_METATYPE(std::vector) + RoomSearchInput::RoomSearchInput(QWidget *parent) : TextField(parent) {} diff --git a/src/QuickSwitcher.h b/src/QuickSwitcher.h index 05f7be07..5bc31650 100644 --- a/src/QuickSwitcher.h +++ b/src/QuickSwitcher.h @@ -25,8 +25,6 @@ #include "popups/SuggestionsPopup.h" #include "ui/TextField.h" -Q_DECLARE_METATYPE(std::vector) - class RoomSearchInput : public TextField { Q_OBJECT diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp index 942fd1b8..76721036 100644 --- a/src/RegisterPage.cpp +++ b/src/RegisterPage.cpp @@ -19,6 +19,8 @@ #include #include +#include + #include "Config.h" #include "Logging.h" #include "MainWindow.h" diff --git a/src/RoomList.h b/src/RoomList.h index d921990b..51a24043 100644 --- a/src/RoomList.h +++ b/src/RoomList.h @@ -17,15 +17,12 @@ #pragma once -#include #include #include #include #include #include -#include - class LeaveRoomDialog; class OverlayModal; class RoomInfoListItem; diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 7be50ab5..2ad74e3a 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -109,7 +109,7 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent) } void -FilteredTextEdit::showResults(const QVector &results) +FilteredTextEdit::showResults(const std::vector &results) { QPoint pos; diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index a430aa5c..2f267a23 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -76,13 +76,13 @@ signals: //! Trigger the suggestion popup. void showSuggestions(const QString &query); - void resultsRetrieved(const QVector &results); + void resultsRetrieved(const std::vector &results); void selectNextSuggestion(); void selectPreviousSuggestion(); void selectHoveredSuggestion(); public slots: - void showResults(const QVector &results); + void showResults(const std::vector &results); protected: void keyPressEvent(QKeyEvent *event) override; diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp index 273ffd54..f1dd77df 100644 --- a/src/dialogs/UserProfile.cpp +++ b/src/dialogs/UserProfile.cpp @@ -15,6 +15,8 @@ using namespace dialogs; +Q_DECLARE_METATYPE(std::vector) + constexpr int BUTTON_SIZE = 36; constexpr int BUTTON_RADIUS = BUTTON_SIZE / 2; constexpr int WIDGET_MARGIN = 20; diff --git a/src/dialogs/UserProfile.h b/src/dialogs/UserProfile.h index 0f684cda..81276d2a 100644 --- a/src/dialogs/UserProfile.h +++ b/src/dialogs/UserProfile.h @@ -15,8 +15,6 @@ struct DeviceInfo QString display_name; }; -Q_DECLARE_METATYPE(std::vector) - class Proxy : public QObject { Q_OBJECT diff --git a/src/popups/SuggestionsPopup.cpp b/src/popups/SuggestionsPopup.cpp index ba1f77b9..8f355b38 100644 --- a/src/popups/SuggestionsPopup.cpp +++ b/src/popups/SuggestionsPopup.cpp @@ -60,9 +60,9 @@ SuggestionsPopup::addRooms(const std::vector &rooms) } void -SuggestionsPopup::addUsers(const QVector &users) +SuggestionsPopup::addUsers(const std::vector &users) { - if (users.isEmpty()) { + if (users.empty()) { hide(); return; } diff --git a/src/popups/SuggestionsPopup.h b/src/popups/SuggestionsPopup.h index de52760a..dcd054f8 100644 --- a/src/popups/SuggestionsPopup.h +++ b/src/popups/SuggestionsPopup.h @@ -9,8 +9,6 @@ #include "ChatPage.h" #include "PopupItem.h" -Q_DECLARE_METATYPE(QVector) - class SuggestionsPopup : public QWidget { Q_OBJECT @@ -33,7 +31,7 @@ public: } public slots: - void addUsers(const QVector &users); + void addUsers(const std::vector &users); void addRooms(const std::vector &rooms); //! Move to the next available suggestion item. -- cgit 1.5.1 From 63f3071445308aaa01c1f04d6c19f15f0bdde3d4 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 31 Jan 2020 16:25:43 +0100 Subject: Remove more unneeded headers --- src/Splitter.cpp | 6 -- src/TextInputWidget.h | 5 +- src/Utils.cpp | 1 - src/dialogs/PreviewUploadOverlay.cpp | 1 - src/popups/UserMentions.cpp | 3 + src/popups/UserMentions.h | 8 +- src/ui/DropShadow.cpp | 188 +++++++++++++++++------------------ src/ui/TextField.cpp | 2 +- src/ui/ToggleButton.cpp | 2 +- 9 files changed, 103 insertions(+), 113 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/src/Splitter.cpp b/src/Splitter.cpp index 32c67425..6267e591 100644 --- a/src/Splitter.cpp +++ b/src/Splitter.cpp @@ -15,15 +15,10 @@ * along with this program. If not, see . */ -#include -#include #include -#include -#include "Config.h" #include "Logging.h" #include "Splitter.h" -#include "Utils.h" constexpr auto MaxWidth = (1 << 24) - 1; @@ -180,4 +175,3 @@ splitter::calculateSidebarSizes(const QFont &f) return sz; } - diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 2f267a23..3674ee0d 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -18,17 +18,14 @@ #pragma once #include -#include -#include #include -#include +#include #include #include #include #include -#include "Utils.h" #include "dialogs/PreviewUploadOverlay.h" #include "emoji/PickButton.h" #include "popups/ReplyPopup.h" diff --git a/src/Utils.cpp b/src/Utils.cpp index 55eebbc9..91ecfcd7 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -651,4 +651,3 @@ utils::restoreCombobox(QComboBox *combo, const QString &value) } } } - diff --git a/src/dialogs/PreviewUploadOverlay.cpp b/src/dialogs/PreviewUploadOverlay.cpp index 31d01214..42558d67 100644 --- a/src/dialogs/PreviewUploadOverlay.cpp +++ b/src/dialogs/PreviewUploadOverlay.cpp @@ -15,7 +15,6 @@ * along with this program. If not, see . */ -#include #include #include #include diff --git a/src/popups/UserMentions.cpp b/src/popups/UserMentions.cpp index 763eeffc..b0223f7f 100644 --- a/src/popups/UserMentions.cpp +++ b/src/popups/UserMentions.cpp @@ -1,7 +1,10 @@ +#include #include +#include #include #include #include +#include #include "Cache.h" #include "ChatPage.h" diff --git a/src/popups/UserMentions.h b/src/popups/UserMentions.h index 42bdcd60..b7c4e51d 100644 --- a/src/popups/UserMentions.h +++ b/src/popups/UserMentions.h @@ -3,13 +3,13 @@ #include #include -#include -#include #include -#include -#include #include +class QPaintEvent; +class QTabWidget; +class QScrollArea; +class QVBoxLayout; namespace popups { diff --git a/src/ui/DropShadow.cpp b/src/ui/DropShadow.cpp index 93baa02d..d437975c 100644 --- a/src/ui/DropShadow.cpp +++ b/src/ui/DropShadow.cpp @@ -3,108 +3,106 @@ #include #include +void +DropShadow::draw(QPainter &painter, + qint16 margin, + qreal radius, + QColor start, + QColor end, + qreal startPosition, + qreal endPosition0, + qreal endPosition1, + qreal width, + qreal height) +{ + painter.setPen(Qt::NoPen); - void DropShadow::draw(QPainter &painter, - qint16 margin, - qreal radius, - QColor start, - QColor end, - qreal startPosition, - qreal endPosition0, - qreal endPosition1, - qreal width, - qreal height) - { - painter.setPen(Qt::NoPen); + QLinearGradient gradient; + gradient.setColorAt(startPosition, start); + gradient.setColorAt(endPosition0, end); - QLinearGradient gradient; - gradient.setColorAt(startPosition, start); - gradient.setColorAt(endPosition0, end); + // Right + QPointF right0(width - margin, height / 2); + QPointF right1(width, height / 2); + gradient.setStart(right0); + gradient.setFinalStop(right1); + painter.setBrush(QBrush(gradient)); + // Deprecated in 5.13: painter.drawRoundRect( + // QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - + // margin)), 0.0, 0.0); + painter.drawRoundedRect( + QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)), + 0.0, + 0.0); - // Right - QPointF right0(width - margin, height / 2); - QPointF right1(width, height / 2); - gradient.setStart(right0); - gradient.setFinalStop(right1); - painter.setBrush(QBrush(gradient)); - // Deprecated in 5.13: painter.drawRoundRect( - // QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - - // margin)), 0.0, 0.0); - painter.drawRoundedRect( - QRectF(QPointF(width - margin * radius, margin), QPointF(width, height - margin)), - 0.0, - 0.0); + // Left + QPointF left0(margin, height / 2); + QPointF left1(0, height / 2); + gradient.setStart(left0); + gradient.setFinalStop(left1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect( + QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0); - // Left - QPointF left0(margin, height / 2); - QPointF left1(0, height / 2); - gradient.setStart(left0); - gradient.setFinalStop(left1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(margin * radius, margin), QPointF(0, height - margin)), 0.0, 0.0); + // Top + QPointF top0(width / 2, margin); + QPointF top1(width / 2, 0); + gradient.setStart(top0); + gradient.setFinalStop(top1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect( + QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0); - // Top - QPointF top0(width / 2, margin); - QPointF top1(width / 2, 0); - gradient.setStart(top0); - gradient.setFinalStop(top1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(width - margin, 0), QPointF(margin, margin)), 0.0, 0.0); + // Bottom + QPointF bottom0(width / 2, height - margin); + QPointF bottom1(width / 2, height); + gradient.setStart(bottom0); + gradient.setFinalStop(bottom1); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect( + QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)), 0.0, 0.0); - // Bottom - QPointF bottom0(width / 2, height - margin); - QPointF bottom1(width / 2, height); - gradient.setStart(bottom0); - gradient.setFinalStop(bottom1); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect( - QRectF(QPointF(margin, height - margin), QPointF(width - margin, height)), - 0.0, - 0.0); + // BottomRight + QPointF bottomright0(width - margin, height - margin); + QPointF bottomright1(width, height); + gradient.setStart(bottomright0); + gradient.setFinalStop(bottomright1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); - // BottomRight - QPointF bottomright0(width - margin, height - margin); - QPointF bottomright1(width, height); - gradient.setStart(bottomright0); - gradient.setFinalStop(bottomright1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); + // BottomLeft + QPointF bottomleft0(margin, height - margin); + QPointF bottomleft1(0, height); + gradient.setStart(bottomleft0); + gradient.setFinalStop(bottomleft1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); - // BottomLeft - QPointF bottomleft0(margin, height - margin); - QPointF bottomleft1(0, height); - gradient.setStart(bottomleft0); - gradient.setFinalStop(bottomleft1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); + // TopLeft + QPointF topleft0(margin, margin); + QPointF topleft1(0, 0); + gradient.setStart(topleft0); + gradient.setFinalStop(topleft1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(topleft0, topleft1), 0.0, 0.0); - // TopLeft - QPointF topleft0(margin, margin); - QPointF topleft1(0, 0); - gradient.setStart(topleft0); - gradient.setFinalStop(topleft1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(topleft0, topleft1), 0.0, 0.0); + // TopRight + QPointF topright0(width - margin, margin); + QPointF topright1(width, 0); + gradient.setStart(topright0); + gradient.setFinalStop(topright1); + gradient.setColorAt(endPosition1, end); + painter.setBrush(QBrush(gradient)); + painter.drawRoundedRect(QRectF(topright0, topright1), 0.0, 0.0); - // TopRight - QPointF topright0(width - margin, margin); - QPointF topright1(width, 0); - gradient.setStart(topright0); - gradient.setFinalStop(topright1); - gradient.setColorAt(endPosition1, end); - painter.setBrush(QBrush(gradient)); - painter.drawRoundedRect(QRectF(topright0, topright1), 0.0, 0.0); - - // Widget - painter.setBrush(QBrush("#FFFFFF")); - painter.setRenderHint(QPainter::Antialiasing); - painter.drawRoundedRect( - QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)), - radius, - radius); - } + // Widget + painter.setBrush(QBrush("#FFFFFF")); + painter.setRenderHint(QPainter::Antialiasing); + painter.drawRoundedRect( + QRectF(QPointF(margin, margin), QPointF(width - margin, height - margin)), + radius, + radius); +} diff --git a/src/ui/TextField.cpp b/src/ui/TextField.cpp index c4582085..0ae2516d 100644 --- a/src/ui/TextField.cpp +++ b/src/ui/TextField.cpp @@ -1,6 +1,6 @@ #include "TextField.h" -#include +#include #include #include #include diff --git a/src/ui/ToggleButton.cpp b/src/ui/ToggleButton.cpp index 755f528f..f9411489 100644 --- a/src/ui/ToggleButton.cpp +++ b/src/ui/ToggleButton.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include #include -- cgit 1.5.1 From 7ccc120f6345bff8dad4abb349669973746aa8da Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 4 Feb 2020 04:58:43 +0100 Subject: modernize: use nullptr --- src/ChatPage.h | 2 +- src/LoginPage.cpp | 2 +- src/LoginPage.h | 2 +- src/MainWindow.h | 2 +- src/RegisterPage.cpp | 8 ++++---- src/RegisterPage.h | 2 +- src/RoomInfoListItem.h | 2 +- src/RoomList.h | 2 +- src/TextInputWidget.h | 2 +- src/TopRoomBar.h | 2 +- src/UserInfoWidget.h | 2 +- src/UserSettingsPage.h | 2 +- src/WelcomePage.h | 2 +- src/dialogs/ImageOverlay.cpp | 2 +- src/popups/ReplyPopup.cpp | 6 +++--- src/popups/SuggestionsPopup.h | 2 +- src/timeline/TimelineModel.h | 2 +- src/timeline/TimelineViewManager.h | 2 +- src/ui/Avatar.h | 2 +- src/ui/Badge.h | 6 +++--- src/ui/FlatButton.h | 6 +++--- src/ui/LoadingIndicator.h | 2 +- src/ui/RaisedButton.h | 4 ++-- src/ui/Ripple.cpp | 2 +- src/ui/Ripple.h | 4 ++-- src/ui/RippleOverlay.h | 2 +- src/ui/TextField.cpp | 8 ++++---- src/ui/TextField.h | 2 +- src/ui/Theme.h | 2 +- 29 files changed, 43 insertions(+), 43 deletions(-) (limited to 'src/TextInputWidget.h') diff --git a/src/ChatPage.h b/src/ChatPage.h index 9bc5fb73..8e2e9192 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -65,7 +65,7 @@ class ChatPage : public QWidget Q_OBJECT public: - ChatPage(QSharedPointer userSettings, QWidget *parent = 0); + ChatPage(QSharedPointer userSettings, QWidget *parent = nullptr); // Initialize all the components of the UI. void bootstrap(QString userid, QString homeserver, QString token); diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp index c06137c9..c3919b93 100644 --- a/src/LoginPage.cpp +++ b/src/LoginPage.cpp @@ -111,7 +111,7 @@ LoginPage::LoginPage(QWidget *parent) form_layout_->addLayout(matrixidLayout_); form_layout_->addWidget(password_input_); - form_layout_->addWidget(deviceName_, Qt::AlignHCenter, 0); + form_layout_->addWidget(deviceName_, Qt::AlignHCenter, nullptr); form_layout_->addLayout(serverLayout_); button_layout_ = new QHBoxLayout(); diff --git a/src/LoginPage.h b/src/LoginPage.h index 99c249b1..4b84abfc 100644 --- a/src/LoginPage.h +++ b/src/LoginPage.h @@ -38,7 +38,7 @@ class LoginPage : public QWidget Q_OBJECT public: - LoginPage(QWidget *parent = 0); + LoginPage(QWidget *parent = nullptr); void reset(); diff --git a/src/MainWindow.h b/src/MainWindow.h index 1aadbf4d..59f29d50 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -62,7 +62,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); + explicit MainWindow(QWidget *parent = nullptr); static MainWindow *instance() { return instance_; }; void saveCurrentWindowSize(); diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp index 76721036..2688e9a9 100644 --- a/src/RegisterPage.cpp +++ b/src/RegisterPage.cpp @@ -90,10 +90,10 @@ RegisterPage::RegisterPage(QWidget *parent) server_input_ = new TextField(); server_input_->setLabel(tr("Home Server")); - form_layout_->addWidget(username_input_, Qt::AlignHCenter, 0); - form_layout_->addWidget(password_input_, Qt::AlignHCenter, 0); - form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter, 0); - form_layout_->addWidget(server_input_, Qt::AlignHCenter, 0); + form_layout_->addWidget(username_input_, Qt::AlignHCenter, nullptr); + form_layout_->addWidget(password_input_, Qt::AlignHCenter, nullptr); + form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter, nullptr); + form_layout_->addWidget(server_input_, Qt::AlignHCenter, nullptr); button_layout_ = new QHBoxLayout(); button_layout_->setSpacing(0); diff --git a/src/RegisterPage.h b/src/RegisterPage.h index b05cf150..96a5b3ca 100644 --- a/src/RegisterPage.h +++ b/src/RegisterPage.h @@ -30,7 +30,7 @@ class RegisterPage : public QWidget Q_OBJECT public: - RegisterPage(QWidget *parent = 0); + RegisterPage(QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *event) override; diff --git a/src/RoomInfoListItem.h b/src/RoomInfoListItem.h index 16553c73..5cb9e83c 100644 --- a/src/RoomInfoListItem.h +++ b/src/RoomInfoListItem.h @@ -65,7 +65,7 @@ class RoomInfoListItem : public QWidget Q_PROPERTY(QColor btnTextColor READ btnTextColor WRITE setBtnTextColor) public: - RoomInfoListItem(QString room_id, const RoomInfo &info, QWidget *parent = 0); + RoomInfoListItem(QString room_id, const RoomInfo &info, QWidget *parent = nullptr); void updateUnreadMessageCount(int count, int highlightedCount); void clearUnreadMessageCount() { updateUnreadMessageCount(0, 0); }; diff --git a/src/RoomList.h b/src/RoomList.h index 51a24043..fef552c6 100644 --- a/src/RoomList.h +++ b/src/RoomList.h @@ -35,7 +35,7 @@ class RoomList : public QWidget Q_OBJECT public: - explicit RoomList(QWidget *parent = 0); + explicit RoomList(QWidget *parent = nullptr); void initialize(const QMap &info); void sync(const std::map &info); diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index 3674ee0d..ac79be8b 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -142,7 +142,7 @@ class TextInputWidget : public QWidget Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: - TextInputWidget(QWidget *parent = 0); + TextInputWidget(QWidget *parent = nullptr); void stopTyping(); diff --git a/src/TopRoomBar.h b/src/TopRoomBar.h index 5ab25f39..63ce847e 100644 --- a/src/TopRoomBar.h +++ b/src/TopRoomBar.h @@ -40,7 +40,7 @@ class TopRoomBar : public QWidget Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: - TopRoomBar(QWidget *parent = 0); + TopRoomBar(QWidget *parent = nullptr); void updateRoomAvatar(const QString &avatar_image); void updateRoomAvatar(const QIcon &icon); diff --git a/src/UserInfoWidget.h b/src/UserInfoWidget.h index 263dd0c2..e1a925a4 100644 --- a/src/UserInfoWidget.h +++ b/src/UserInfoWidget.h @@ -31,7 +31,7 @@ class UserInfoWidget : public QWidget Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: - UserInfoWidget(QWidget *parent = 0); + UserInfoWidget(QWidget *parent = nullptr); void setDisplayName(const QString &name); void setUserId(const QString &userid); diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 8658e80e..299905ab 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -147,7 +147,7 @@ class UserSettingsPage : public QWidget Q_OBJECT public: - UserSettingsPage(QSharedPointer settings, QWidget *parent = 0); + UserSettingsPage(QSharedPointer settings, QWidget *parent = nullptr); protected: void showEvent(QShowEvent *event) override; diff --git a/src/WelcomePage.h b/src/WelcomePage.h index 480dc702..ae660215 100644 --- a/src/WelcomePage.h +++ b/src/WelcomePage.h @@ -7,7 +7,7 @@ class WelcomePage : public QWidget Q_OBJECT public: - explicit WelcomePage(QWidget *parent = 0); + explicit WelcomePage(QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *) override; diff --git a/src/dialogs/ImageOverlay.cpp b/src/dialogs/ImageOverlay.cpp index cbdd351c..a98c39c2 100644 --- a/src/dialogs/ImageOverlay.cpp +++ b/src/dialogs/ImageOverlay.cpp @@ -32,7 +32,7 @@ ImageOverlay::ImageOverlay(QPixmap image, QWidget *parent) , originalImage_{image} { setMouseTracking(true); - setParent(0); + setParent(nullptr); setWindowFlags(windowFlags() | Qt::FramelessWindowHint); diff --git a/src/popups/ReplyPopup.cpp b/src/popups/ReplyPopup.cpp index 42a5a6d3..5058c039 100644 --- a/src/popups/ReplyPopup.cpp +++ b/src/popups/ReplyPopup.cpp @@ -13,9 +13,9 @@ ReplyPopup::ReplyPopup(QWidget *parent) : QWidget(parent) - , userItem_{0} - , msgLabel_{0} - , eventLabel_{0} + , userItem_{nullptr} + , msgLabel_{nullptr} + , eventLabel_{nullptr} { setAttribute(Qt::WA_ShowWithoutActivating, true); setWindowFlags(Qt::ToolTip | Qt::NoDropShadowWindowHint); diff --git a/src/popups/SuggestionsPopup.h b/src/popups/SuggestionsPopup.h index dcd054f8..f84870e7 100644 --- a/src/popups/SuggestionsPopup.h +++ b/src/popups/SuggestionsPopup.h @@ -59,7 +59,7 @@ private: size_t posToRemove = layout_->count() - 1; QLayoutItem *item; - while (startingPos <= posToRemove && (item = layout_->takeAt(posToRemove)) != 0) { + while (startingPos <= posToRemove && (item = layout_->takeAt(posToRemove)) != nullptr) { delete item->widget(); delete item; diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index fb32f0fb..2d0e9627 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -126,7 +126,7 @@ class TimelineModel : public QAbstractListModel typingUsersChanged) public: - explicit TimelineModel(TimelineViewManager *manager, QString room_id, QObject *parent = 0); + explicit TimelineModel(TimelineViewManager *manager, QString room_id, QObject *parent = nullptr); enum Roles { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 5880a382..8552d6b3 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -29,7 +29,7 @@ class TimelineViewManager : public QObject replyingEventChanged) public: - TimelineViewManager(QSharedPointer userSettings, QWidget *parent = 0); + TimelineViewManager(QSharedPointer userSettings, QWidget *parent = nullptr); QWidget *getWidget() const { return container; } void sync(const mtx::responses::Rooms &rooms); diff --git a/src/ui/Avatar.h b/src/ui/Avatar.h index a643c8c4..d6d0b5c7 100644 --- a/src/ui/Avatar.h +++ b/src/ui/Avatar.h @@ -15,7 +15,7 @@ class Avatar : public QWidget Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) public: - explicit Avatar(QWidget *parent = 0, int size = ui::AvatarSize); + explicit Avatar(QWidget *parent = nullptr, int size = ui::AvatarSize); void setBackgroundColor(const QColor &color); void setIcon(const QIcon &icon); diff --git a/src/ui/Badge.h b/src/ui/Badge.h index fd73ad30..748b56fd 100644 --- a/src/ui/Badge.h +++ b/src/ui/Badge.h @@ -16,9 +16,9 @@ class Badge : public OverlayWidget Q_PROPERTY(QPointF relativePosition WRITE setRelativePosition READ relativePosition) public: - explicit Badge(QWidget *parent = 0); - explicit Badge(const QIcon &icon, QWidget *parent = 0); - explicit Badge(const QString &text, QWidget *parent = 0); + explicit Badge(QWidget *parent = nullptr); + explicit Badge(const QIcon &icon, QWidget *parent = nullptr); + explicit Badge(const QString &text, QWidget *parent = nullptr); void setBackgroundColor(const QColor &color); void setTextColor(const QColor &color); diff --git a/src/ui/FlatButton.h b/src/ui/FlatButton.h index d29903c2..764df6e9 100644 --- a/src/ui/FlatButton.h +++ b/src/ui/FlatButton.h @@ -91,14 +91,14 @@ class FlatButton : public QPushButton Q_PROPERTY(qreal fontSize WRITE setFontSize READ fontSize) public: - explicit FlatButton(QWidget *parent = 0, + explicit FlatButton(QWidget *parent = nullptr, ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); explicit FlatButton(const QString &text, - QWidget *parent = 0, + QWidget *parent = nullptr, ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); FlatButton(const QString &text, ui::Role role, - QWidget *parent = 0, + QWidget *parent = nullptr, ui::ButtonPreset preset = ui::ButtonPreset::FlatPreset); ~FlatButton(); diff --git a/src/ui/LoadingIndicator.h b/src/ui/LoadingIndicator.h index 1585098e..e72a8c48 100644 --- a/src/ui/LoadingIndicator.h +++ b/src/ui/LoadingIndicator.h @@ -12,7 +12,7 @@ class LoadingIndicator : public QWidget Q_PROPERTY(QColor color READ color WRITE setColor) public: - LoadingIndicator(QWidget *parent = 0); + LoadingIndicator(QWidget *parent = nullptr); void paintEvent(QPaintEvent *e); diff --git a/src/ui/RaisedButton.h b/src/ui/RaisedButton.h index edd5ee4a..74543262 100644 --- a/src/ui/RaisedButton.h +++ b/src/ui/RaisedButton.h @@ -11,8 +11,8 @@ class RaisedButton : public FlatButton Q_OBJECT public: - explicit RaisedButton(QWidget *parent = 0); - explicit RaisedButton(const QString &text, QWidget *parent = 0); + explicit RaisedButton(QWidget *parent = nullptr); + explicit RaisedButton(const QString &text, QWidget *parent = nullptr); ~RaisedButton(); protected: diff --git a/src/ui/Ripple.cpp b/src/ui/Ripple.cpp index e22c4a62..ef8a62dd 100644 --- a/src/ui/Ripple.cpp +++ b/src/ui/Ripple.cpp @@ -3,7 +3,7 @@ Ripple::Ripple(const QPoint ¢er, QObject *parent) : QParallelAnimationGroup(parent) - , overlay_(0) + , overlay_(nullptr) , radius_anim_(animate("radius")) , opacity_anim_(animate("opacity")) , radius_(0) diff --git a/src/ui/Ripple.h b/src/ui/Ripple.h index 9184f061..3701fb6c 100644 --- a/src/ui/Ripple.h +++ b/src/ui/Ripple.h @@ -16,8 +16,8 @@ class Ripple : public QParallelAnimationGroup Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity) public: - explicit Ripple(const QPoint ¢er, QObject *parent = 0); - Ripple(const QPoint ¢er, RippleOverlay *overlay, QObject *parent = 0); + explicit Ripple(const QPoint ¢er, QObject *parent = nullptr); + Ripple(const QPoint ¢er, RippleOverlay *overlay, QObject *parent = nullptr); inline void setOverlay(RippleOverlay *overlay); diff --git a/src/ui/RippleOverlay.h b/src/ui/RippleOverlay.h index 9ef91fbf..5d12aff7 100644 --- a/src/ui/RippleOverlay.h +++ b/src/ui/RippleOverlay.h @@ -11,7 +11,7 @@ class RippleOverlay : public OverlayWidget Q_OBJECT public: - explicit RippleOverlay(QWidget *parent = 0); + explicit RippleOverlay(QWidget *parent = nullptr); void addRipple(Ripple *ripple); void addRipple(const QPoint &position, qreal radius = 300); diff --git a/src/ui/TextField.cpp b/src/ui/TextField.cpp index 0ae2516d..6c1552a8 100644 --- a/src/ui/TextField.cpp +++ b/src/ui/TextField.cpp @@ -16,7 +16,7 @@ TextField::TextField(QWidget *parent) QPalette pal; state_machine_ = new TextFieldStateMachine(this); - label_ = 0; + label_ = nullptr; label_font_size_ = 15; show_label_ = false; background_color_ = pal.color(QPalette::Window); @@ -230,9 +230,9 @@ TextFieldStateMachine::TextFieldStateMachine(TextField *parent) normal_state_ = new QState; focused_state_ = new QState; - label_ = 0; - offset_anim_ = 0; - color_anim_ = 0; + label_ = nullptr; + offset_anim_ = nullptr; + color_anim_ = nullptr; progress_ = 0.0; addState(normal_state_); diff --git a/src/ui/TextField.h b/src/ui/TextField.h index 1675a2e0..100fed31 100644 --- a/src/ui/TextField.h +++ b/src/ui/TextField.h @@ -22,7 +22,7 @@ class TextField : public QLineEdit Q_PROPERTY(QColor backgroundColor WRITE setBackgroundColor READ backgroundColor) public: - explicit TextField(QWidget *parent = 0); + explicit TextField(QWidget *parent = nullptr); void setInkColor(const QColor &color); void setBackgroundColor(const QColor &color); diff --git a/src/ui/Theme.h b/src/ui/Theme.h index d1d7e2a6..ecff02b5 100644 --- a/src/ui/Theme.h +++ b/src/ui/Theme.h @@ -78,7 +78,7 @@ class Theme : public QObject { Q_OBJECT public: - explicit Theme(QObject *parent = 0); + explicit Theme(QObject *parent = nullptr); QColor getColor(const QString &key) const; -- cgit 1.5.1 From 096db389d18a85d209bcde1a73e1f748c8adce54 Mon Sep 17 00:00:00 2001 From: Joseph Donofry Date: Tue, 4 Feb 2020 18:17:14 -0500 Subject: Make closing the reply popup actually clear the reply message --- resources/qml/TimelineView.qml | 2 +- src/ChatPage.cpp | 1 + src/TextInputWidget.h | 1 + src/timeline/TimelineViewManager.h | 6 ++++++ 4 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/TextInputWidget.h') diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 6f5eb42b..9730422d 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -300,7 +300,7 @@ Item { ToolTip.visible: closeReplyButton.hovered ToolTip.text: qsTr("Close") - onClicked: timelineManager.updateReplyingEvent(undefined) + onClicked: timelineManager.closeReply() } } } diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index e54892a6..d5e3113d 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -524,6 +524,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(this, &ChatPage::messageReply, this, [this](const RelatedInfo &related) { view_manager_->updateReplyingEvent(QString::fromStdString(related.related_event)); }); + connect(view_manager_, &TimelineViewManager::replyClosed, text_input_, &TextInputWidget::closeReplyPopup); instance_ = this; } diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h index ac79be8b..77d77e44 100644 --- a/src/TextInputWidget.h +++ b/src/TextInputWidget.h @@ -164,6 +164,7 @@ public slots: void hideUploadSpinner(); void focusLineEdit() { input_->setFocus(); } void addReply(const RelatedInfo &related); + void closeReplyPopup() { input_->closeReply(); } private slots: void addSelectedEmoji(const QString &emoji); diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 8552d6b3..625999c9 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -47,6 +47,7 @@ signals: void activeTimelineChanged(TimelineModel *timeline); void initialSyncChanged(bool isInitialSync); void replyingEventChanged(QString replyingEvent); + void replyClosed(); public slots: void updateReplyingEvent(const QString &replyingEvent) @@ -56,6 +57,11 @@ public slots: emit replyingEventChanged(replyingEvent_); } } + void closeReply() + { + this->updateReplyingEvent(nullptr); + emit replyClosed(); + } QString getReplyingEvent() const { return replyingEvent_; } void updateReadReceipts(const QString &room_id, const std::vector &event_ids); void initWithMessages(const std::map &msgs); -- cgit 1.5.1