#include "widgets/chatwidget.h" #include "channelmanager.h" #include "colorscheme.h" #include "settingsmanager.h" #include "widgets/textinputdialog.h" #include #include #include #include #include #include using namespace chatterino::messages; namespace chatterino { namespace widgets { ChatWidget::ChatWidget(QWidget *parent) : QWidget(parent) , _messages() , _channel(ChannelManager::getInstance().getEmpty()) , _channelName(QString()) , _vbox(this) , _header(this) , _view(this) , _input(this) { this->_vbox.setSpacing(0); this->_vbox.setMargin(1); this->_vbox.addWidget(&_header); this->_vbox.addWidget(&_view, 1); this->_vbox.addWidget(&_input); } ChatWidget::~ChatWidget() { detachChannel(); } std::shared_ptr ChatWidget::getChannel() const { return _channel; } std::shared_ptr &ChatWidget::getChannelRef() { return _channel; } const QString &ChatWidget::getChannelName() const { return _channelName; } void ChatWidget::setChannelName(const QString &name) { QString channelName = name.trimmed(); // return if channel name is the same if (QString::compare(channelName, _channelName, Qt::CaseInsensitive) == 0) { _channelName = channelName; _header.updateChannelText(); return; } // remove current channel if (!_channelName.isEmpty()) { ChannelManager::getInstance().removeChannel(_channelName); detachChannel(); } // update members _channelName = channelName; // update messages _messages.clear(); printf("Set channel name xD %s\n", qPrintable(name)); if (channelName.isEmpty()) { _channel = nullptr; } else { _channel = ChannelManager::getInstance().addChannel(channelName); printf("Created channel FeelsGoodMan %p\n", _channel.get()); attachChannel(_channel); } // update header _header.updateChannelText(); // update view _view.layoutMessages(); _view.update(); } void ChatWidget::attachChannel(SharedChannel channel) { // on new message _messageAppendedConnection = channel->messageAppended.connect([this](SharedMessage &message) { SharedMessageRef deleted; auto messageRef = new MessageRef(message); if (_messages.appendItem(SharedMessageRef(messageRef), deleted)) { qreal value = std::max(0.0, _view.getScrollbar()->getDesiredValue() - 1); _view.getScrollbar()->setDesiredValue(value, false); } }); // on message removed _messageRemovedConnection = _channel->messageRemovedFromStart.connect([](SharedMessage &) { // }); auto snapshot = _channel.get()->getMessageSnapshot(); for (int i = 0; i < snapshot.getSize(); i++) { SharedMessageRef deleted; auto messageRef = new MessageRef(snapshot[i]); _messages.appendItem(SharedMessageRef(messageRef), deleted); } } void ChatWidget::detachChannel() { // on message added _messageAppendedConnection.disconnect(); // on message removed _messageRemovedConnection.disconnect(); } LimitedQueueSnapshot ChatWidget::getMessagesSnapshot() { return _messages.getSnapshot(); } void ChatWidget::showChangeChannelPopup() { // create new input dialog and execute it TextInputDialog dialog(this); dialog.setText(_channelName); if (dialog.exec() == QDialog::Accepted) { setChannelName(dialog.getText()); } } void ChatWidget::layoutMessages() { if (_view.layoutMessages()) { _view.update(); } } void ChatWidget::updateGifEmotes() { _view.updateGifEmotes(); } void ChatWidget::paintEvent(QPaintEvent *) { // color the background of the chat QPainter painter(this); painter.fillRect(this->rect(), ColorScheme::getInstance().ChatBackground); } void ChatWidget::load(const boost::property_tree::ptree &tree) { // load tab text try { this->setChannelName(QString::fromStdString(tree.get("channelName"))); } catch (boost::property_tree::ptree_error) { } } boost::property_tree::ptree ChatWidget::save() { boost::property_tree::ptree tree; tree.put("channelName", this->getChannelName().toStdString()); return tree; } } // namespace widgets } // namespace chatterino