summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baczynski <danielbaczynski8@gmail.com>2015-03-25 00:16:20 (GMT)
committerKevin Smith <git@kismith.co.uk>2015-03-26 07:39:31 (GMT)
commit85e53159321ab3e013dd2fc0a16748ed6755b119 (patch)
tree6ed333198bb756c8e1946505663ae0c95e72223b
parentb23f4fb9bee49f93bbba6a9039f0f764664125cd (diff)
downloadswift-85e53159321ab3e013dd2fc0a16748ed6755b119.zip
swift-85e53159321ab3e013dd2fc0a16748ed6755b119.tar.bz2
Add emoticons input popup
This is simple popup menu added to chat window where it is possible to choose an emoticon. To activate click on the smiling face next to input field. When emoticon is selected its text equivalent is appended to input. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: Tested on Ubuntu 14.10 with KDE and Qt 4.8.6 Change-Id: I6c5907959970398c9c38591f64ceec20efcbf409
-rw-r--r--Swift/QtUI/QtChatWindow.cpp25
-rw-r--r--Swift/QtUI/QtChatWindow.h11
-rw-r--r--Swift/QtUI/QtChatWindowFactory.cpp4
-rw-r--r--Swift/QtUI/QtChatWindowFactory.h9
-rw-r--r--Swift/QtUI/QtEmoticonCell.cpp30
-rw-r--r--Swift/QtUI/QtEmoticonCell.h34
-rw-r--r--Swift/QtUI/QtEmoticonsGrid.cpp59
-rw-r--r--Swift/QtUI/QtEmoticonsGrid.h40
-rw-r--r--Swift/QtUI/QtSwift.cpp2
-rw-r--r--Swift/QtUI/SConscript2
10 files changed, 207 insertions, 9 deletions
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 33bec75..f25c033 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -15,6 +15,7 @@
#include <QBoxLayout>
#include <QCloseEvent>
#include <QComboBox>
+#include <QCursor>
#include <QFileDialog>
#include <QFileInfo>
#include <QInputDialog>
@@ -23,7 +24,9 @@
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
+#include <QPoint>
#include <QPushButton>
+#include <QSize>
#include <QSplitter>
#include <QString>
#include <QTextDocument>
@@ -57,7 +60,7 @@
namespace Swift {
-QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings) : QtTabbable(), id_(Q2PSTRING(contact)), contact_(contact), nextAlertId_(0), eventStream_(eventStream), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false) {
+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) {
settings_ = settings;
unreadCount_ = 0;
isOnline_ = true;
@@ -140,8 +143,17 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt
inputBarLayout->addWidget(correctingLabel_);
correctingLabel_->hide();
+ 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)));
+
// using an extra layout to work around Qt margin glitches on OS X
QHBoxLayout* actionLayout = new QHBoxLayout();
+ actionLayout->addWidget(emoticonsButton_);
actionLayout->addWidget(actionButton_);
inputBarLayout->addLayout(actionLayout);
@@ -514,6 +526,7 @@ void QtChatWindow::updateTitleWithUnreadCount() {
+
void QtChatWindow::flash() {
emit requestFlash();
}
@@ -637,6 +650,16 @@ void QtChatWindow::setSubject(const std::string& 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::handleEmoticonClicked(QString emoticonAsText) {
+ input_->textCursor().insertText(emoticonAsText);
+}
+
void QtChatWindow::handleActionButtonClicked() {
QMenu contextMenu;
QAction* changeSubject = NULL;
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index da3a3b9..5c6fa2a 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -8,9 +8,11 @@
#include <map>
+#include <QMap>
+#include <QMenu>
#include <QPointer>
+#include <QString>
#include <QTextCursor>
-#include <QMap>
#include <SwifTools/LastLineTracker.h>
@@ -18,12 +20,12 @@
#include <Swift/QtUI/ChatSnippet.h>
#include <Swift/QtUI/QtAffiliationEditor.h>
+#include <Swift/QtUI/QtEmoticonsGrid.h>
#include <Swift/QtUI/QtMUCConfigurationWindow.h>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtTabbable.h>
-
class QTextEdit;
class QLineEdit;
class QComboBox;
@@ -77,7 +79,7 @@ namespace Swift {
Q_OBJECT
public:
- QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings);
+ QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, const std::map<std::string, std::string>& emoticons);
virtual ~QtChatWindow();
std::string addMessage(const ChatMessage& message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
std::string addAction(const ChatMessage& message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
@@ -169,6 +171,8 @@ namespace Swift {
void handleActionButtonClicked();
void handleAffiliationEditorAccepted();
void handleCurrentLabelChanged(int);
+ void handleEmoticonsButtonClicked();
+ void handleEmoticonClicked(QString emoticonAsText);
private:
void updateTitleWithUnreadCount();
@@ -221,5 +225,6 @@ namespace Swift {
bool impromptu_;
bool isMUC_;
bool supportsImpromptuChat_;
+ QMenu* emoticonsMenu_;
};
}
diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp
index 3793392..1774653 100644
--- a/Swift/QtUI/QtChatWindowFactory.cpp
+++ b/Swift/QtUI/QtChatWindowFactory.cpp
@@ -21,7 +21,7 @@ namespace Swift {
static const QString SPLITTER_STATE = "mucSplitterState";
static const QString CHAT_TABS_GEOMETRY = "chatTabsGeometry";
-QtChatWindowFactory::QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath) : themePath_(themePath) {
+QtChatWindowFactory::QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath, const std::map<std::string, std::string>& emoticons) : themePath_(themePath), emoticons_(emoticons) {
qtOnlySettings_ = qtSettings;
settings_ = settings;
tabs_ = tabs;
@@ -50,7 +50,7 @@ ChatWindow* QtChatWindowFactory::createChatWindow(const JID &contact,UIEventStre
}
}
- QtChatWindow *chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), theme_, eventStream, settings_);
+ QtChatWindow* chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), theme_, eventStream, settings_, emoticons_);
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 aa91d0b..c38202f 100644
--- a/Swift/QtUI/QtChatWindowFactory.h
+++ b/Swift/QtUI/QtChatWindowFactory.h
@@ -6,12 +6,16 @@
#pragma once
-#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
+#include <map>
+#include <string>
#include <QObject>
#include <QSplitter>
#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
+
#include <Swift/QtUI/QtSettingsProvider.h>
namespace Swift {
@@ -23,7 +27,7 @@ namespace Swift {
class QtChatWindowFactory : public QObject, public ChatWindowFactory {
Q_OBJECT
public:
- QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath);
+ QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath, const std::map<std::string, std::string>& emoticons);
~QtChatWindowFactory();
ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
signals:
@@ -37,6 +41,7 @@ namespace Swift {
QtSettingsProvider* qtOnlySettings_;
QtChatTabs* tabs_;
QtChatTheme* theme_;
+ std::map<std::string, std::string> emoticons_;
};
}
diff --git a/Swift/QtUI/QtEmoticonCell.cpp b/Swift/QtUI/QtEmoticonCell.cpp
new file mode 100644
index 0000000..1c1f6ed
--- /dev/null
+++ b/Swift/QtUI/QtEmoticonCell.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 Daniel Baczynski
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtEmoticonCell.h"
+
+namespace Swift {
+
+QtEmoticonCell::QtEmoticonCell(const QString emoticonAsText, QString filePath, QWidget* parent) : QLabel(parent), emoticonAsText_(emoticonAsText) {
+ if (filePath.startsWith("qrc:/")) {
+ filePath.remove(0, 3);
+ }
+ setPixmap(QPixmap(filePath));
+ setToolTip(emoticonAsText_);
+}
+
+QtEmoticonCell::~QtEmoticonCell() {
+
+}
+
+void QtEmoticonCell::mousePressEvent (QMouseEvent* event) {
+ emit emoticonClicked(emoticonAsText_);
+ QLabel::mousePressEvent(event);
+}
+
+}
+
+
diff --git a/Swift/QtUI/QtEmoticonCell.h b/Swift/QtUI/QtEmoticonCell.h
new file mode 100644
index 0000000..379f5d6
--- /dev/null
+++ b/Swift/QtUI/QtEmoticonCell.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015 Daniel Baczynski
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <map>
+#include <string>
+
+#include <QLabel>
+#include <QPixmap>
+#include <QString>
+
+class QWidget;
+class QMouseEvent;
+
+namespace Swift {
+
+ class QtEmoticonCell : public QLabel {
+ Q_OBJECT
+ public:
+ QtEmoticonCell(const QString emoticonAsText, QString filePath, QWidget* parent = 0);
+ ~QtEmoticonCell();
+ virtual void mousePressEvent(QMouseEvent* event);
+
+ signals:
+ void emoticonClicked(QString emoticonAsText);
+
+ private:
+ QString emoticonAsText_;
+ };
+}
diff --git a/Swift/QtUI/QtEmoticonsGrid.cpp b/Swift/QtUI/QtEmoticonsGrid.cpp
new file mode 100644
index 0000000..4a599ea
--- /dev/null
+++ b/Swift/QtUI/QtEmoticonsGrid.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015 Daniel Baczynski
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtEmoticonsGrid.h"
+
+#include <set>
+
+#include <QPushButton>
+
+#include <Swiften/Base/foreach.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+typedef std::map<std::string, std::string> EmoticonsMap; // Without this typedef compiler complains when using foreach
+
+QtEmoticonsGrid::QtEmoticonsGrid(const std::map<std::string, std::string>& emoticons, QWidget* parent) : QGridLayout(parent) {
+ makeUniqueEmoticonsMap(emoticons);
+
+ // Create grid: 3 columns, [uniqueEmoticons_.size()/3] rows
+ int row = 0;
+ int column = 0;
+
+ foreach(EmoticonsMap::value_type emoticon, uniqueEmoticons_) {
+ QtEmoticonCell* newCell = new QtEmoticonCell(P2QSTRING(emoticon.first), P2QSTRING(emoticon.second));
+ addWidget(newCell, row, column);
+ connect(newCell, SIGNAL(emoticonClicked(QString)), this, SLOT(emoticonClickedSlot(QString)));
+
+ column++;
+ if (column >= 3) {
+ column = 0;
+ row++;
+ }
+ }
+}
+
+QtEmoticonsGrid::~QtEmoticonsGrid() {
+
+}
+
+void QtEmoticonsGrid::makeUniqueEmoticonsMap(const std::map<std::string, std::string>& emoticons) {
+ std::set<std::string> paths;
+ reverse_foreach(EmoticonsMap::value_type emoticon, emoticons) {
+ if (paths.find(emoticon.second) == paths.end()) {
+ uniqueEmoticons_.insert(emoticon);
+ paths.insert(emoticon.second);
+ }
+ }
+}
+
+void QtEmoticonsGrid::emoticonClickedSlot(QString emoticonAsText) {
+ emit emoticonClicked(emoticonAsText);
+}
+
+}
diff --git a/Swift/QtUI/QtEmoticonsGrid.h b/Swift/QtUI/QtEmoticonsGrid.h
new file mode 100644
index 0000000..b045b26
--- /dev/null
+++ b/Swift/QtUI/QtEmoticonsGrid.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 Daniel Baczynski
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <map>
+#include <string>
+
+#include <QGridLayout>
+#include <QLabel>
+#include <QSize>
+#include <QString>
+
+#include <Swift/QtUI/QtEmoticonCell.h>
+
+class QWidget;
+
+namespace Swift {
+
+ class QtEmoticonsGrid : public QGridLayout {
+ Q_OBJECT
+ public:
+ explicit QtEmoticonsGrid(const std::map<std::string, std::string>& emoticons, QWidget* parent = 0);
+ virtual ~QtEmoticonsGrid();
+
+ signals:
+ void emoticonClicked(QString emoticonAsText);
+
+ public slots:
+ void emoticonClickedSlot(QString emoticonAsText);
+
+ private:
+ void makeUniqueEmoticonsMap(const std::map<std::string, std::string>& emoticons);
+
+ std::map<std::string, std::string> uniqueEmoticons_;
+ };
+}
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index 1d945da..bce3ca4 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -170,7 +170,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_, "");
+ chatWindowFactory_ = new QtChatWindowFactory(splitter_, settingsHierachy_, qtSettings_, tabs_, "", 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 858df19..36f7cc9 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -124,6 +124,8 @@ sources = [
"QtBookmarkDetailWindow.cpp",
"QtAddBookmarkWindow.cpp",
"QtEditBookmarkWindow.cpp",
+ "QtEmoticonsGrid.cpp",
+ "QtEmoticonCell.cpp",
"QtContactEditWindow.cpp",
"QtContactEditWidget.cpp",
"QtSingleWindow.cpp",