[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [ktp-common-internals/mklapetek/SpaceBar] /: A special TextArea backend to handle emoji stuff
From:       Martin Klapetek <mklapetek () kde ! org>
Date:       2016-06-11 14:26:17
Message-ID: E1bBjrd-00026R-TW () scm ! kde ! org
[Download RAW message or body]

Git commit 7a6b82e6e639e246bacbcdd7f8f50f4a5321f04d by Martin Klapetek.
Committed on 11/06/2016 at 14:24.
Pushed by mklapetek into branch 'mklapetek/SpaceBar'.

A special TextArea backend to handle emoji stuff

M  +1    -0    CMakeLists.txt
M  +2    -0    KTp/Declarative/CMakeLists.txt
M  +2    -0    KTp/Declarative/qml-plugins.cpp
A  +131  -0    KTp/Declarative/text-area-emojis-handler.cpp     [License: LGPL \
(v2.1+)] A  +60   -0    KTp/Declarative/text-area-emojis-handler.h     [License: LGPL \
(v2.1+)]

http://commits.kde.org/telepathy-common-internals/7a6b82e6e639e246bacbcdd7f8f50f4a5321f04d


diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2567d1a..91a83af 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,7 @@ set (KTP_MESSAGE_FILTER_FRAMEWORK_VERSION "5")
 
 find_package (Qt5 REQUIRED CONFIG COMPONENTS
               Qml
+              Quick
               Sql
               Test)
 
diff --git a/KTp/Declarative/CMakeLists.txt b/KTp/Declarative/CMakeLists.txt
index f667565..e6a6de8 100644
--- a/KTp/Declarative/CMakeLists.txt
+++ b/KTp/Declarative/CMakeLists.txt
@@ -9,6 +9,7 @@ set (ktp_qml_plugin_SRCS
     messages-model.cpp
     pinned-contacts-model.cpp
     filtered-pinned-contacts-proxy-model.cpp
+    text-area-emojis-handler.cpp
     contact-pin.cpp
     telepathy-manager.cpp
     qml-plugins.cpp
@@ -22,6 +23,7 @@ add_library (ktpqmlplugin SHARED ${ktp_qml_plugin_SRCS})
 target_link_libraries (ktpqmlplugin
     Qt5::Qml
     Qt5::Sql
+    Qt5::Quick
 
     KF5::WindowSystem
     KF5::I18n
diff --git a/KTp/Declarative/qml-plugins.cpp b/KTp/Declarative/qml-plugins.cpp
index 994c6f5..0ac505e 100644
--- a/KTp/Declarative/qml-plugins.cpp
+++ b/KTp/Declarative/qml-plugins.cpp
@@ -32,6 +32,7 @@
 #include "telepathy-manager.h"
 #include "mainlogmodel.h"
 #include "emojis-model.h"
+#include "text-area-emojis-handler.h"
 
 #include <TelepathyQt/PendingChannelRequest>
 #include "KTp/types.h"
@@ -63,6 +64,7 @@ void QmlPlugins::registerTypes(const char *uri)
     qmlRegisterType<KTp::PresenceModel> (uri, 0, 1, "PresenceModel");
     qmlRegisterType<MainLogModel> (uri, 0, 1, "MainLogModel");
     qmlRegisterType<EmojisModel> (uri, 0, 1, "EmojisModel");
+    qmlRegisterType<TextAreaEmojisHandler> (uri, 0, 1, "TextAreaEmojisHandler");
 
     qmlRegisterUncreatableType<MessagesModel> (uri, 0, 1, "MessagesModel",
         QLatin1String("It will be created once the conversation is created"));
diff --git a/KTp/Declarative/text-area-emojis-handler.cpp \
b/KTp/Declarative/text-area-emojis-handler.cpp new file mode 100644
index 0000000..456d9d3
--- /dev/null
+++ b/KTp/Declarative/text-area-emojis-handler.cpp
@@ -0,0 +1,131 @@
+/*
+    Copyright (C) 2016  Martin Klapetek <mklapetek@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "text-area-emojis-handler.h"
+
+#include <QQuickTextDocument>
+#include <QQuickItem>
+#include <QVariant>
+#include <QRegularExpressionMatchIterator>
+#include <QTextDocumentFragment>
+#include <QTextCursor>
+#include <QDebug>
+
+#include <KEmoticons>
+
+TextAreaEmojisHandler::TextAreaEmojisHandler(QObject *parent)
+    : QObject(parent),
+      m_emojiMatcher(QStringLiteral("(^|\\s)(:[^\\s]+:)")),
+      m_emojiImgMatcher(QStringLiteral("<img.+src=\"([^\\s]+)\".+/>"))
+{
+    KEmoticons *kemoticons = new KEmoticons();
+    kemoticons->setPreferredEmoticonSize(QSize(32, 32));
+    m_theme = kemoticons->theme(QStringLiteral("EmojiOne"));
+}
+
+TextAreaEmojisHandler::~TextAreaEmojisHandler()
+{
+
+}
+
+void TextAreaEmojisHandler::setTextArea(QQuickItem *textArea)
+{
+    m_document = 0;
+    m_textArea = textArea;
+
+    if (!m_textArea) {
+        return;
+    }
+
+    QVariant doc = m_textArea->property("textDocument");
+    if (doc.canConvert<QQuickTextDocument*>()) {
+        QQuickTextDocument *qqdoc = doc.value<QQuickTextDocument*>();
+        if (qqdoc) {
+            m_document = qqdoc->textDocument();
+        }
+    }
+
+    Q_EMIT textAreaChanged();
+
+    connect(m_document, &QTextDocument::contentsChanged, this, \
&TextAreaEmojisHandler::onTextChanged); +}
+
+QQuickItem* TextAreaEmojisHandler::textArea() const
+{
+    return m_textArea;
+}
+
+void TextAreaEmojisHandler::onTextChanged()
+{
+    QRegularExpressionMatchIterator matches = \
m_emojiMatcher.globalMatch(m_document->toPlainText()); +    if (!matches.hasNext()) {
+        return;
+    }
+
+    QString text = m_document->toPlainText();
+    QTextCursor cursor = QTextCursor(m_document);
+
+    while (matches.hasNext()) {
+        QRegularExpressionMatch match = matches.next();
+
+        QString emojiHtml;
+        if (match.capturedStart() != 0) {
+            emojiHtml = QStringLiteral(" ");
+        }
+
+        emojiHtml.append(m_theme.parseEmoticons(match.captured(2)))
+                 .append(QStringLiteral(" "));
+
+        cursor.setPosition(match.capturedStart(2));
+        cursor.setPosition(match.capturedEnd(2), QTextCursor::KeepAnchor);
+        cursor.removeSelectedText();
+        cursor.insertHtml(emojiHtml);
+    }
+}
+
+QString TextAreaEmojisHandler::getText() const
+{
+    auto documentHtml = m_document->toHtml();
+    auto emojiImgs = m_emojiImgMatcher.globalMatch(documentHtml);
+
+    while (emojiImgs.hasNext()) {
+        auto emoji = emojiImgs.next();
+        documentHtml.replace(emoji.capturedStart(0), emoji.capturedLength(0), \
asciiEmojiForPath(emoji.captured(1))); +    }
+
+    QTextDocument *tempDocument = new QTextDocument();
+    tempDocument->setHtml(documentHtml);
+
+    int start = qBound(0, 0, tempDocument->characterCount() - 1);
+    int end = qBound(0, 100, tempDocument->characterCount() - 1);
+    QTextCursor cursor(tempDocument);
+    cursor.setPosition(start, QTextCursor::MoveAnchor);
+    cursor.setPosition(end, QTextCursor::KeepAnchor);
+    return cursor.selection().toPlainText().trimmed();
+}
+
+QString TextAreaEmojisHandler::asciiEmojiForPath(const QString &filePath) const
+{
+    const auto emojiValues = m_theme.emoticonsMap().value(filePath);
+    Q_FOREACH (const QString &emoji, emojiValues) {
+        if (emoji.startsWith(QLatin1Char(':'))) {
+            return emoji;
+        }
+    }
+    return emojiValues.at(0);
+}
diff --git a/KTp/Declarative/text-area-emojis-handler.h \
b/KTp/Declarative/text-area-emojis-handler.h new file mode 100644
index 0000000..33b66cb
--- /dev/null
+++ b/KTp/Declarative/text-area-emojis-handler.h
@@ -0,0 +1,60 @@
+/*
+    Copyright (C) 2016  Martin Klapetek <mklapetek@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef TEXTAREAEMOJISHANDLER_H
+#define TEXTAREAEMOJISHANDLER_H
+
+#include <QObject>
+#include <QRegularExpression>
+#include <KEmoticonsTheme>
+
+class QTextDocument;
+class QQuickItem;
+
+class TextAreaEmojisHandler : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QQuickItem *textArea READ textArea WRITE setTextArea NOTIFY \
textAreaChanged) +
+public:
+    TextAreaEmojisHandler(QObject *parent = 0);
+    ~TextAreaEmojisHandler();
+
+    void setTextArea(QQuickItem *textArea);
+    QQuickItem *textArea() const;
+
+    Q_INVOKABLE QString getText() const;
+
+Q_SIGNALS:
+    void textAreaChanged();
+    void shouldShowAutocompletion(const QString &text);
+
+private Q_SLOTS:
+    void onTextChanged();
+
+private:
+    QString asciiEmojiForPath(const QString &filePath) const;
+
+    QTextDocument *m_document;
+    QQuickItem *m_textArea;
+    QRegularExpression m_emojiMatcher;
+    QRegularExpression m_emojiImgMatcher;
+    KEmoticonsTheme m_theme;
+};
+
+#endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic