2017-06-07 10:09:24 +02:00
|
|
|
#pragma once
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2023-11-05 17:25:26 +01:00
|
|
|
#include "messages/Message.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "widgets/BaseWidget.hpp"
|
2017-01-21 05:14:27 +01:00
|
|
|
|
|
|
|
#include <QHBoxLayout>
|
2017-01-22 05:58:23 +01:00
|
|
|
#include <QLabel>
|
2017-01-21 05:14:27 +01:00
|
|
|
#include <QLineEdit>
|
2017-01-18 04:52:47 +01:00
|
|
|
#include <QPaintEvent>
|
2023-06-04 13:24:04 +02:00
|
|
|
#include <QPointer>
|
2017-01-20 06:10:28 +01:00
|
|
|
#include <QTextEdit>
|
2017-01-21 05:14:27 +01:00
|
|
|
#include <QVBoxLayout>
|
2017-01-18 04:52:47 +01:00
|
|
|
#include <QWidget>
|
Sort and force grouping of includes (#4172)
This change enforces strict include grouping using IncludeCategories
In addition to adding this to the .clang-format file and applying it in the tests/src and src directories, I also did the following small changes:
In ChatterSet.hpp, I changed lrucache to a <>include
In Irc2.hpp, I change common/SignalVector.hpp to a "project-include"
In AttachedWindow.cpp, NativeMessaging.cpp, WindowsHelper.hpp, BaseWindow.cpp, and StreamerMode.cpp, I disabled clang-format for the windows-includes
In WindowDescriptors.hpp, I added the missing vector include. It was previously not needed because the include was handled by another file that was previously included first.
clang-format minimum version has been bumped, so Ubuntu version used in the check-formatting job has been bumped to 22.04 (which is the latest LTS)
2022-11-27 19:32:53 +01:00
|
|
|
|
2022-07-31 12:45:25 +02:00
|
|
|
#include <memory>
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2017-01-18 21:30:23 +01:00
|
|
|
namespace chatterino {
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
class Split;
|
2018-08-11 22:23:06 +02:00
|
|
|
class EmotePopup;
|
2021-06-19 18:29:17 +02:00
|
|
|
class InputCompletionPopup;
|
2018-08-11 22:23:06 +02:00
|
|
|
class EffectLabel;
|
2024-07-14 21:06:42 +02:00
|
|
|
class MessageView;
|
2018-08-11 22:23:06 +02:00
|
|
|
class ResizingTextEdit;
|
2022-12-03 14:02:39 +01:00
|
|
|
class ChannelView;
|
2023-09-24 14:17:17 +02:00
|
|
|
enum class CompletionKind;
|
2017-01-29 13:23:22 +01:00
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
class SplitInput : public BaseWidget
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
2022-07-31 12:45:25 +02:00
|
|
|
SplitInput(Split *_chatWidget, bool enableInlineReplying = true);
|
2022-12-03 14:02:39 +01:00
|
|
|
SplitInput(QWidget *parent, Split *_chatWidget, ChannelView *_channelView,
|
2022-07-31 12:45:25 +02:00
|
|
|
bool enableInlineReplying = true);
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2022-11-27 20:39:53 +01:00
|
|
|
bool hasSelection() const;
|
|
|
|
void clearSelection() const;
|
|
|
|
|
2021-07-24 12:01:50 +02:00
|
|
|
bool isEditFirstWord() const;
|
2017-12-17 16:19:16 +01:00
|
|
|
QString getInputText() const;
|
2018-01-24 20:58:53 +01:00
|
|
|
void insertText(const QString &text);
|
2017-12-17 16:19:16 +01:00
|
|
|
|
2024-07-14 21:06:42 +02:00
|
|
|
void setReply(MessagePtr target);
|
2022-07-31 12:45:25 +02:00
|
|
|
void setPlaceholderText(const QString &text);
|
|
|
|
|
2022-06-26 18:53:09 +02:00
|
|
|
/**
|
|
|
|
* @brief Hide the widget
|
|
|
|
*
|
|
|
|
* This is a no-op if the SplitInput is already hidden
|
|
|
|
**/
|
|
|
|
void hide();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Show the widget
|
|
|
|
*
|
|
|
|
* This is a no-op if the SplitInput is already shown
|
|
|
|
**/
|
|
|
|
void show();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Returns the hidden or shown state of the SplitInput
|
|
|
|
*
|
|
|
|
* Hidden in this context means "has 0 height", meaning it won't be visible
|
|
|
|
* but Qt still treats the widget as "technically visible" so we receive events
|
|
|
|
* as if the widget is visible
|
|
|
|
**/
|
|
|
|
bool isHidden() const;
|
|
|
|
|
2024-02-17 13:26:54 +01:00
|
|
|
/**
|
|
|
|
* @brief Sets the text of this input
|
|
|
|
*
|
|
|
|
* This method should only be used in tests
|
|
|
|
*/
|
|
|
|
void setInputText(const QString &newInputText);
|
|
|
|
|
2017-12-17 16:19:16 +01:00
|
|
|
pajlada::Signals::Signal<const QString &> textChanged;
|
2022-12-07 19:21:04 +01:00
|
|
|
pajlada::Signals::NoArgSignal selectionChanged;
|
2017-09-21 02:20:02 +02:00
|
|
|
|
2017-01-01 02:30:42 +01:00
|
|
|
protected:
|
2022-06-26 18:53:09 +02:00
|
|
|
void scaleChangedEvent(float scale_) override;
|
|
|
|
void themeChangedEvent() override;
|
2017-01-22 05:58:23 +01:00
|
|
|
|
2022-06-26 18:53:09 +02:00
|
|
|
void paintEvent(QPaintEvent * /*event*/) override;
|
|
|
|
void resizeEvent(QResizeEvent * /*event*/) override;
|
2017-07-31 01:26:20 +02:00
|
|
|
|
2022-11-21 19:27:56 +01:00
|
|
|
void mousePressEvent(QMouseEvent *event) override;
|
|
|
|
|
2022-07-31 12:45:25 +02:00
|
|
|
virtual void giveFocus(Qt::FocusReason reason);
|
|
|
|
|
2024-01-17 21:05:44 +01:00
|
|
|
QString handleSendMessage(const std::vector<QString> &arguments);
|
2022-07-31 12:45:25 +02:00
|
|
|
void postMessageSend(const QString &message,
|
|
|
|
const std::vector<QString> &arguments);
|
|
|
|
|
2024-07-14 21:06:42 +02:00
|
|
|
/// Clears the input box, clears reply target if inline replies are enabled
|
2022-07-31 12:45:25 +02:00
|
|
|
void clearInput();
|
|
|
|
|
2021-11-21 18:46:21 +01:00
|
|
|
void addShortcuts() override;
|
2018-07-06 19:23:47 +02:00
|
|
|
void initLayout();
|
2021-11-21 18:46:21 +01:00
|
|
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
2023-09-16 13:52:51 +02:00
|
|
|
#ifdef DEBUG
|
|
|
|
bool keyPressedEventInstalled{};
|
|
|
|
#endif
|
2018-07-06 19:23:47 +02:00
|
|
|
void installKeyPressedEvent();
|
2020-08-15 18:59:17 +02:00
|
|
|
void onCursorPositionChanged();
|
2021-05-15 16:24:46 +02:00
|
|
|
void onTextChanged();
|
2018-07-06 19:23:47 +02:00
|
|
|
void updateEmoteButton();
|
2021-06-19 18:29:17 +02:00
|
|
|
void updateCompletionPopup();
|
2023-09-24 14:17:17 +02:00
|
|
|
void showCompletionPopup(const QString &text, CompletionKind kind);
|
2021-06-19 18:29:17 +02:00
|
|
|
void hideCompletionPopup();
|
2022-12-18 14:25:11 +01:00
|
|
|
void insertCompletionText(const QString &input_) const;
|
2018-08-27 14:36:01 +02:00
|
|
|
void openEmotePopup();
|
2024-07-14 21:06:42 +02:00
|
|
|
void clearReplyTarget();
|
2018-07-06 19:23:47 +02:00
|
|
|
|
2022-07-31 12:45:25 +02:00
|
|
|
void updateCancelReplyButton();
|
|
|
|
|
2022-06-26 18:53:09 +02:00
|
|
|
// scaledMaxHeight returns the height in pixels that this widget can grow to
|
|
|
|
// This does not take hidden into account, so callers must take hidden into account themselves
|
|
|
|
int scaledMaxHeight() const;
|
|
|
|
|
2022-11-13 12:47:46 +01:00
|
|
|
// Returns true if the channel this input is connected to is a Twitch channel,
|
|
|
|
// the user's setting is set to Prevent, and the given text goes beyond the Twitch message length limit
|
|
|
|
bool shouldPreventInput(const QString &text) const;
|
|
|
|
|
2024-07-14 21:06:42 +02:00
|
|
|
int marginForTheme() const;
|
|
|
|
|
2024-07-21 00:49:46 +02:00
|
|
|
void applyOuterMargin();
|
|
|
|
|
|
|
|
int replyMessageWidth() const;
|
|
|
|
|
2018-06-06 18:57:22 +02:00
|
|
|
Split *const split_;
|
2022-12-03 14:02:39 +01:00
|
|
|
ChannelView *const channelView_;
|
2023-06-04 13:24:04 +02:00
|
|
|
QPointer<EmotePopup> emotePopup_;
|
|
|
|
QPointer<InputCompletionPopup> inputCompletionPopup_;
|
2017-01-29 13:23:22 +01:00
|
|
|
|
2018-01-25 20:49:49 +01:00
|
|
|
struct {
|
2024-07-14 21:06:42 +02:00
|
|
|
// vbox for all components
|
2022-07-31 12:45:25 +02:00
|
|
|
QVBoxLayout *vbox;
|
|
|
|
|
2024-07-14 21:06:42 +02:00
|
|
|
// reply widgets
|
2022-07-31 12:45:25 +02:00
|
|
|
QWidget *replyWrapper;
|
2024-07-14 21:06:42 +02:00
|
|
|
QVBoxLayout *replyVbox;
|
2022-07-31 12:45:25 +02:00
|
|
|
QHBoxLayout *replyHbox;
|
2024-07-14 21:06:42 +02:00
|
|
|
MessageView *replyMessage;
|
2022-07-31 12:45:25 +02:00
|
|
|
QLabel *replyLabel;
|
|
|
|
EffectLabel *cancelReplyButton;
|
2018-01-25 20:49:49 +01:00
|
|
|
|
2024-07-14 21:06:42 +02:00
|
|
|
// input widgets
|
|
|
|
QWidget *inputWrapper;
|
|
|
|
QHBoxLayout *inputHbox;
|
|
|
|
ResizingTextEdit *textEdit;
|
|
|
|
QLabel *textEditLength;
|
|
|
|
EffectLabel *sendButton;
|
|
|
|
EffectLabel *emoteButton;
|
|
|
|
} ui_;
|
|
|
|
|
|
|
|
MessagePtr replyTarget_ = nullptr;
|
2022-07-31 12:45:25 +02:00
|
|
|
bool enableInlineReplying_;
|
|
|
|
|
2021-12-19 15:57:56 +01:00
|
|
|
pajlada::Signals::SignalHolder managedConnections_;
|
2018-06-06 18:57:22 +02:00
|
|
|
QStringList prevMsg_;
|
|
|
|
QString currMsg_;
|
|
|
|
int prevIndex_ = 0;
|
2018-01-25 20:49:49 +01:00
|
|
|
|
2022-06-26 18:53:09 +02:00
|
|
|
// Hidden denotes whether this split input should be hidden or not
|
|
|
|
// This is used instead of the regular QWidget::hide/show because
|
|
|
|
// focus events don't work as expected, so instead we use this bool and
|
|
|
|
// set the height of the split input to 0 if we're supposed to be hidden instead
|
|
|
|
bool hidden{false};
|
|
|
|
|
2017-01-22 05:58:23 +01:00
|
|
|
private slots:
|
2017-01-29 13:23:22 +01:00
|
|
|
void editTextChanged();
|
2017-06-11 20:53:43 +02:00
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
friend class Split;
|
2022-07-31 12:45:25 +02:00
|
|
|
friend class ReplyThreadPopup;
|
2017-01-01 02:30:42 +01:00
|
|
|
};
|
2017-06-07 10:09:24 +02:00
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
} // namespace chatterino
|