[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