diff options
Diffstat (limited to '')
-rw-r--r-- | sfx2/source/control/emojiview.cxx | 224 |
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: */ |