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: L= GPL (v2.1+)] A +60 -0 KTp/Declarative/text-area-emojis-handler.h [License: LGP= L (v2.1+)] http://commits.kde.org/telepathy-common-internals/7a6b82e6e639e246bacbcdd7f= 8f50f4a5321f04d 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 #include "KTp/types.h" @@ -63,6 +64,7 @@ void QmlPlugins::registerTypes(const char *uri) qmlRegisterType (uri, 0, 1, "PresenceModel"); qmlRegisterType (uri, 0, 1, "MainLogModel"); qmlRegisterType (uri, 0, 1, "EmojisModel"); + qmlRegisterType (uri, 0, 1, "TextAreaEmojisHand= ler"); = qmlRegisterUncreatableType (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 + + 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-1= 301 USA +*/ + +#include "text-area-emojis-handler.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +TextAreaEmojisHandler::TextAreaEmojisHandler(QObject *parent) + : QObject(parent), + m_emojiMatcher(QStringLiteral("(^|\\s)(:[^\\s]+:)")), + m_emojiImgMatcher(QStringLiteral("")) +{ + KEmoticons *kemoticons =3D new KEmoticons(); + kemoticons->setPreferredEmoticonSize(QSize(32, 32)); + m_theme =3D kemoticons->theme(QStringLiteral("EmojiOne")); +} + +TextAreaEmojisHandler::~TextAreaEmojisHandler() +{ + +} + +void TextAreaEmojisHandler::setTextArea(QQuickItem *textArea) +{ + m_document =3D 0; + m_textArea =3D textArea; + + if (!m_textArea) { + return; + } + + QVariant doc =3D m_textArea->property("textDocument"); + if (doc.canConvert()) { + QQuickTextDocument *qqdoc =3D doc.value(); + if (qqdoc) { + m_document =3D qqdoc->textDocument(); + } + } + + Q_EMIT textAreaChanged(); + + connect(m_document, &QTextDocument::contentsChanged, this, &TextAreaEm= ojisHandler::onTextChanged); +} + +QQuickItem* TextAreaEmojisHandler::textArea() const +{ + return m_textArea; +} + +void TextAreaEmojisHandler::onTextChanged() +{ + QRegularExpressionMatchIterator matches =3D m_emojiMatcher.globalMatch= (m_document->toPlainText()); + if (!matches.hasNext()) { + return; + } + + QString text =3D m_document->toPlainText(); + QTextCursor cursor =3D QTextCursor(m_document); + + while (matches.hasNext()) { + QRegularExpressionMatch match =3D matches.next(); + + QString emojiHtml; + if (match.capturedStart() !=3D 0) { + emojiHtml =3D 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 =3D m_document->toHtml(); + auto emojiImgs =3D m_emojiImgMatcher.globalMatch(documentHtml); + + while (emojiImgs.hasNext()) { + auto emoji =3D emojiImgs.next(); + documentHtml.replace(emoji.capturedStart(0), emoji.capturedLength(= 0), asciiEmojiForPath(emoji.captured(1))); + } + + QTextDocument *tempDocument =3D new QTextDocument(); + tempDocument->setHtml(documentHtml); + + int start =3D qBound(0, 0, tempDocument->characterCount() - 1); + int end =3D 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 =3D 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/t= ext-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 + + 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-1= 301 USA +*/ + +#ifndef TEXTAREAEMOJISHANDLER_H +#define TEXTAREAEMOJISHANDLER_H + +#include +#include +#include + +class QTextDocument; +class QQuickItem; + +class TextAreaEmojisHandler : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickItem *textArea READ textArea WRITE setTextArea NOTIFY= textAreaChanged) + +public: + TextAreaEmojisHandler(QObject *parent =3D 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