diff options
Diffstat (limited to 'Swift/QtUI/QtChatWindow.cpp')
| -rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 113 |
1 files changed, 100 insertions, 13 deletions
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 874f710..82c65ce 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010-2017 Isode Limited. + * Copyright (c) 2010-2018 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/QtUI/QtChatWindow.h> #include <map> #include <memory> #include <string> @@ -105,20 +105,23 @@ QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventSt layout->addLayout(subjectLayout_); logRosterSplitter_ = new QSplitter(this); logRosterSplitter_->setAutoFillBackground(true); layout->addWidget(logRosterSplitter_); if (settings_->getSetting(QtUISettingConstants::USE_PLAIN_CHATS) || settings_->getSetting(QtUISettingConstants::USE_SCREENREADER)) { messageLog_ = new QtPlainChatView(this, eventStream_); } else { - messageLog_ = new QtWebKitChatView(this, eventStream_, theme, this); // I accept that passing the ChatWindow in so that the view can call the signals is somewhat inelegant, but it saves a lot of boilerplate. This patch is unpleasant enough already. So let's fix this soon (it at least needs fixing by the time history is sorted), but not now. + messageLog_ = new QtWebKitChatView(this, eventStream_, theme, this, settings); // I accept that passing the ChatWindow in so that the view can call the signals is somewhat inelegant, but it saves a lot of boilerplate. This patch is unpleasant enough already. So let's fix this soon (it at least needs fixing by the time history is sorted), but not now. } + // When used with QSplitter and setChildrenCollapsible(false), the following prevents + // this widget to be hidden, i.e. resized to zero width. + messageLog_->setMinimumWidth(20); logRosterSplitter_->addWidget(messageLog_); treeWidget_ = new QtOccupantListWidget(eventStream_, settings_, QtTreeWidget::MessageDisplayJID, this); treeWidget_->hide(); logRosterSplitter_->addWidget(treeWidget_); logRosterSplitter_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); connect(logRosterSplitter_, SIGNAL(splitterMoved(int, int)), this, SLOT(handleSplitterMoved(int, int))); midBar_ = new QWidget(this); @@ -146,23 +149,27 @@ QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventSt inputBarLayout->addWidget(input_); correctingLabel_ = new QLabel(tr("Correcting"), this); inputBarLayout->addWidget(correctingLabel_); correctingLabel_->hide(); connect(input_, SIGNAL(receivedFocus()), this, SLOT(handleTextInputReceivedFocus())); connect(input_, SIGNAL(lostFocus()), this, SLOT(handleTextInputLostFocus())); connect(input_, SIGNAL(itemDropped(QDropEvent*)), this, SLOT(dropEvent(QDropEvent*))); QPushButton* emojisButton_ = new QPushButton(this); - -#ifdef SWIFTEN_PLATFORM_MACOSX emojisButton_->setText("\xF0\x9F\x98\x83"); -#else - emojisButton_->setIcon(QIcon(":/emoticons/smile.png")); + +#if defined(SWIFTEN_PLATFORM_WINDOWS) || defined(SWIFTEN_PLATFORM_LINUX) + //Using a emoji glyph instead of an image makes the button sizes inequal in windows & linux, + //so we set fixed size for both buttons, the one that is hinted for actionButton_ + emojisButton_->setMaximumWidth(actionButton_->sizeHint().width()); + emojisButton_->setMaximumHeight(actionButton_->sizeHint().height()); + actionButton_->setMaximumWidth(actionButton_->sizeHint().width()); + actionButton_->setMaximumHeight(actionButton_->sizeHint().height()); #endif connect(emojisButton_, SIGNAL(clicked()), this, SLOT(handleEmojisButtonClicked())); // using an extra layout to work around Qt margin glitches on OS X QHBoxLayout* actionLayout = new QHBoxLayout(); actionLayout->addWidget(emojisButton_); actionLayout->addWidget(actionButton_); inputBarLayout->addLayout(actionLayout); @@ -347,18 +354,22 @@ void QtChatWindow::cancelCorrection() { labelsWidget_->setEnabled(true); } QByteArray QtChatWindow::getSplitterState() { return logRosterSplitter_->saveState(); } void QtChatWindow::handleChangeSplitterState(QByteArray state) { logRosterSplitter_->restoreState(state); +#ifdef SWIFTEN_PLATFORM_MACOSX + logRosterSplitter_->setHandleWidth(0); +#endif + logRosterSplitter_->setChildrenCollapsible(false); } void QtChatWindow::handleSplitterMoved(int, int) { emit splitterMoved(); } void QtChatWindow::tabComplete() { if (!completer_) { return; @@ -488,19 +499,19 @@ void QtChatWindow::setOnline(bool online) { } } } void QtChatWindow::showEvent(QShowEvent* event) { emit windowOpening(); QWidget::showEvent(event); } -void QtChatWindow::setUnreadMessageCount(int count) { +void QtChatWindow::setUnreadMessageCount(size_t count) { if (unreadCount_ != count) { unreadCount_ = count; updateTitleWithUnreadCount(); emit countUpdated(); } } void QtChatWindow::setContactChatState(ChatState::ChatStateType state) { contactIsTyping_ = (state == ChatState::Composing); @@ -530,19 +541,19 @@ void QtChatWindow::updateTitleWithUnreadCount() { setWindowTitle(contact_); } emit titleUpdated(); } void QtChatWindow::flash() { emit requestFlash(); } -int QtChatWindow::getCount() { +size_t QtChatWindow::getCount() { return unreadCount_; } void QtChatWindow::replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, const ChatWindow::TimestampBehaviour timestampBehaviour) { messageLog_->replaceSystemMessage(message, id, timestampBehaviour); } void QtChatWindow::returnPressed() { if (!isOnline_ || (blockingState_ == IsBlocked)) { @@ -687,19 +698,19 @@ void QtChatWindow::setSubject(const std::string& subject) { } void QtChatWindow::handleEmojisButtonClicked() { // Create QtEmojisSelector and QMenu emojisGrid_ = new QtEmojisSelector(qtOnlySettings_->getQSettings(), emoticonsMap_); auto emojisLayout = new QVBoxLayout(); emojisLayout->setContentsMargins(style()->pixelMetric(QStyle::PM_MenuHMargin),style()->pixelMetric(QStyle::PM_MenuVMargin), style()->pixelMetric(QStyle::PM_MenuHMargin),style()->pixelMetric(QStyle::PM_MenuVMargin)); emojisLayout->addWidget(emojisGrid_); - emojisMenu_ = std::unique_ptr<QMenu>(new QMenu()); + emojisMenu_ = std::make_unique<QMenu>(); emojisMenu_->setLayout(emojisLayout); emojisMenu_->adjustSize(); connect(emojisGrid_, SIGNAL(emojiClicked(QString)), this, SLOT(handleEmojiClicked(QString))); QSize menuSize = emojisMenu_->size(); emojisMenu_->exec(QPoint(QCursor::pos().x() - menuSize.width(), QCursor::pos().y() - menuSize.height())); } @@ -710,32 +721,43 @@ void QtChatWindow::handleEmojiClicked(QString emoji) { // We cannot delete the emojisGrid_ // Grid may not close yet and we should not try to destroy it. emojisMenu_->setVisible(false); } } void QtChatWindow::handleTextInputReceivedFocus() { lastLineTracker_.setHasFocus(true); input_->setFocus(); - onAllMessagesRead(); + if (focusTimer_) { + focusTimer_->stop(); + } + else { + focusTimer_ = std::make_unique<QTimer>(this); + focusTimer_->setSingleShot(true); + focusTimer_->setTimerType(Qt::CoarseTimer); + connect(focusTimer_.get(), &QTimer::timeout, this, &QtChatWindow::handleFocusTimerTick); + } + focusTimer_->setInterval(1000); + focusTimer_->start(); } void QtChatWindow::handleTextInputLostFocus() { lastLineTracker_.setHasFocus(false); } void QtChatWindow::handleActionButtonClicked() { QMenu contextMenu; QAction* changeSubject = nullptr; QAction* configure = nullptr; QAction* affiliations = nullptr; QAction* destroy = nullptr; QAction* invite = nullptr; + QAction* leave = nullptr; QAction* block = nullptr; QAction* unblock = nullptr; if (availableRoomActions_.empty()) { if (blockingState_ == IsBlocked) { unblock = contextMenu.addAction(tr("Unblock")); unblock->setEnabled(isOnline_); } @@ -777,18 +799,22 @@ void QtChatWindow::handleActionButtonClicked() { break; case ChatWindow::Destroy: destroy = contextMenu.addAction(tr("Destroy room")); destroy->setEnabled(isOnline_); break; case ChatWindow::Invite: invite = contextMenu.addAction(tr("Invite person to this room…")); invite->setEnabled(isOnline_); break; + case ChatWindow::Leave: + leave = contextMenu.addAction(tr("Leave room")); + leave->setEnabled(isOnline_); + break; } } } QAction* bookmark = nullptr; if (isMUC_) { if (roomBookmarkState_ == RoomNotBookmarked) { bookmark = contextMenu.addAction(tr("Bookmark this room...")); } @@ -828,18 +854,21 @@ void QtChatWindow::handleActionButtonClicked() { msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); if (msgBox.exec() == QMessageBox::Yes) { onDestroyRequest(); } } else if (result == invite) { onInviteToChat(std::vector<JID>()); } + else if (result == leave) { + close(); + } else if (result == block) { onBlockUserRequest(); } else if (result == unblock) { onUnblockUserRequest(); } else if (result == bookmark) { onBookmarkRequest(); } @@ -861,26 +890,28 @@ void QtChatWindow::setAvailableRoomActions(const std::vector<RoomAction>& action void QtChatWindow::setBlockingState(BlockingState state) { blockingState_ = state; } void QtChatWindow::setCanInitiateImpromptuChats(bool supportsImpromptu) { supportsImpromptuChat_ = supportsImpromptu; } void QtChatWindow::showBookmarkWindow(const MUCBookmark& bookmark) { - if (roomBookmarkState_ == RoomNotBookmarked) { - QtAddBookmarkWindow* window = new QtAddBookmarkWindow(eventStream_, bookmark); + if (roomBookmarkState_ != RoomNotBookmarked) { + QtEditBookmarkWindow* window = new QtEditBookmarkWindow(eventStream_, bookmark); window->show(); } +#ifndef NOT_YET else { - QtEditBookmarkWindow* window = new QtEditBookmarkWindow(eventStream_, bookmark); + QtAddBookmarkWindow* window = new QtAddBookmarkWindow(eventStream_, bookmark); window->show(); } +#endif // ! NOT_YET } std::string QtChatWindow::getID() const { return id_; } void QtChatWindow::setEmphasiseFocus(bool emphasise) { input_->setEmphasiseFocus(emphasise); } @@ -978,10 +1009,66 @@ void QtChatWindow::setAckState(const std::string& id, AckState state) { void QtChatWindow::setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) { messageLog_->setMessageReceiptState(id, state); } void QtChatWindow::setBookmarkState(RoomBookmarkState bookmarkState) { roomBookmarkState_ = bookmarkState; } +void QtChatWindow::setChatSecurityMarking(const std::string& markingValue, const std::string& markingForegroundColorValue, const std::string& markingBackgroundColorValue) { + auto layout = static_cast<QBoxLayout*>(this->layout()); + + if (securityMarkingLayout_) { + layout->removeItem(securityMarkingLayout_); + securityMarkingLayout_->removeWidget(securityMarkingDisplay_); + delete securityMarkingLayout_; + } + delete securityMarkingDisplay_; + + securityMarkingLayout_ = new QHBoxLayout(); + securityMarkingDisplay_ = new QLabel(P2QSTRING(markingValue)); + + securityMarkingLayout_->addWidget(securityMarkingDisplay_); + layout->insertLayout(1, securityMarkingLayout_); + + auto palette = securityMarkingDisplay_->palette(); + palette.setColor(securityMarkingDisplay_->foregroundRole(), P2QSTRING(markingForegroundColorValue)); + palette.setColor(securityMarkingDisplay_->backgroundRole(), P2QSTRING(markingBackgroundColorValue)); + + securityMarkingDisplay_->setPalette(palette); + securityMarkingDisplay_->setContentsMargins(4,4,4,4); + securityMarkingDisplay_->setAutoFillBackground(true); + securityMarkingDisplay_->setAlignment(Qt::AlignCenter); +} + +void QtChatWindow::removeChatSecurityMarking() { + if (!securityMarkingLayout_) { + return; + } + + auto layout = static_cast<QBoxLayout*>(this->layout()); + + layout->removeItem(securityMarkingLayout_); + securityMarkingLayout_->removeWidget(securityMarkingDisplay_); + + delete securityMarkingDisplay_; + delete securityMarkingLayout_; + securityMarkingDisplay_ = nullptr; + securityMarkingLayout_ = nullptr; +} + +void QtChatWindow::handleFocusTimerTick() { + if (hasFocus()) { + onAllMessagesRead(); + } + focusTimer_.reset(); +} + +void QtChatWindow::resendMessage(const std::string& id) { + if (!isOnline_ || (blockingState_ == IsBlocked)) { + return; + } + onResendMessageRequest(id); +} + } |
Swift