diff options
-rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 25 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindow.h | 11 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindowFactory.cpp | 4 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindowFactory.h | 9 | ||||
-rw-r--r-- | Swift/QtUI/QtEmoticonCell.cpp | 30 | ||||
-rw-r--r-- | Swift/QtUI/QtEmoticonCell.h | 34 | ||||
-rw-r--r-- | Swift/QtUI/QtEmoticonsGrid.cpp | 59 | ||||
-rw-r--r-- | Swift/QtUI/QtEmoticonsGrid.h | 40 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.cpp | 2 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 2 |
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", |