nss: upgrade to release 3.73
[LibreOffice.git] / sfx2 / source / control / emojiview.cxx
blobee902a9da20723d03ef0b570be03a894ff4e5677
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <osl/file.hxx>
11 #include <emojiview.hxx>
12 #include <emojiviewitem.hxx>
13 #include <rtl/bootstrap.hxx>
14 #include <sal/log.hxx>
15 #include <config_folders.h>
16 #include <officecfg/Office/Common.hxx>
17 #include <comphelper/processfactory.hxx>
18 #include <vcl/event.hxx>
19 #include <vcl/svapp.hxx>
21 #include <orcus/json_document_tree.hpp>
22 #include <orcus/config.hpp>
23 #include <orcus/pstring.hpp>
24 #include <string>
25 #include <fstream>
27 using namespace ::com::sun::star;
29 bool ViewFilter_Category::isFilteredCategory(FILTER_CATEGORY filter, const OUString &rCategory)
31 bool bRet = true;
33 if (filter == FILTER_CATEGORY::PEOPLE)
34 bRet = rCategory.match("people");
35 else if (filter == FILTER_CATEGORY::NATURE)
36 bRet = rCategory.match("nature");
37 else if (filter == FILTER_CATEGORY::FOOD)
38 bRet = rCategory.match("food");
39 else if (filter == FILTER_CATEGORY::ACTIVITY)
40 bRet = rCategory.match("activity");
41 else if (filter == FILTER_CATEGORY::TRAVEL)
42 bRet = rCategory.match("travel");
43 else if (filter == FILTER_CATEGORY::OBJECTS)
44 bRet = rCategory.match("objects");
45 else if (filter == FILTER_CATEGORY::SYMBOLS)
46 bRet = rCategory.match("symbols");
47 else if (filter == FILTER_CATEGORY::FLAGS)
48 bRet = rCategory.match("flags");
49 else if (filter == FILTER_CATEGORY::UNICODE9)
50 bRet = rCategory.match("unicode9");
52 return bRet;
55 bool ViewFilter_Category::operator () (const ThumbnailViewItem *pItem)
57 const EmojiViewItem *pViewItem = dynamic_cast<const EmojiViewItem*>(pItem);
58 if (pViewItem)
59 return isFilteredCategory(mCategory, pViewItem->getCategory());
61 return true;
64 EmojiView::EmojiView(std::unique_ptr<weld::ScrolledWindow> xWindow)
65 : ThumbnailView(std::move(xWindow), nullptr)
67 // locate json data file
68 OUString aURL("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/emojiconfig/emoji.json");
69 rtl::Bootstrap::expandMacros(aURL);
71 OUString aPath;
72 osl::FileBase::getSystemPathFromFileURL(aURL, aPath);
73 std::string strPath = OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).getStr();
75 std::ifstream file(strPath);
76 if(!file.is_open())
77 return;
79 msJSONData = std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
80 if(msJSONData.empty())
81 return;
84 void EmojiView::SetDrawingArea(weld::DrawingArea* pDrawingArea)
86 ThumbnailView::SetDrawingArea(pDrawingArea);
88 if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice()))
90 uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
91 OUString sFontName(officecfg::Office::Common::Misc::EmojiFont::get(xContext));
92 vcl::Font aFont = pDrawingArea->get_font();
93 aFont.SetFamilyName(sFontName);
94 OutputDevice& rDevice = pDrawingArea->get_ref_device();
95 pDefaultDevice->SetPointFont(rDevice, aFont);
98 mpItemAttrs->aFontSize.setX(ITEM_MAX_WIDTH - 2*ITEM_PADDING);
99 mpItemAttrs->aFontSize.setY(ITEM_MAX_HEIGHT - 2*ITEM_PADDING);
102 EmojiView::~EmojiView()
106 void EmojiView::Populate()
108 if (msJSONData.empty())
110 SAL_WARN("sfx", "Emoji config data is empty");
111 return;
114 // Populate view using the orcus json parser
115 using node = orcus::json::node;
117 // default json config
118 orcus::json_config config;
120 orcus::json::document_tree aEmojiInfo;
122 // Load JSON string into a document tree.
123 aEmojiInfo.load(msJSONData, config);
125 node root = aEmojiInfo.get_document_root();
126 std::vector<orcus::pstring> keys = root.keys();
128 for (auto const& key : keys)
130 node value = root.child(key);
132 if(value.type() == orcus::json::node_t::object)
134 // iterate each element to get the keys
135 std::vector<orcus::pstring> aEmojiParams = value.keys();
136 OUString sTitle, sCategory, sName;
137 bool bDuplicate = false;
139 for (auto const& emojiParam : aEmojiParams)
141 node prop = value.child(emojiParam);
143 // get values of parameters in AppendItem() function
144 if(emojiParam == "unicode")
146 sTitle = OStringToOUString(OString( prop.string_value().get(), prop.string_value().size() ), RTL_TEXTENCODING_UTF8);
148 else if(emojiParam == "category")
150 sCategory = OStringToOUString(OString( prop.string_value().get(), prop.string_value().size() ), RTL_TEXTENCODING_UTF8);
152 else if(emojiParam == "name")
154 sName = OStringToOUString(OString( prop.string_value().get(), prop.string_value().size() ), RTL_TEXTENCODING_UTF8);
156 else if(emojiParam == "duplicate")
158 bDuplicate = true;
162 // Don't append if a duplicate emoji
163 if(!bDuplicate)
165 AppendItem(sTitle, sCategory, sName);
171 bool EmojiView::MouseButtonDown( const MouseEvent& rMEvt )
173 GrabFocus();
175 if (rMEvt.IsLeft())
177 size_t nPos = ImplGetItem(rMEvt.GetPosPixel());
178 ThumbnailViewItem* pItem = ImplGetItem(nPos);
180 if(pItem)
181 maInsertEmojiHdl.Call(pItem);
184 return true;
187 bool EmojiView::KeyInput( const KeyEvent& rKEvt )
189 vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
191 if(aKeyCode == ( KEY_MOD1 | KEY_A ) )
193 for (ThumbnailViewItem* pItem : mFilteredItemList)
195 if (!pItem->isSelected())
197 pItem->setSelection(true);
201 if (IsReallyVisible() && IsUpdateMode())
202 Invalidate();
203 return true;
206 return ThumbnailView::KeyInput(rKEvt);
209 void EmojiView::setInsertEmojiHdl(const Link<ThumbnailViewItem*, void> &rLink)
211 maInsertEmojiHdl = rLink;
214 void EmojiView::AppendItem(const OUString &rTitle, const OUString &rCategory, const OUString &rName)
216 std::unique_ptr<EmojiViewItem> pItem(new EmojiViewItem(*this, getNextItemId()));
218 pItem->maTitle = rTitle;
219 pItem->setCategory(rCategory);
220 pItem->setHelpText(rName);
222 ThumbnailView::AppendItem(std::move(pItem));
224 CalculateItemPositions();
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */