summaryrefslogtreecommitdiffstats
path: root/sfx2/source/control/emojiview.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/control/emojiview.cxx')
-rw-r--r--sfx2/source/control/emojiview.cxx224
1 files changed, 224 insertions, 0 deletions
diff --git a/sfx2/source/control/emojiview.cxx b/sfx2/source/control/emojiview.cxx
new file mode 100644
index 000000000..6e5bd97b8
--- /dev/null
+++ b/sfx2/source/control/emojiview.cxx
@@ -0,0 +1,224 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <osl/file.hxx>
+#include <emojiview.hxx>
+#include <emojiviewitem.hxx>
+#include <rtl/bootstrap.hxx>
+#include <sal/log.hxx>
+#include <config_folders.h>
+#include <officecfg/Office/Common.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vcl/event.hxx>
+#include <vcl/weldutils.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <orcus/json_document_tree.hpp>
+#include <orcus/config.hpp>
+#include <string>
+#include <string_view>
+#include <fstream>
+
+using namespace ::com::sun::star;
+
+bool ViewFilter_Category::isFilteredCategory(FILTER_CATEGORY filter, std::u16string_view rCategory)
+{
+ bool bRet = true;
+
+ if (filter == FILTER_CATEGORY::PEOPLE)
+ bRet = o3tl::starts_with(rCategory, u"people");
+ else if (filter == FILTER_CATEGORY::NATURE)
+ bRet = o3tl::starts_with(rCategory, u"nature");
+ else if (filter == FILTER_CATEGORY::FOOD)
+ bRet = o3tl::starts_with(rCategory, u"food");
+ else if (filter == FILTER_CATEGORY::ACTIVITY)
+ bRet = o3tl::starts_with(rCategory, u"activity");
+ else if (filter == FILTER_CATEGORY::TRAVEL)
+ bRet = o3tl::starts_with(rCategory, u"travel");
+ else if (filter == FILTER_CATEGORY::OBJECTS)
+ bRet = o3tl::starts_with(rCategory, u"objects");
+ else if (filter == FILTER_CATEGORY::SYMBOLS)
+ bRet = o3tl::starts_with(rCategory, u"symbols");
+ else if (filter == FILTER_CATEGORY::FLAGS)
+ bRet = o3tl::starts_with(rCategory, u"flags");
+ else if (filter == FILTER_CATEGORY::UNICODE9)
+ bRet = o3tl::starts_with(rCategory, u"unicode9");
+
+ return bRet;
+}
+
+bool ViewFilter_Category::operator () (const ThumbnailViewItem *pItem)
+{
+ const EmojiViewItem *pViewItem = dynamic_cast<const EmojiViewItem*>(pItem);
+ if (pViewItem)
+ return isFilteredCategory(mCategory, pViewItem->getCategory());
+
+ return true;
+}
+
+EmojiView::EmojiView(std::unique_ptr<weld::ScrolledWindow> xWindow)
+ : ThumbnailView(std::move(xWindow), nullptr)
+{
+ // locate json data file
+ OUString aURL("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/emojiconfig/emoji.json");
+ rtl::Bootstrap::expandMacros(aURL);
+
+ OUString aPath;
+ osl::FileBase::getSystemPathFromFileURL(aURL, aPath);
+ std::string strPath = OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).getStr();
+
+ std::ifstream file(strPath);
+ if(!file.is_open())
+ return;
+
+ msJSONData = std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
+ if(msJSONData.empty())
+ return;
+}
+
+void EmojiView::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ ThumbnailView::SetDrawingArea(pDrawingArea);
+
+ OUString sFontName(officecfg::Office::Common::Misc::EmojiFont::get());
+ vcl::Font aFont = pDrawingArea->get_font();
+ aFont.SetFamilyName(sFontName);
+ OutputDevice& rDevice = pDrawingArea->get_ref_device();
+ weld::SetPointFont(rDevice, aFont);
+
+ mpItemAttrs->aFontSize.setX(ITEM_MAX_WIDTH - 2*ITEM_PADDING);
+ mpItemAttrs->aFontSize.setY(ITEM_MAX_HEIGHT - 2*ITEM_PADDING);
+}
+
+EmojiView::~EmojiView()
+{
+}
+
+void EmojiView::Populate()
+{
+ if (msJSONData.empty())
+ {
+ SAL_WARN("sfx", "Emoji config data is empty");
+ return;
+ }
+
+ // Populate view using the orcus json parser
+ using node = orcus::json::node;
+
+ // default json config
+ orcus::json_config config;
+
+ orcus::json::document_tree aEmojiInfo;
+
+ // Load JSON string into a document tree.
+ aEmojiInfo.load(msJSONData, config);
+
+ node root = aEmojiInfo.get_document_root();
+ std::vector<std::string_view> keys = root.keys();
+
+ for (auto const& key : keys)
+ {
+ node value = root.child(key);
+
+ if(value.type() == orcus::json::node_t::object)
+ {
+ // iterate each element to get the keys
+ std::vector<std::string_view> aEmojiParams = value.keys();
+ OUString sTitle, sCategory, sName;
+ bool bDuplicate = false;
+
+ for (auto const& emojiParam : aEmojiParams)
+ {
+ node prop = value.child(emojiParam);
+
+ // get values of parameters in AppendItem() function
+ if(emojiParam == "unicode")
+ {
+ sTitle = OStringToOUString(prop.string_value(), RTL_TEXTENCODING_UTF8);
+ }
+ else if(emojiParam == "category")
+ {
+ sCategory = OStringToOUString(prop.string_value(), RTL_TEXTENCODING_UTF8);
+ }
+ else if(emojiParam == "name")
+ {
+ sName = OStringToOUString(prop.string_value(), RTL_TEXTENCODING_UTF8);
+ }
+ else if(emojiParam == "duplicate")
+ {
+ bDuplicate = true;
+ }
+ }
+
+ // Don't append if a duplicate emoji
+ if(!bDuplicate)
+ {
+ AppendItem(sTitle, sCategory, sName);
+ }
+ }
+ }
+}
+
+bool EmojiView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ GrabFocus();
+
+ if (rMEvt.IsLeft())
+ {
+ size_t nPos = ImplGetItem(rMEvt.GetPosPixel());
+ ThumbnailViewItem* pItem = ImplGetItem(nPos);
+
+ if(pItem)
+ maInsertEmojiHdl.Call(pItem);
+ }
+
+ return true;
+}
+
+bool EmojiView::KeyInput( const KeyEvent& rKEvt )
+{
+ vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if(aKeyCode == ( KEY_MOD1 | KEY_A ) )
+ {
+ for (ThumbnailViewItem* pItem : mFilteredItemList)
+ {
+ if (!pItem->isSelected())
+ {
+ pItem->setSelection(true);
+ }
+ }
+
+ if (IsReallyVisible() && IsUpdateMode())
+ Invalidate();
+ return true;
+ }
+
+ return ThumbnailView::KeyInput(rKEvt);
+}
+
+void EmojiView::setInsertEmojiHdl(const Link<ThumbnailViewItem*, void> &rLink)
+{
+ maInsertEmojiHdl = rLink;
+}
+
+void EmojiView::AppendItem(const OUString &rTitle, const OUString &rCategory, const OUString &rName)
+{
+ std::unique_ptr<EmojiViewItem> pItem(new EmojiViewItem(*this, getNextItemId()));
+
+ pItem->maTitle = rTitle;
+ pItem->setCategory(rCategory);
+ pItem->setHelpText(rName);
+
+ ThumbnailView::AppendItem(std::move(pItem));
+
+ CalculateItemPositions();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */