From 121361e37bc2cc8ab1eae2f2aea92975a62e5511 Mon Sep 17 00:00:00 2001 From: Tobias Markmann Date: Tue, 7 Mar 2017 20:32:56 +0100 Subject: Use text-based emoticons on Linux and Windows The new unicode-based emoji dialog currently only provides a good experience on macOS. This commit enables the unicode-based emoji dialog on macOS and uses the text-based emoticons on Linux and Windows. Test-Information: Tested on macOS 10.12.3 with Qt 5.5.1 and Windows 8 with Qt 5.5.1. Change-Id: Ibee20eacafa5788bcdf5a46e1ceac713a28a0383 diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 345139c..f57b83f 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -6,7 +6,9 @@ #include +#include #include +#include #include #include @@ -38,6 +40,7 @@ #include #include +#include #include #include @@ -64,7 +67,7 @@ namespace Swift { -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) { +QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, QtSettingsProvider* qtOnlySettings, const std::map& emoticonsMap) : QtTabbable(), id_(Q2PSTRING(contact)), contact_(contact), nextAlertId_(0), eventStream_(eventStream), settings_(settings), qtOnlySettings_(qtOnlySettings), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false), roomBookmarkState_(RoomNotBookmarked), emoticonsMap_(emoticonsMap) { unreadCount_ = 0; isOnline_ = true; completer_ = nullptr; @@ -147,7 +150,12 @@ QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventSt connect(input_, SIGNAL(receivedFocus()), this, SLOT(handleTextInputReceivedFocus())); connect(input_, SIGNAL(lostFocus()), this, SLOT(handleTextInputLostFocus())); QPushButton* emojisButton_ = new QPushButton(this); + +#ifdef SWIFTEN_PLATFORM_MACOSX emojisButton_->setText("\xF0\x9F\x98\x83"); +#else + emojisButton_->setIcon(QIcon(":/emoticons/smile.png")); +#endif connect(emojisButton_, SIGNAL(clicked()), this, SLOT(handleEmojisButtonClicked())); // using an extra layout to work around Qt margin glitches on OS X @@ -662,7 +670,7 @@ void QtChatWindow::setSubject(const std::string& subject) { void QtChatWindow::handleEmojisButtonClicked() { // Create QtEmojisSelector and QMenu - emojisGrid_ = new QtEmojisSelector(qtOnlySettings_->getQSettings()); + 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)); diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index 4c64c84..fca4aec 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include @@ -81,7 +82,7 @@ namespace Swift { Q_OBJECT public: - QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, QtSettingsProvider* qtOnlySettings); + QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, QtSettingsProvider* qtOnlySettings, const std::map& emoticonsMap); virtual ~QtChatWindow(); std::string addMessage(const ChatMessage& message, const std::string &senderName, bool senderIsSelf, std::shared_ptr label, const std::string& avatarPath, const boost::posix_time::ptime& time); std::string addAction(const ChatMessage& message, const std::string &senderName, bool senderIsSelf, std::shared_ptr label, const std::string& avatarPath, const boost::posix_time::ptime& time); @@ -236,5 +237,6 @@ namespace Swift { RoomBookmarkState roomBookmarkState_; std::unique_ptr emojisMenu_; QPointer emojisGrid_; + std::map emoticonsMap_; }; } diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp index 5a4a501..49cfe4d 100644 --- a/Swift/QtUI/QtChatWindowFactory.cpp +++ b/Swift/QtUI/QtChatWindowFactory.cpp @@ -23,7 +23,7 @@ namespace Swift { static const QString SPLITTER_STATE = "mucSplitterState"; static const QString CHAT_TABS_GEOMETRY = "chatTabsGeometry"; -QtChatWindowFactory::QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabsBase* tabs, const QString& themePath) : themePath_(themePath) { +QtChatWindowFactory::QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabsBase* tabs, const QString& themePath, const std::map& emoticonsMap) : themePath_(themePath), emoticonsMap_(emoticonsMap) { qtOnlySettings_ = qtSettings; settings_ = settings; tabs_ = tabs; @@ -54,7 +54,7 @@ ChatWindow* QtChatWindowFactory::createChatWindow(const JID &contact,UIEventStre } } - QtChatWindow* chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), theme_, eventStream, settings_, qtOnlySettings_); + QtChatWindow* chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), theme_, eventStream, settings_, qtOnlySettings_, emoticonsMap_); connect(chatWindow, SIGNAL(splitterMoved()), this, SLOT(handleSplitterMoved())); connect(this, SIGNAL(changeSplitterState(QByteArray)), chatWindow, SLOT(handleChangeSplitterState(QByteArray))); diff --git a/Swift/QtUI/QtChatWindowFactory.h b/Swift/QtUI/QtChatWindowFactory.h index a217215..2bb6a90 100644 --- a/Swift/QtUI/QtChatWindowFactory.h +++ b/Swift/QtUI/QtChatWindowFactory.h @@ -6,6 +6,9 @@ #pragma once +#include +#include + #include #include #include @@ -29,7 +32,7 @@ namespace Swift { class QtChatWindowFactory : public QObject, public ChatWindowFactory { Q_OBJECT public: - QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabsBase* tabs, const QString& themePath); + QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabsBase* tabs, const QString& themePath, const std::map& emoticonsMap); ~QtChatWindowFactory(); ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream); signals: @@ -43,5 +46,6 @@ namespace Swift { QtSettingsProvider* qtOnlySettings_; QtChatTabsBase* tabs_; QtChatTheme* theme_; + std::map emoticonsMap_; }; } diff --git a/Swift/QtUI/QtEmojiCell.cpp b/Swift/QtUI/QtEmojiCell.cpp index 3f2c652..865f1f6 100644 --- a/Swift/QtUI/QtEmojiCell.cpp +++ b/Swift/QtUI/QtEmojiCell.cpp @@ -30,14 +30,27 @@ namespace Swift { connect(this, SIGNAL(clicked()), this, SLOT(handleEmojiClicked())); } + QtEmojiCell::QtEmojiCell(QIcon icon, QString text, QWidget* parent) : QPushButton(parent), text_(text) { + setIcon(icon); + setFlat(true); + connect(this, SIGNAL(clicked()), this, SLOT(handleEmojiClicked())); + setFixedSize(icon.availableSizes()[0] * 1.5); + } + QtEmojiCell::QtEmojiCell(const QtEmojiCell& b) : QtEmojiCell(b.toolTip(), b.text()) { + } QtEmojiCell::~QtEmojiCell() { } void QtEmojiCell::handleEmojiClicked () { - emit emojiClicked(text()); + if (text_.isEmpty()) { + emit emojiClicked(text()); + } + else { + emit emojiClicked(text_); + } } } diff --git a/Swift/QtUI/QtEmojiCell.h b/Swift/QtUI/QtEmojiCell.h index 62f989b..250b10d 100644 --- a/Swift/QtUI/QtEmojiCell.h +++ b/Swift/QtUI/QtEmojiCell.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Isode Limited. + * Copyright (c) 2016-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -20,11 +20,16 @@ namespace Swift { public: QtEmojiCell(const QtEmojiCell& b); QtEmojiCell(QString shortname, QString text, QWidget* parent = nullptr); + QtEmojiCell(QIcon icon, QString text, QWidget* parent = nullptr); ~QtEmojiCell(); + signals: void emojiClicked(QString emojiAsText); private slots: void handleEmojiClicked(); + + private: + QString text_; }; } diff --git a/Swift/QtUI/QtEmojisGrid.cpp b/Swift/QtUI/QtEmojisGrid.cpp index 6064a66..981dd67 100644 --- a/Swift/QtUI/QtEmojisGrid.cpp +++ b/Swift/QtUI/QtEmojisGrid.cpp @@ -47,6 +47,12 @@ namespace Swift { } } + void QtEmojisGrid::addEmoticon(QIcon icon, QString text) { + auto emoji = new QtEmojiCell(icon, text); + connect(emoji, SIGNAL(emojiClicked(QString)), this, SIGNAL(onEmojiSelected(QString))); + addItem(new QWidgetItem(emoji)); + } + void QtEmojisGrid::clearEmojis() { QLayoutItem* child = nullptr; while ((child = this->takeAt(0)) != nullptr) { diff --git a/Swift/QtUI/QtEmojisGrid.h b/Swift/QtUI/QtEmojisGrid.h index b7ba87f..5e6c770 100644 --- a/Swift/QtUI/QtEmojisGrid.h +++ b/Swift/QtUI/QtEmojisGrid.h @@ -22,6 +22,7 @@ namespace Swift { protected: void setEmojis(const QVector& emojis); + void addEmoticon(QIcon icon, QString text); private: void clearEmojis(); diff --git a/Swift/QtUI/QtEmojisScroll.cpp b/Swift/QtUI/QtEmojisScroll.cpp index 2c347bb..be505b6 100644 --- a/Swift/QtUI/QtEmojisScroll.cpp +++ b/Swift/QtUI/QtEmojisScroll.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include #include @@ -26,7 +28,11 @@ namespace Swift { this->layout()->setContentsMargins(0,0,0,0); if (emojiLayout->itemAt(0)) { +#ifdef SWIFTEN_PLATFORM_MACOSX setMinimumHeight(emojiLayout->itemAt(0)->minimumSize().height() * 8); +#else + setMinimumHeight(emojiLayout->itemAt(0)->minimumSize().height() * 2); +#endif } } } diff --git a/Swift/QtUI/QtEmojisSelector.cpp b/Swift/QtUI/QtEmojisSelector.cpp index 8b21380..62ed862 100644 --- a/Swift/QtUI/QtEmojisSelector.cpp +++ b/Swift/QtUI/QtEmojisSelector.cpp @@ -9,17 +9,22 @@ #include #include #include +#include #include +#include + #include #include #include +#include #include #include namespace Swift { - QtEmojisSelector::QtEmojisSelector(QSettings* settings, QWidget* parent) : QTabWidget(parent), settings_(settings) { + QtEmojisSelector::QtEmojisSelector(QSettings* settings, const std::map& emoticonsMap, QWidget* parent) : QTabWidget(parent), settings_(settings), emoticonsMap_(emoticonsMap) { +#ifdef SWIFTEN_PLATFORM_MACOSX recentEmojisGrid_ = addRecentTab(); connect(recentEmojisGrid_, SIGNAL(onEmojiSelected(QString)), this, SLOT(emojiClickedSlot(QString))); @@ -31,10 +36,15 @@ namespace Swift { } loadSettings(); +#else + setupEmoticonsTab(); +#endif } QtEmojisSelector::~QtEmojisSelector() { +#ifdef SWIFTEN_PLATFORM_MACOSX writeSettings(); +#endif } QtRecentEmojisGrid* QtEmojisSelector::addRecentTab() { @@ -68,8 +78,18 @@ namespace Swift { settings_->setValue("currentEmojiTab", currentIndex()); } + void QtEmojisSelector::setupEmoticonsTab() { + QtEmojisGrid* grid = new QtEmoticonsGrid(emoticonsMap_); + QtEmojisScroll* scroll = new QtEmojisScroll(grid); + QTabWidget::addTab(scroll, QIcon(":/emoticons/smile.png"),""); + connect(grid, SIGNAL(onEmojiSelected(QString)), this, SLOT(emojiClickedSlot(QString))); + tabBar()->hide(); + } + void QtEmojisSelector::emojiClickedSlot(QString emoji) { - recentEmojisGrid_->handleEmojiClicked(emoji); + if (recentEmojisGrid_) { + recentEmojisGrid_->handleEmojiClicked(emoji); + } emit emojiClicked(emoji); } } diff --git a/Swift/QtUI/QtEmojisSelector.h b/Swift/QtUI/QtEmojisSelector.h index 1065aa0..7ac11d0 100644 --- a/Swift/QtUI/QtEmojisSelector.h +++ b/Swift/QtUI/QtEmojisSelector.h @@ -6,6 +6,9 @@ #pragma once +#include +#include + #include #include @@ -17,7 +20,7 @@ namespace Swift { class QtEmojisSelector : public QTabWidget { Q_OBJECT public: - QtEmojisSelector(QSettings* settings, QWidget * parent = 0); + QtEmojisSelector(QSettings* settings, const std::map& emoticonsMap, QWidget * parent = 0); ~QtEmojisSelector(); public slots: @@ -32,9 +35,12 @@ class QtEmojisSelector : public QTabWidget { void loadSettings(); void writeSettings(); + void setupEmoticonsTab(); + private: QSettings* settings_ = nullptr; QtRecentEmojisGrid* recentEmojisGrid_ = nullptr; + std::map emoticonsMap_; }; } diff --git a/Swift/QtUI/QtEmoticonsGrid.cpp b/Swift/QtUI/QtEmoticonsGrid.cpp new file mode 100644 index 0000000..a592e90 --- /dev/null +++ b/Swift/QtUI/QtEmoticonsGrid.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include + +#include + +#include + +#include +#include + +namespace Swift { + + QtEmoticonsGrid::QtEmoticonsGrid(const std::map& emoticonsMap) : QtEmojisGrid() { + std::unordered_set usedEmoticons; + for (const auto& emoticonPair : emoticonsMap) { + if (usedEmoticons.find(emoticonPair.second) == usedEmoticons.end()) { + usedEmoticons.insert(emoticonPair.second); + + auto filePath = P2QSTRING(emoticonPair.second); + if (filePath.startsWith("qrc:/")) { + filePath.remove(0, 3); + } + auto icon = QIcon(filePath); + auto text = P2QSTRING(emoticonPair.first); + + addEmoticon(icon, text); + } + } + } + + QtEmoticonsGrid::~QtEmoticonsGrid() { + + } + +} diff --git a/Swift/QtUI/QtEmoticonsGrid.h b/Swift/QtUI/QtEmoticonsGrid.h new file mode 100644 index 0000000..2fc2907 --- /dev/null +++ b/Swift/QtUI/QtEmoticonsGrid.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include +#include +#include + +#include + +namespace Swift { + class QtEmoticonsGrid : public QtEmojisGrid { + Q_OBJECT + public: + explicit QtEmoticonsGrid(const std::map& emoticonsMap); + ~QtEmoticonsGrid(); + + }; +} diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index b61147d..7b4e2c3 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -229,7 +229,7 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME); storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir(), networkFactories_.getCryptoProvider()); certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory(), networkFactories_.getCryptoProvider()); - chatWindowFactory_ = new QtChatWindowFactory(splitter_, settingsHierachy_, qtSettings_, tabs_, ":/themes/Default/"); + chatWindowFactory_ = new QtChatWindowFactory(splitter_, settingsHierachy_, qtSettings_, tabs_, ":/themes/Default/", emoticons); soundPlayer_ = new QtSoundPlayer(applicationPathProvider_); // Ugly, because the dock depends on the tray, but the temporary diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 69e99e7..1bcba64 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -142,6 +142,7 @@ sources = [ "QtEmojisScroll.cpp", "QtEmojisSelector.cpp", "QtRecentEmojisGrid.cpp", + "QtEmoticonsGrid.cpp", "QtContactEditWindow.cpp", "QtContactEditWidget.cpp", "QtSingleWindow.cpp", -- cgit v0.10.2-6-g49f6