diff options
Diffstat (limited to 'Swift/QtUI/QtChatWindow.cpp')
-rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index d799e19..345139c 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -1,96 +1,97 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/QtUI/QtChatWindow.h> #include <memory> #include <boost/cstdint.hpp> #include <boost/lexical_cast.hpp> #include <QApplication> #include <QBoxLayout> #include <QCloseEvent> #include <QComboBox> #include <QCursor> #include <QDebug> #include <QFileDialog> #include <QFileInfo> +#include <QFontMetrics> #include <QInputDialog> #include <QLabel> #include <QLineEdit> #include <QMenu> #include <QMessageBox> #include <QMimeData> #include <QPoint> #include <QPushButton> #include <QSize> #include <QSplitter> #include <QString> #include <QTextDocument> #include <QTextEdit> #include <QTime> #include <QToolButton> #include <QUrl> #include <Swiften/Base/Log.h> #include <Swift/Controllers/Roster/ContactRosterItem.h> #include <Swift/Controllers/Roster/Roster.h> #include <Swift/Controllers/Roster/RosterItem.h> #include <Swift/Controllers/Settings/SettingsProvider.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/SendFileUIEvent.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> +#include <SwifTools/EmojiMapper.h> #include <SwifTools/TabComplete.h> #include <Swift/QtUI/QtAddBookmarkWindow.h> #include <Swift/QtUI/QtEditBookmarkWindow.h> -#include <Swift/QtUI/QtEmoticonsGrid.h> +#include <Swift/QtUI/QtEmojisSelector.h> #include <Swift/QtUI/QtPlainChatView.h> #include <Swift/QtUI/QtScaledAvatarCache.h> #include <Swift/QtUI/QtSettingsProvider.h> #include <Swift/QtUI/QtTextEdit.h> #include <Swift/QtUI/QtUISettingConstants.h> #include <Swift/QtUI/QtUtilities.h> #include <Swift/QtUI/QtWebKitChatView.h> #include <Swift/QtUI/Roster/QtOccupantListWidget.h> namespace Swift { -QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, const std::map<std::string, std::string>& emoticons) : QtTabbable(), id_(Q2PSTRING(contact)), contact_(contact), nextAlertId_(0), eventStream_(eventStream), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false), roomBookmarkState_(RoomNotBookmarked) { - settings_ = settings; +QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, QtSettingsProvider* qtOnlySettings) : QtTabbable(), id_(Q2PSTRING(contact)), contact_(contact), nextAlertId_(0), eventStream_(eventStream), settings_(settings), qtOnlySettings_(qtOnlySettings), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false), roomBookmarkState_(RoomNotBookmarked) { unreadCount_ = 0; isOnline_ = true; completer_ = nullptr; affiliationEditor_ = nullptr; theme_ = theme; isCorrection_ = false; labelModel_ = nullptr; correctionEnabled_ = Maybe; fileTransferEnabled_ = Maybe; updateTitleWithUnreadCount(); assert(settings); setAcceptDrops(true); alertStyleSheet_ = ".QWidget, QTextEdit { background: rgb(255, 255, 153); color: black }"; QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); layout->setContentsMargins(0,0,0,0); layout->setSpacing(2); alertLayout_ = new QVBoxLayout(); layout->addLayout(alertLayout_); subjectLayout_ = new QBoxLayout(QBoxLayout::LeftToRight); subject_ = new QLineEdit(this); subjectLayout_->addWidget(subject_); setSubject(""); subject_->setReadOnly(true); QPushButton* actionButton_ = new QPushButton(this); actionButton_->setIcon(QIcon(":/icons/actions.png")); @@ -118,71 +119,67 @@ QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventSt midBar_ = new QWidget(this); //layout->addWidget(midBar); midBar_->setAutoFillBackground(true); QHBoxLayout *midBarLayout = new QHBoxLayout(midBar_); midBarLayout->setContentsMargins(0,0,0,0); midBarLayout->setSpacing(2); //midBarLayout->addStretch(); labelsWidget_ = new QComboBox(this); labelsWidget_->setFocusPolicy(Qt::NoFocus); labelsWidget_->hide(); labelsWidget_->setSizeAdjustPolicy(QComboBox::AdjustToContents); midBarLayout->addWidget(labelsWidget_,0); connect(labelsWidget_, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentLabelChanged(int))); defaultLabelsPalette_ = labelsWidget_->palette(); QHBoxLayout* inputBarLayout = new QHBoxLayout(); inputBarLayout->setContentsMargins(0,0,0,0); inputBarLayout->setSpacing(2); input_ = new QtTextEdit(settings_, this); input_->setAcceptRichText(false); inputBarLayout->addWidget(midBar_); 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())); - QPushButton* emoticonsButton_ = new QPushButton(this); - emoticonsButton_->setIcon(QIcon(":/emoticons/smile.png")); - connect(emoticonsButton_, SIGNAL(clicked()), this, SLOT(handleEmoticonsButtonClicked())); - - emoticonsMenu_ = new QMenu(this); - QtEmoticonsGrid* emoticonsGrid = new QtEmoticonsGrid(emoticons, emoticonsMenu_); - connect(emoticonsGrid, SIGNAL(emoticonClicked(QString)), this, SLOT(handleEmoticonClicked(QString))); + QPushButton* emojisButton_ = new QPushButton(this); + emojisButton_->setText("\xF0\x9F\x98\x83"); + 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(emoticonsButton_); + actionLayout->addWidget(emojisButton_); actionLayout->addWidget(actionButton_); inputBarLayout->addLayout(actionLayout); layout->addLayout(inputBarLayout); inputClearing_ = false; contactIsTyping_ = false; tabCompletion_ = false; connect(input_, SIGNAL(unhandledKeyPressEvent(QKeyEvent*)), this, SLOT(handleKeyPressEvent(QKeyEvent*))); connect(input_, SIGNAL(returnPressed()), this, SLOT(returnPressed())); connect(input_, SIGNAL(textChanged()), this, SLOT(handleInputChanged())); connect(input_, SIGNAL(cursorPositionChanged()), this, SLOT(handleCursorPositionChanged())); setFocusProxy(input_); logRosterSplitter_->setFocusProxy(input_); midBar_->setFocusProxy(input_); messageLog_->setFocusProxy(input_); connect(messageLog_, SIGNAL(gotFocus()), input_, SLOT(setFocus())); resize(400,300); connect(messageLog_, SIGNAL(fontResized(int)), this, SIGNAL(fontResized(int))); connect(messageLog_, SIGNAL(logCleared()), this, SLOT(handleLogCleared())); treeWidget_->onSomethingSelectedChanged.connect(boost::bind(&QtChatWindow::handleOccupantSelectionChanged, this, _1)); treeWidget_->onOccupantActionSelected.connect(boost::bind(boost::ref(onOccupantActionSelected), _1, _2)); settings_->onSettingChanged.connect(boost::bind(&QtChatWindow::handleSettingChanged, this, _1)); messageLog_->showEmoticons(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS)); setMinimumSize(100, 100); } @@ -636,69 +633,85 @@ void QtChatWindow::dropEvent(QDropEvent *event) { } } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { std::vector<JID> invites = jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list")); onInviteToChat(invites); } } std::vector<JID> QtChatWindow::jidListFromQByteArray(const QByteArray& dataBytes) { QDataStream dataStream(dataBytes); std::vector<JID> invites; while (!dataStream.atEnd()) { QString jidString; dataStream >> jidString; invites.push_back(Q2PSTRING(jidString)); } return invites; } void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction>& actions) { treeWidget_->setAvailableOccupantActions(actions); } void QtChatWindow::setSubject(const std::string& subject) { //subject_->setVisible(!subject.empty()); subject_->setText(P2QSTRING(subject)); subject_->setToolTip(P2QSTRING(subject)); subject_->setCursorPosition(0); } -void QtChatWindow::handleEmoticonsButtonClicked() { - emoticonsMenu_->adjustSize(); - QSize menuSize = emoticonsMenu_->size(); - emoticonsMenu_->exec(QPoint(QCursor::pos().x() - menuSize.width(), QCursor::pos().y() - menuSize.height())); +void QtChatWindow::handleEmojisButtonClicked() { + // Create QtEmojisSelector and QMenu + emojisGrid_ = new QtEmojisSelector(qtOnlySettings_->getQSettings()); + 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_->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())); } -void QtChatWindow::handleEmoticonClicked(QString emoticonAsText) { - input_->textCursor().insertText(emoticonAsText); - input_->setFocus(); +void QtChatWindow::handleEmojiClicked(QString emoji) { + if (isVisible()) { + input_->textCursor().insertText(emoji); + input_->setFocus(); + // The next line also deletes the emojisGrid_, as it was added to the + // layout of the emojisMenu_. + emojisMenu_.reset(); + } } void QtChatWindow::handleTextInputReceivedFocus() { lastLineTracker_.setHasFocus(true); input_->setFocus(); onAllMessagesRead(); } 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* block = nullptr; QAction* unblock = nullptr; if (availableRoomActions_.empty()) { if (blockingState_ == IsBlocked) { unblock = contextMenu.addAction(tr("Unblock")); unblock->setEnabled(isOnline_); } else if (!isMUC_ && blockingState_ == IsUnblocked) { block = contextMenu.addAction(tr("Block")); |