From 5a1bdf2f6a4842176be5938f8db5cb9d151aceb5 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 14 Jun 2012 22:28:58 +0100 Subject: Preliminary emoticon work. Parsing and toggling support for emoticons. No emoticons are included so this won't do anything yet. diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp index 54bce09..a55161f 100644 --- a/Swift/QtUI/QtChatView.cpp +++ b/Swift/QtUI/QtChatView.cpp @@ -183,6 +183,21 @@ void QtChatView::replaceMessage(const QString& newMessage, const QString& id, co } } +void QtChatView::showEmoticons(bool show) { + { + const QWebElementCollection spans = document_.findAll("span.swift_emoticon_image"); + foreach (QWebElement span, spans) { + span.setStyleProperty("display", show ? "inline" : "none"); + } + } + { + const QWebElementCollection spans = document_.findAll("span.swift_emoticon_text"); + foreach (QWebElement span, spans) { + span.setStyleProperty("display", show ? "none" : "inline"); + } + } +} + void QtChatView::copySelectionToClipboard() { if (!webPage_->selectedText().isEmpty()) { webPage_->triggerAction(QWebPage::Copy); diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h index 2e64593..fdbdd5a 100644 --- a/Swift/QtUI/QtChatView.h +++ b/Swift/QtUI/QtChatView.h @@ -43,7 +43,7 @@ namespace Swift { void setFileTransferProgress(QString id, const int percentageDone); void setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& msg); void setMUCInvitationJoined(QString id); - + void showEmoticons(bool show); signals: void gotFocus(); void fontResized(int); diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 137c044..d3abaa6 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -18,6 +18,7 @@ #include "QtSettingsProvider.h" #include "QtScaledAvatarCache.h" #include "QtInviteToChatWindow.h" +#include #include #include "SwifTools/TabComplete.h" @@ -59,7 +60,7 @@ const QString QtChatWindow::ButtonFileTransferSendRequest = QString("filetransfe const QString QtChatWindow::ButtonFileTransferAcceptRequest = QString("filetransfer-acceptrequest"); const QString QtChatWindow::ButtonMUCInvite = QString("mucinvite"); -QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings) : QtTabbable(), contact_(contact), previousMessageWasSelf_(false), previousMessageKind_(PreviosuMessageWasNone), eventStream_(eventStream) { +QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, QMap emoticons) : QtTabbable(), contact_(contact), previousMessageWasSelf_(false), previousMessageKind_(PreviosuMessageWasNone), eventStream_(eventStream), emoticons_(emoticons) { settings_ = settings; unreadCount_ = 0; idCounter_ = 0; @@ -69,6 +70,7 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt theme_ = theme; isCorrection_ = false; correctionEnabled_ = Maybe; + showEmoticons_ = true; updateTitleWithUnreadCount(); #ifdef SWIFT_EXPERIMENTAL_FT @@ -173,6 +175,10 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt jsBridge = new QtChatWindowJSBridge(); messageLog_->addToJSEnvironment("chatwindow", jsBridge); connect(jsBridge, SIGNAL(buttonClicked(QString,QString,QString,QString)), this, SLOT(handleHTMLButtonClicked(QString,QString,QString,QString))); + + settings_->onSettingChanged.connect(boost::bind(&QtChatWindow::handleSettingChanged, this, _1)); + showEmoticons_ = settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS); + } QtChatWindow::~QtChatWindow() { @@ -182,6 +188,13 @@ QtChatWindow::~QtChatWindow() { } } +void QtChatWindow::handleSettingChanged(const std::string& setting) { + if (setting == QtUISettingConstants::SHOW_EMOTICONS.getKey()) { + showEmoticons_ = settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS); + messageLog_->showEmoticons(showEmoticons_); + } +} + void QtChatWindow::handleLogCleared() { onLogCleared(); } @@ -453,8 +466,18 @@ std::string QtChatWindow::addMessage(const std::string &message, const std::stri htmlString = QString("").arg(Qt::escape(P2QSTRING(label->getForegroundColor()))).arg(Qt::escape(P2QSTRING(label->getBackgroundColor()))); htmlString += QString("%3 ").arg(Qt::escape(P2QSTRING(label->getDisplayMarking()))); } - QString messageHTML(Qt::escape(P2QSTRING(message))); - messageHTML = P2QSTRING(Linkify::linkify(Q2PSTRING(messageHTML))); + QString messageHTML(P2QSTRING(message)); + messageHTML = Qt::escape(messageHTML); + QMapIterator it(emoticons_); + QString textStyle = showEmoticons_ ? "style='display:none'" : ""; + QString imageStyle = showEmoticons_ ? "" : "style='display:none'"; + if (messageHTML.length() < 500) { + while (it.hasNext()) { + it.next(); + messageHTML.replace(it.key(), ""+it.key() + ""); + } + messageHTML = P2QSTRING(Linkify::linkify(Q2PSTRING(messageHTML))); + } messageHTML.replace("\n","
"); QString styleSpanStart = style == "" ? "" : ""; QString styleSpanEnd = style == "" ? "" : ""; diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index ff26c9c..5081681 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -17,6 +17,7 @@ #include #include #include +#include class QTextEdit; class QLineEdit; @@ -46,7 +47,7 @@ namespace Swift { static const QString ButtonMUCInvite; public: - QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings); + QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, QMap emoticons); ~QtChatWindow(); std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr label, const std::string& avatarPath, const boost::posix_time::ptime& time); std::string addAction(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr label, const std::string& avatarPath, const boost::posix_time::ptime& time); @@ -147,6 +148,7 @@ namespace Swift { void tabComplete(); void beginCorrection(); void cancelCorrection(); + void handleSettingChanged(const std::string& setting); std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time); void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const QString& style); void handleOccupantSelectionChanged(RosterItem* item); @@ -189,5 +191,7 @@ namespace Swift { int idCounter_; SettingsProvider* settings_; std::vector availableRoomActions_; + QMap emoticons_; + bool showEmoticons_; }; } diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp index 7610082..5f91ff8 100644 --- a/Swift/QtUI/QtChatWindowFactory.cpp +++ b/Swift/QtUI/QtChatWindowFactory.cpp @@ -20,7 +20,7 @@ namespace Swift { static const QString SPLITTER_STATE = "mucSplitterState"; static const QString CHAT_TABS_GEOMETRY = "chatTabsGeometry"; -QtChatWindowFactory::QtChatWindowFactory(QSplitter* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath) : themePath_(themePath) { +QtChatWindowFactory::QtChatWindowFactory(QSplitter* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath, QMap emoticons) : themePath_(themePath), emoticons_(emoticons) { qtOnlySettings_ = qtSettings; settings_ = settings; tabs_ = tabs; @@ -49,7 +49,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 2a16c3b..4f59961 100644 --- a/Swift/QtUI/QtChatWindowFactory.h +++ b/Swift/QtUI/QtChatWindowFactory.h @@ -20,7 +20,7 @@ namespace Swift { class QtChatWindowFactory : public QObject, public ChatWindowFactory { Q_OBJECT public: - QtChatWindowFactory(QSplitter* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath); + QtChatWindowFactory(QSplitter* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath, QMap emoticons); ~QtChatWindowFactory(); ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream); signals: @@ -34,6 +34,7 @@ namespace Swift { QtSettingsProvider* qtOnlySettings_; QtChatTabs* tabs_; QtChatTheme* theme_; + QMap emoticons_; }; } diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp index ec05684..d312546 100644 --- a/Swift/QtUI/QtMainWindow.cpp +++ b/Swift/QtUI/QtMainWindow.cpp @@ -44,7 +44,7 @@ namespace Swift { -QtMainWindow::QtMainWindow(SettingsProvider* settings, UIEventStream* uiEventStream, QtLoginWindow::QtMenus loginMenus) : QWidget(), MainWindow(false), loginMenus_(loginMenus) { +QtMainWindow::QtMainWindow(SettingsProvider* settings, UIEventStream* uiEventStream, QtLoginWindow::QtMenus loginMenus, bool emoticonsExist) : QWidget(), MainWindow(false), loginMenus_(loginMenus) { uiEventStream_ = uiEventStream; settings_ = settings; setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); @@ -99,6 +99,15 @@ QtMainWindow::QtMainWindow(SettingsProvider* settings, UIEventStream* uiEventStr viewMenu->addAction(showOfflineAction_); handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); + if (emoticonsExist) { + showEmoticonsAction_ = new QAction(tr("&Show Emoticons"), this); + showEmoticonsAction_->setCheckable(true); + showEmoticonsAction_->setChecked(false); + connect(showEmoticonsAction_, SIGNAL(toggled(bool)), SLOT(handleShowEmoticonsToggled(bool))); + viewMenu->addAction(showEmoticonsAction_); + handleShowEmoticonsToggled(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS)); + } + //QAction* compactRosterAction_ = new QAction(tr("&Compact Roster"), this); //compactRosterAction_->setCheckable(true); //compactRosterAction_->setChecked(false); @@ -234,6 +243,9 @@ void QtMainWindow::handleSettingChanged(const std::string& settingPath) { if (settingPath == SettingConstants::SHOW_OFFLINE.getKey()) { handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); } + if (settingPath == QtUISettingConstants::SHOW_EMOTICONS.getKey()) { + handleShowEmoticonsToggled(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS)); + } if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { toggleRequestDeliveryReceipts_->setChecked(settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS)); } @@ -244,6 +256,11 @@ void QtMainWindow::handleShowOfflineToggled(bool state) { showOfflineAction_->setChecked(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); } +void QtMainWindow::handleShowEmoticonsToggled(bool state) { + settings_->storeSetting(QtUISettingConstants::SHOW_EMOTICONS, state); + showEmoticonsAction_->setChecked(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS)); +} + void QtMainWindow::setMyNick(const std::string& nick) { meView_->setNick(P2QSTRING(nick)); } diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h index 25d9ace..251c346 100644 --- a/Swift/QtUI/QtMainWindow.h +++ b/Swift/QtUI/QtMainWindow.h @@ -36,7 +36,7 @@ namespace Swift { class QtMainWindow : public QWidget, public MainWindow { Q_OBJECT public: - QtMainWindow(SettingsProvider*, UIEventStream* eventStream, QtLoginWindow::QtMenus loginMenus); + QtMainWindow(SettingsProvider*, UIEventStream* eventStream, QtLoginWindow::QtMenus loginMenus, bool emoticonsExist); virtual ~QtMainWindow(); std::vector getMenus() {return menus_;} void setMyNick(const std::string& name); @@ -56,6 +56,7 @@ namespace Swift { void handleStatusChanged(StatusShow::Type showType, const QString &statusMessage); void handleSettingChanged(const std::string& settingPath); void handleShowOfflineToggled(bool); + void handleShowEmoticonsToggled(bool); void handleJoinMUCAction(); void handleSignOutAction(); void handleEditProfileAction(); @@ -79,6 +80,7 @@ namespace Swift { QAction* editUserAction_; QAction* chatUserAction_; QAction* showOfflineAction_; + QAction* showEmoticonsAction_; QAction* toggleRequestDeliveryReceipts_; QMenu* serverAdHocMenu_; QtTabWidget* tabs_; diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index 9602336..ca609de 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include @@ -97,6 +99,26 @@ XMLSettingsProvider* QtSwift::loadSettingsFile(const QString& fileName) { return new XMLSettingsProvider(""); } +QMap QtSwift::loadEmoticonsFile(const QString& fileName) { + QMap emoticons; + QFile file(fileName); + if (file.exists() && file.open(QIODevice::ReadOnly)) { + while (!file.atEnd()) { + QString line = file.readLine(); + line.replace("\n", ""); + line.replace("\r", ""); + qDebug() << "Parsing line : " << line; + QStringList tokens = line.split(" "); + if (tokens.size() == 2) { + emoticons[tokens[0]] = "file://" + tokens[1]; + qDebug() << "Adding mapping from " << tokens[0] << " to " << tokens[1]; + } + } + } + + return emoticons; +} + QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMainThreadCaller_), autoUpdater_(NULL), idleDetector_(&idleQuerier_, networkFactories_.getTimerFactory(), 1000) { if (options.count("netbook-mode")) { splitter_ = new QSplitter(); @@ -114,6 +136,8 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa settingsHierachy_->addProviderToTopOfStack(xmlSettings_); settingsHierachy_->addProviderToTopOfStack(qtSettings_); + QMap emoticons = loadEmoticonsFile(P2QSTRING((Paths::getExecutablePath() / "emoticons.txt").string())); + int numberOfAccounts = 1; try { numberOfAccounts = options["multi-account"].as(); @@ -131,7 +155,7 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME); storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir()); certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory()); - 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 @@ -172,7 +196,7 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa // Don't add the first tray (see note above) systemTrays_.push_back(new QtSystemTray()); } - QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), startMinimized); + QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), startMinimized, !emoticons.empty()); uiFactories_.push_back(uiFactory); MainController* mainController = new MainController( &clientMainThreadCaller_, diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h index d30ed7c..42fb50f 100644 --- a/Swift/QtUI/QtSwift.h +++ b/Swift/QtUI/QtSwift.h @@ -59,6 +59,7 @@ namespace Swift { ~QtSwift(); private: XMLSettingsProvider* loadSettingsFile(const QString& fileName); + QMap loadEmoticonsFile(const QString& fileName); private: QtEventLoop clientMainThreadCaller_; PlatformTLSFactories tlsFactories_; diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp index 2a50592..78de7aa 100644 --- a/Swift/QtUI/QtUIFactory.cpp +++ b/Swift/QtUI/QtUIFactory.cpp @@ -30,7 +30,7 @@ namespace Swift { -QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, bool startMinimized) : settings(settings), qtOnlySettings(qtOnlySettings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(NULL), loginWindow(NULL), startMinimized(startMinimized) { +QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, bool startMinimized, bool emoticonsExist) : settings(settings), qtOnlySettings(qtOnlySettings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(NULL), loginWindow(NULL), startMinimized(startMinimized), emoticonsExist_(emoticonsExist) { chatFontSize = settings->getSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE); } @@ -55,7 +55,7 @@ FileTransferListWidget* QtUIFactory::createFileTransferListWidget() { } MainWindow* QtUIFactory::createMainWindow(UIEventStream* eventStream) { - lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus()); + lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus(), emoticonsExist_); return lastMainWindow; } diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h index 29d9d1c..edb89ad 100644 --- a/Swift/QtUI/QtUIFactory.h +++ b/Swift/QtUI/QtUIFactory.h @@ -28,7 +28,7 @@ namespace Swift { class QtUIFactory : public QObject, public UIFactory { Q_OBJECT public: - QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, bool startMinimized); + QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, bool startMinimized, bool emoticonsExist); virtual XMLConsoleWidget* createXMLConsoleWidget(); virtual MainWindow* createMainWindow(UIEventStream* eventStream); @@ -61,5 +61,6 @@ namespace Swift { std::vector > chatWindows; bool startMinimized; int chatFontSize; + bool emoticonsExist_; }; } diff --git a/Swift/QtUI/QtUISettingConstants.cpp b/Swift/QtUI/QtUISettingConstants.cpp index 046ccc1..81022ec 100644 --- a/Swift/QtUI/QtUISettingConstants.cpp +++ b/Swift/QtUI/QtUISettingConstants.cpp @@ -13,4 +13,5 @@ const SettingsProvider::Setting QtUISettingConstants::CLICKTHROUGH_ const SettingsProvider::Setting QtUISettingConstants::CURRENT_ROSTER_TAB("currentRosterTab", 0); const SettingsProvider::Setting QtUISettingConstants::SHOW_NICK_IN_ROSTER_HEADER("showNickInRosterHeader", true); const SettingsProvider::Setting QtUISettingConstants::CHATWINDOW_FONT_SIZE("chatWindowFontSize", 0); +const SettingsProvider::Setting QtUISettingConstants::SHOW_EMOTICONS("showEmoticons", true); } diff --git a/Swift/QtUI/QtUISettingConstants.h b/Swift/QtUI/QtUISettingConstants.h index 82f98bb..2740abb 100644 --- a/Swift/QtUI/QtUISettingConstants.h +++ b/Swift/QtUI/QtUISettingConstants.h @@ -16,5 +16,6 @@ namespace Swift { static const SettingsProvider::Setting CURRENT_ROSTER_TAB; static const SettingsProvider::Setting SHOW_NICK_IN_ROSTER_HEADER; static const SettingsProvider::Setting CHATWINDOW_FONT_SIZE; + static const SettingsProvider::Setting SHOW_EMOTICONS; }; } -- cgit v0.10.2-6-g49f6