/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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(pItem); if (pViewItem) return isFilteredCategory(mCategory, pViewItem->getCategory()); return true; } EmojiView::EmojiView(std::unique_ptr 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(file)), std::istreambuf_iterator()); 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 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 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 &rLink) { maInsertEmojiHdl = rLink; } void EmojiView::AppendItem(const OUString &rTitle, const OUString &rCategory, const OUString &rName) { std::unique_ptr 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: */