cui/source/dialogs/cuicharmap.cxx | 408 +----------------------------- include/cui/cuicharmap.hxx | 34 -- include/sfx2/charwin.hxx | 58 ++++ sfx2/inc/charmapcontrol.hxx | 16 - sfx2/source/control/charmapcontrol.cxx | 440 ++++++++++++++++++++++++++------- sfx2/uiconfig/ui/charmapcontrol.ui | 4 6 files changed, 430 insertions(+), 530 deletions(-)
New commits: commit c706fde1c4ecc6974bcf32ce33aacf3093355ae1 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Tue Jun 27 12:35:57 2023 +0100 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Wed Jun 28 09:41:20 2023 +0200 Resolves: tdf#156067 merge special char dialog/popup logic there was some cut and paste done to create the popup at some point, so put it back together and reuse the "delete recent" etc which is missing from the popup case Change-Id: Idc33d83ea04b46b0255e77bcecf565dc8174e426 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153647 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/cui/source/dialogs/cuicharmap.cxx b/cui/source/dialogs/cuicharmap.cxx index c075c12326d2..4c4df2fe9cb3 100644 --- a/cui/source/dialogs/cuicharmap.cxx +++ b/cui/source/dialogs/cuicharmap.cxx @@ -58,38 +58,7 @@ SvxCharacterMap::SvxCharacterMap(weld::Widget* pParent, const SfxItemSet* pSet, , m_xVirDev(VclPtr<VirtualDevice>::Create()) , isSearchMode(true) , m_xFrame(std::move(xFrame)) - , m_aRecentCharView{SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev)} - , m_aFavCharView{SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev)} + , m_aCharmapContents(*m_xBuilder, m_xVirDev) , m_aShowChar(m_xVirDev) , m_xOKBtn(m_xFrame.is() ? m_xBuilder->weld_button("insert") : m_xBuilder->weld_button("ok")) , m_xFontText(m_xBuilder->weld_label("fontft")) @@ -101,41 +70,7 @@ SvxCharacterMap::SvxCharacterMap(weld::Widget* pParent, const SfxItemSet* pSet, , m_xDecimalCodeText(m_xBuilder->weld_entry("decimalvalue")) , m_xFavouritesBtn(m_xBuilder->weld_button("favbtn")) , m_xCharName(m_xBuilder->weld_label("charname")) - , m_xRecentGrid(m_xBuilder->weld_widget("viewgrid")) - , m_xFavGrid(m_xBuilder->weld_widget("favgrid")) , m_xShowChar(new weld::CustomWeld(*m_xBuilder, "showchar", m_aShowChar)) - , m_xRecentCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar1", m_aRecentCharView[0]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar2", m_aRecentCharView[1]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar3", m_aRecentCharView[2]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar4", m_aRecentCharView[3]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar5", m_aRecentCharView[4]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar6", m_aRecentCharView[5]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar7", m_aRecentCharView[6]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar8", m_aRecentCharView[7]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar9", m_aRecentCharView[8]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar10", m_aRecentCharView[9]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar11", m_aRecentCharView[10]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar12", m_aRecentCharView[11]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar13", m_aRecentCharView[12]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar14", m_aRecentCharView[13]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar15", m_aRecentCharView[14]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar16", m_aRecentCharView[15])} - , m_xFavCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar1", m_aFavCharView[0]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar2", m_aFavCharView[1]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar3", m_aFavCharView[2]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar4", m_aFavCharView[3]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar5", m_aFavCharView[4]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar6", m_aFavCharView[5]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar7", m_aFavCharView[6]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar8", m_aFavCharView[7]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar9", m_aFavCharView[8]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar10", m_aFavCharView[9]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar11", m_aFavCharView[10]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar12", m_aFavCharView[11]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar13", m_aFavCharView[12]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar14", m_aFavCharView[13]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar15", m_aFavCharView[14]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar16", m_aFavCharView[15])} , m_xShowSet(new SvxShowCharSet(m_xBuilder->weld_scrolled_window("showscroll", true), m_xVirDev)) , m_xShowSetArea(new weld::CustomWeld(*m_xBuilder, "showcharset", *m_xShowSet)) , m_xSearchSet(new SvxSearchCharSet(m_xBuilder->weld_scrolled_window("searchscroll", true), m_xVirDev)) @@ -149,9 +84,6 @@ SvxCharacterMap::SvxCharacterMap(weld::Widget* pParent, const SfxItemSet* pSet, m_xCharName->set_size_request(m_aShowChar.get_preferred_size().Width(), m_xCharName->get_text_height() * 4); //lock the size request of this widget to the width of the original .ui string m_xHexCodeText->set_size_request(m_xHexCodeText->get_preferred_size().Width(), -1); - //so things don't jump around if all the children are hidden - m_xRecentGrid->set_size_request(-1, m_aRecentCharView[0].get_preferred_size().Height()); - m_xFavGrid->set_size_request(-1, m_aFavCharView[0].get_preferred_size().Height()); init(); @@ -222,236 +154,14 @@ void SvxCharacterMap::DisableFontSelection() m_xFontLB->set_sensitive(false); } - -void SvxCharacterMap::getRecentCharacterList() -{ - //retrieve recent character list - const css::uno::Sequence< OUString > rRecentCharList( officecfg::Office::Common::RecentCharacters::RecentCharacterList::get() ); - for (OUString const & s : rRecentCharList) - { - maRecentCharList.push_back(s); - } - - //retrieve recent character font list - const css::uno::Sequence< OUString > rRecentCharFontList( officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::get() ); - for (OUString const & s : rRecentCharFontList) - { - maRecentCharFontList.push_back(s); - } - - // tdf#135997: make sure that the two lists are same length - const auto nCommonLength = std::min(maRecentCharList.size(), maRecentCharFontList.size()); - maRecentCharList.resize(nCommonLength); - maRecentCharFontList.resize(nCommonLength); -} - - -void SvxCharacterMap::getFavCharacterList() -{ - maFavCharList.clear(); - maFavCharFontList.clear(); - //retrieve recent character list - const css::uno::Sequence< OUString > rFavCharList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::get() ); - for (const OUString& s : rFavCharList) - { - maFavCharList.push_back(s); - } - - //retrieve recent character font list - const css::uno::Sequence< OUString > rFavCharFontList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::get() ); - for (const OUString& s : rFavCharFontList) - { - maFavCharFontList.push_back(s); - } - - // tdf#135997: make sure that the two lists are same length - const auto nCommonLength = std::min(maFavCharList.size(), maFavCharFontList.size()); - maFavCharList.resize(nCommonLength); - maFavCharFontList.resize(nCommonLength); -} - -static std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> -findInPair(std::u16string_view str1, const std::deque<OUString>& rContainer1, - std::u16string_view str2, const std::deque<OUString>& rContainer2) -{ - assert(rContainer1.size() == rContainer2.size()); - - for (auto it1 = std::find(rContainer1.begin(), rContainer1.end(), str1); - it1 != rContainer1.end(); it1 = std::find(std::next(it1), rContainer1.end(), str1)) - { - auto it2 = rContainer2.begin() + (it1 - rContainer1.begin()); - if (*it2 == str2) - return { it1, it2 }; - } - return { rContainer1.end(), rContainer2.end() }; -} - -std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> -SvxCharacterMap::getRecentChar(std::u16string_view sTitle, std::u16string_view rFont) const -{ - return findInPair(sTitle, maRecentCharList, rFont, maRecentCharFontList); -} - -std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> -SvxCharacterMap::getFavChar(std::u16string_view sTitle, std::u16string_view rFont) const +IMPL_LINK_NOARG(SvxCharacterMap, UpdateFavHdl, void*, void) { - return findInPair(sTitle, maFavCharList, rFont, maFavCharFontList); -} - - -void SvxCharacterMap::updateRecentCharControl() -{ - assert(maRecentCharList.size() == maRecentCharFontList.size()); - - int i = 0; - for ( std::deque< OUString >::iterator it = maRecentCharList.begin(), it2 = maRecentCharFontList.begin(); - it != maRecentCharList.end() && it2 != maRecentCharFontList.end(); - ++it, ++it2, i++) - { - m_aRecentCharView[i].SetText(*it); - vcl::Font rFont = m_aRecentCharView[i].GetFont(); - rFont.SetFamilyName( *it2 ); - m_aRecentCharView[i].SetFont(rFont); - m_aRecentCharView[i].Show(); - } - - for(; i < 16 ; i++) - { - m_aRecentCharView[i].SetText(OUString()); - m_aRecentCharView[i].Hide(); - } -} - -void SvxCharacterMap::updateRecentCharacterList(const OUString& sTitle, const OUString& rFont) -{ - // if recent char to be added is already in list, remove it - if( const auto& [itChar, itChar2] = getRecentChar(sTitle, rFont); - itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() ) - { - maRecentCharList.erase( itChar ); - maRecentCharFontList.erase( itChar2); - } - - if (maRecentCharList.size() == 16) - { - maRecentCharList.pop_back(); - maRecentCharFontList.pop_back(); - } - - maRecentCharList.push_front(sTitle); - maRecentCharFontList.push_front(rFont); - - css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size()); - auto aRecentCharListRange = asNonConstRange(aRecentCharList); - css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size()); - auto aRecentCharFontListRange = asNonConstRange(aRecentCharFontList); - - for (size_t i = 0; i < maRecentCharList.size(); ++i) - { - aRecentCharListRange[i] = maRecentCharList[i]; - aRecentCharFontListRange[i] = maRecentCharFontList[i]; - } - - std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); - officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch); - officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch); - batch->commit(); - - updateRecentCharControl(); -} - - -void SvxCharacterMap::updateFavCharacterList(const OUString& sTitle, const OUString& rFont) -{ - // if Fav char to be added is already in list, remove it - if( const auto& [itChar, itChar2] = getFavChar(sTitle, rFont); - itChar != maFavCharList.end() && itChar2 != maFavCharFontList.end() ) - { - maFavCharList.erase( itChar ); - maFavCharFontList.erase( itChar2); - } - - if (maFavCharList.size() == 16) - { - maFavCharList.pop_back(); - maFavCharFontList.pop_back(); - } - - maFavCharList.push_back(sTitle); - maFavCharFontList.push_back(rFont); - - css::uno::Sequence< OUString > aFavCharList(maFavCharList.size()); - auto aFavCharListRange = asNonConstRange(aFavCharList); - css::uno::Sequence< OUString > aFavCharFontList(maFavCharFontList.size()); - auto aFavCharFontListRange = asNonConstRange(aFavCharFontList); - - for (size_t i = 0; i < maFavCharList.size(); ++i) - { - aFavCharListRange[i] = maFavCharList[i]; - aFavCharFontListRange[i] = maFavCharFontList[i]; - } - - std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); - officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch); - officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch); - batch->commit(); -} - - -void SvxCharacterMap::updateFavCharControl() -{ - assert(maFavCharList.size() == maFavCharFontList.size()); - - int i = 0; - for ( std::deque< OUString >::iterator it = maFavCharList.begin(), it2 = maFavCharFontList.begin(); - it != maFavCharList.end() && it2 != maFavCharFontList.end(); - ++it, ++it2, i++) - { - m_aFavCharView[i].SetText(*it); - vcl::Font rFont = m_aFavCharView[i].GetFont(); - rFont.SetFamilyName( *it2 ); - m_aFavCharView[i].SetFont(rFont); - m_aFavCharView[i].Show(); - } - - for(; i < 16 ; i++) - { - m_aFavCharView[i].SetText(OUString()); - m_aFavCharView[i].Hide(); - } m_xShowSet->getFavCharacterList(); m_xSearchSet->getFavCharacterList(); // tdf#109214 - redraw highlight of the favorite characters m_xShowSet->Invalidate(); } -void SvxCharacterMap::deleteFavCharacterFromList(std::u16string_view sTitle, std::u16string_view rFont) -{ - // if Fav char is found, remove it - if( const auto& [itChar, itChar2] = getFavChar(sTitle, rFont); - itChar != maFavCharList.end() && itChar2 != maFavCharFontList.end() ) - { - maFavCharList.erase( itChar ); - maFavCharFontList.erase( itChar2); - } - - css::uno::Sequence< OUString > aFavCharList(maFavCharList.size()); - auto aFavCharListRange = asNonConstRange(aFavCharList); - css::uno::Sequence< OUString > aFavCharFontList(maFavCharFontList.size()); - auto aFavCharFontListRange = asNonConstRange(aFavCharFontList); - - for (size_t i = 0; i < maFavCharList.size(); ++i) - { - aFavCharListRange[i] = maFavCharList[i]; - aFavCharFontListRange[i] = maFavCharFontList[i]; - } - - std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); - officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch); - officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch); - batch->commit(); -} - void SvxCharacterMap::init() { aFont = m_xVirDev->GetFont(); @@ -549,25 +259,10 @@ void SvxCharacterMap::init() m_xOKBtn->set_sensitive(true); } - getRecentCharacterList(); - updateRecentCharControl(); - - getFavCharacterList(); - updateFavCharControl(); - - bool bHasInsert = m_xFrame.is(); - - for(int i = 0; i < 16; i++) - { - m_aRecentCharView[i].SetHasInsert(bHasInsert); - m_aRecentCharView[i].setMouseClickHdl(LINK(this,SvxCharacterMap, CharClickHdl)); - m_aRecentCharView[i].setClearClickHdl(LINK(this,SvxCharacterMap, RecentClearClickHdl)); - m_aRecentCharView[i].setClearAllClickHdl(LINK(this,SvxCharacterMap, RecentClearAllClickHdl)); - m_aFavCharView[i].SetHasInsert(bHasInsert); - m_aFavCharView[i].setMouseClickHdl(LINK(this,SvxCharacterMap, CharClickHdl)); - m_aFavCharView[i].setClearClickHdl(LINK(this,SvxCharacterMap, FavClearClickHdl)); - m_aFavCharView[i].setClearAllClickHdl(LINK(this,SvxCharacterMap, FavClearAllClickHdl)); - } + m_aCharmapContents.init(m_xFrame.is(), + LINK(this, SvxCharacterMap, CharClickHdl), + LINK(this, SvxCharacterMap, UpdateFavHdl), + Link<void*, void>()); setCharName(90); @@ -575,13 +270,6 @@ void SvxCharacterMap::init() m_xSearchText->connect_changed(LINK(this, SvxCharacterMap, SearchUpdateHdl)); } -bool SvxCharacterMap::isFavChar(std::u16string_view sTitle, std::u16string_view rFont) -{ - const auto& [itChar, itFont] = getFavChar(sTitle, rFont); - return itChar != maFavCharList.end() && itFont != maFavCharFontList.end(); -} - - void SvxCharacterMap::setFavButtonState(std::u16string_view sTitle, std::u16string_view rFont) { if(sTitle.empty() || rFont.empty()) @@ -592,16 +280,14 @@ void SvxCharacterMap::setFavButtonState(std::u16string_view sTitle, std::u16stri else m_xFavouritesBtn->set_sensitive(true); - if (isFavChar(sTitle, rFont)) + if (m_aCharmapContents.isFavChar(sTitle, rFont)) { m_xFavouritesBtn->set_label(CuiResId(RID_CUISTR_REMOVE_FAVORITES)); } else { - if(maFavCharList.size() == 16) - { + if (m_aCharmapContents.FavCharListIsFull()) m_xFavouritesBtn->set_sensitive(false); - } m_xFavouritesBtn->set_label(CuiResId(RID_CUISTR_ADD_FAVORITES)); } @@ -656,7 +342,7 @@ void SvxCharacterMap::insertCharToDoc(const OUString& sGlyph) }; comphelper::dispatchCommand(".uno:InsertSymbol", m_xFrame, aArgs); - updateRecentCharacterList(sGlyph, aFont.GetFamilyName()); + m_aCharmapContents.updateRecentCharacterList(sGlyph, aFont.GetFamilyName()); } else { sal_UCS4 cChar = sGlyph.iterateCodePoints(&o3tl::temporary(sal_Int32(0))); @@ -783,70 +469,6 @@ IMPL_LINK_NOARG(SvxCharacterMap, SubsetSelectHdl, weld::ComboBox&, void) } } -IMPL_LINK(SvxCharacterMap, RecentClearClickHdl, SvxCharView*, rView, void) -{ - const OUString& sTitle = rView->GetText(); - OUString sFont = rView->GetFont().GetFamilyName(); - - // if recent char to be added is already in list, remove it - if( const auto& [itChar, itChar2] = getRecentChar(sTitle, sFont); - itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() ) - { - maRecentCharList.erase( itChar ); - maRecentCharFontList.erase( itChar2); - } - - css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size()); - auto aRecentCharListRange = asNonConstRange(aRecentCharList); - css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size()); - auto aRecentCharFontListRange = asNonConstRange(aRecentCharFontList); - - for (size_t i = 0; i < maRecentCharList.size(); ++i) - { - aRecentCharListRange[i] = maRecentCharList[i]; - aRecentCharFontListRange[i] = maRecentCharFontList[i]; - } - - std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); - officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch); - officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch); - batch->commit(); - - updateRecentCharControl(); -} - -IMPL_LINK_NOARG(SvxCharacterMap, RecentClearAllClickHdl, SvxCharView*, void) -{ - maRecentCharList.clear(); - maRecentCharFontList.clear(); - - std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); - officecfg::Office::Common::RecentCharacters::RecentCharacterList::set({ }, batch); - officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set({ }, batch); - batch->commit(); - - updateRecentCharControl(); -} - -IMPL_LINK(SvxCharacterMap, FavClearClickHdl, SvxCharView*, rView, void) -{ - deleteFavCharacterFromList(rView->GetText(), rView->GetFont().GetFamilyName()); - updateFavCharControl(); -} - -IMPL_LINK_NOARG(SvxCharacterMap, FavClearAllClickHdl, SvxCharView*, void) -{ - maFavCharList.clear(); - maFavCharFontList.clear(); - - std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); - officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set({ }, batch); - officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set({ }, batch); - batch->commit(); - - updateFavCharControl(); -} - IMPL_LINK_NOARG(SvxCharacterMap, SearchFieldGetFocusHdl, weld::Widget&, void) { m_xOKBtn->set_sensitive(false); @@ -955,7 +577,7 @@ IMPL_LINK_NOARG(SvxCharacterMap, InsertClickHdl, weld::Button&, void) insertCharToDoc(sChar); // Need to update recent character list, when OK button does not insert if(!m_xFrame.is()) - updateRecentCharacterList(sChar, aFont.GetFamilyName()); + m_aCharmapContents.updateRecentCharacterList(sChar, aFont.GetFamilyName()); m_xDialog->response(RET_OK); } @@ -963,23 +585,23 @@ IMPL_LINK_NOARG(SvxCharacterMap, FavSelectHdl, weld::Button&, void) { if (m_xFavouritesBtn->get_label().match(CuiResId(RID_CUISTR_ADD_FAVORITES))) { - updateFavCharacterList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName()); + m_aCharmapContents.updateFavCharacterList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName()); setFavButtonState(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName()); } else { - deleteFavCharacterFromList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName()); + m_aCharmapContents.deleteFavCharacterFromList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName()); m_xFavouritesBtn->set_label(CuiResId(RID_CUISTR_ADD_FAVORITES)); m_xFavouritesBtn->set_sensitive(false); } - updateFavCharControl(); + m_aCharmapContents.updateFavCharControl(); } IMPL_LINK_NOARG(SvxCharacterMap, FavClickHdl, SvxShowCharSet*, void) { - getFavCharacterList(); - updateFavCharControl(); + m_aCharmapContents.getFavCharacterList(); + m_aCharmapContents.updateFavCharControl(); } IMPL_LINK_NOARG(SvxCharacterMap, CharHighlightHdl, SvxShowCharSet*, void) diff --git a/include/cui/cuicharmap.hxx b/include/cui/cuicharmap.hxx index 431ce6dc30f5..8b85b1883ea5 100644 --- a/include/cui/cuicharmap.hxx +++ b/include/cui/cuicharmap.hxx @@ -83,13 +83,9 @@ private: std::unique_ptr<const SubsetMap> pSubsetMap; bool isSearchMode; css::uno::Reference<css::frame::XFrame> m_xFrame; - std::deque<OUString> maRecentCharList; - std::deque<OUString> maRecentCharFontList; - std::deque<OUString> maFavCharList; - std::deque<OUString> maFavCharFontList; - SvxCharView m_aRecentCharView[16]; - SvxCharView m_aFavCharView[16]; + SfxCharmapContainer m_aCharmapContents; + SvxShowText m_aShowChar; std::unique_ptr<weld::Button> m_xOKBtn; @@ -102,11 +98,7 @@ private: std::unique_ptr<weld::Entry> m_xDecimalCodeText; std::unique_ptr<weld::Button> m_xFavouritesBtn; std::unique_ptr<weld::Label> m_xCharName; - std::unique_ptr<weld::Widget> m_xRecentGrid; - std::unique_ptr<weld::Widget> m_xFavGrid; std::unique_ptr<weld::CustomWeld> m_xShowChar; - std::unique_ptr<weld::CustomWeld> m_xRecentCharView[16]; - std::unique_ptr<weld::CustomWeld> m_xFavCharView[16]; std::unique_ptr<SvxShowCharSet> m_xShowSet; std::unique_ptr<weld::CustomWeld> m_xShowSetArea; std::unique_ptr<SvxSearchCharSet> m_xSearchSet; @@ -135,14 +127,11 @@ private: DECL_DLLPRIVATE_LINK(DecimalCodeChangeHdl, weld::Entry&, void); DECL_DLLPRIVATE_LINK(HexCodeChangeHdl, weld::Entry&, void); DECL_DLLPRIVATE_LINK(CharClickHdl, SvxCharView*, void); - DECL_DLLPRIVATE_LINK(RecentClearClickHdl, SvxCharView*, void); - DECL_DLLPRIVATE_LINK(FavClearClickHdl, SvxCharView*, void); - DECL_DLLPRIVATE_LINK(RecentClearAllClickHdl, SvxCharView*, void); - DECL_DLLPRIVATE_LINK(FavClearAllClickHdl, SvxCharView*, void); DECL_DLLPRIVATE_LINK(InsertClickHdl, weld::Button&, void); DECL_DLLPRIVATE_LINK(FavSelectHdl, weld::Button&, void); DECL_DLLPRIVATE_LINK(SearchUpdateHdl, weld::Entry&, void); DECL_DLLPRIVATE_LINK(SearchFieldGetFocusHdl, weld::Widget&, void); + DECL_DLLPRIVATE_LINK(UpdateFavHdl, void*, void); static void fillAllSubsets(weld::ComboBox& rListBox); void selectCharByCode(Radix radix); @@ -164,30 +153,13 @@ public: void SetChar(sal_UCS4); sal_UCS4 GetChar() const; - void getRecentCharacterList(); //gets both recent char and recent char font list - void updateRecentCharacterList(const OUString& rChar, const OUString& rFont); - - void getFavCharacterList(); //gets both Fav char and Fav char font list - void updateFavCharacterList(const OUString& rChar, const OUString& rFont); - void deleteFavCharacterFromList(std::u16string_view rChar, std::u16string_view rFont); - bool isFavChar(std::u16string_view sTitle, std::u16string_view rFont); - - void updateRecentCharControl(); void insertCharToDoc(const OUString& sChar); - void updateFavCharControl(); void setFavButtonState(std::u16string_view sTitle, std::u16string_view rFont); void setCharName(sal_UCS4 nDecimalValue); void toggleSearchView(bool state); - -private: - std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> - getRecentChar(std::u16string_view sTitle, std::u16string_view rFont) const; - - std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> - getFavChar(std::u16string_view sTitle, std::u16string_view rFont) const; }; #endif diff --git a/include/sfx2/charwin.hxx b/include/sfx2/charwin.hxx index a2beabc5b2df..515aa64a4acb 100644 --- a/include/sfx2/charwin.hxx +++ b/include/sfx2/charwin.hxx @@ -24,6 +24,7 @@ #include <vcl/customweld.hxx> #include <vcl/virdev.hxx> #include <vcl/weld.hxx> +#include <deque> class SFX2_DLLPUBLIC SvxCharView final : public weld::CustomWidgetController { @@ -67,6 +68,63 @@ public: void ContextMenuSelect(std::u16string_view rIdent); }; +class SFX2_DLLPUBLIC SfxCharmapContainer +{ + std::deque<OUString> m_aRecentCharList; + std::deque<OUString> m_aRecentCharFontList; + std::deque<OUString> m_aFavCharList; + std::deque<OUString> m_aFavCharFontList; + + SvxCharView m_aRecentCharView[16]; + SvxCharView m_aFavCharView[16]; + std::unique_ptr<weld::CustomWeld> m_xRecentCharView[16]; + std::unique_ptr<weld::CustomWeld> m_xFavCharView[16]; + + std::unique_ptr<weld::Widget> m_xRecentGrid; + std::unique_ptr<weld::Widget> m_xFavGrid; + + Link<SvxCharView*, void> m_aMouseClickHdl; + Link<void*, void> m_aUpdateFavHdl; + Link<void*, void> m_aUpdateRecentHdl; + + DECL_DLLPRIVATE_LINK(CharClickHdl, SvxCharView*, void); + DECL_DLLPRIVATE_LINK(RecentClearClickHdl, SvxCharView*, void); + DECL_DLLPRIVATE_LINK(FavClearClickHdl, SvxCharView*, void); + DECL_DLLPRIVATE_LINK(RecentClearAllClickHdl, SvxCharView*, void); + DECL_DLLPRIVATE_LINK(FavClearAllClickHdl, SvxCharView*, void); + +public: + SfxCharmapContainer(weld::Builder& rBuilder, const VclPtr<VirtualDevice>& rVirDev); + + void init(bool bHasInsert, const Link<SvxCharView*,void> &rMouseClickHdl, + const Link<void*,void> &rUpdateFavHdl, + const Link<void*,void> &rUpdateRecentHdl); + + void getFavCharacterList(); + void updateFavCharControl(); + + void getRecentCharacterList(); //gets both recent char and recent char font list + void updateRecentCharControl(); + + void updateRecentCharacterList(const OUString& sTitle, const OUString& rFont); + void updateFavCharacterList(const OUString& sTitle, const OUString& rFont); + void deleteFavCharacterFromList(std::u16string_view sTitle, std::u16string_view rFont); + + bool isFavChar(std::u16string_view sTitle, std::u16string_view rFont); + bool hasRecentChars() const; + + bool FavCharListIsFull() const; + + void GrabFocusToFirstFavorite(); + +private: + std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> + getRecentChar(std::u16string_view sTitle, std::u16string_view rFont) const; + + std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> + getFavChar(std::u16string_view sTitle, std::u16string_view rFont) const; +}; + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sfx2/inc/charmapcontrol.hxx b/sfx2/inc/charmapcontrol.hxx index e2c1e1e07349..c6045154583e 100644 --- a/sfx2/inc/charmapcontrol.hxx +++ b/sfx2/inc/charmapcontrol.hxx @@ -41,26 +41,14 @@ private: ScopedVclPtr<VirtualDevice> m_xVirDev; - std::deque<OUString> m_aRecentCharList; - std::deque<OUString> m_aRecentCharFontList; - std::deque<OUString> m_aFavCharList; - std::deque<OUString> m_aFavCharFontList; + SfxCharmapContainer m_aCharmapContents; - SvxCharView m_aRecentCharView[16]; - SvxCharView m_aFavCharView[16]; std::unique_ptr<weld::Label> m_xRecentLabel; std::unique_ptr<weld::Button> m_xDlgBtn; - std::unique_ptr<weld::CustomWeld> m_xRecentCharView[16]; - std::unique_ptr<weld::CustomWeld> m_xFavCharView[16]; DECL_LINK(CharClickHdl, SvxCharView*, void); DECL_LINK(OpenDlgHdl, weld::Button&, void); - - void getFavCharacterList(); - void updateFavCharControl(); - - void getRecentCharacterList(); //gets both recent char and recent char font list - void updateRecentCharControl(); + DECL_LINK(UpdateRecentHdl, void*, void); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/control/charmapcontrol.cxx b/sfx2/source/control/charmapcontrol.cxx index a79da745be26..359b81c49330 100644 --- a/sfx2/source/control/charmapcontrol.cxx +++ b/sfx2/source/control/charmapcontrol.cxx @@ -27,97 +27,127 @@ using namespace css; +SfxCharmapContainer::SfxCharmapContainer(weld::Builder& rBuilder, const VclPtr<VirtualDevice>& rVirDev) + : m_aRecentCharView{SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev)} + , m_aFavCharView{SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev), + SvxCharView(rVirDev)} + , m_xRecentCharView{std::make_unique<weld::CustomWeld>(rBuilder, "viewchar1", m_aRecentCharView[0]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar2", m_aRecentCharView[1]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar3", m_aRecentCharView[2]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar4", m_aRecentCharView[3]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar5", m_aRecentCharView[4]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar6", m_aRecentCharView[5]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar7", m_aRecentCharView[6]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar8", m_aRecentCharView[7]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar9", m_aRecentCharView[8]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar10", m_aRecentCharView[9]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar11", m_aRecentCharView[10]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar12", m_aRecentCharView[11]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar13", m_aRecentCharView[12]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar14", m_aRecentCharView[13]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar15", m_aRecentCharView[14]), + std::make_unique<weld::CustomWeld>(rBuilder, "viewchar16", m_aRecentCharView[15])} + , m_xFavCharView{std::make_unique<weld::CustomWeld>(rBuilder, "favchar1", m_aFavCharView[0]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar2", m_aFavCharView[1]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar3", m_aFavCharView[2]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar4", m_aFavCharView[3]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar5", m_aFavCharView[4]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar6", m_aFavCharView[5]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar7", m_aFavCharView[6]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar8", m_aFavCharView[7]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar9", m_aFavCharView[8]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar10", m_aFavCharView[9]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar11", m_aFavCharView[10]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar12", m_aFavCharView[11]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar13", m_aFavCharView[12]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar14", m_aFavCharView[13]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar15", m_aFavCharView[14]), + std::make_unique<weld::CustomWeld>(rBuilder, "favchar16", m_aFavCharView[15])} + , m_xRecentGrid(rBuilder.weld_widget("viewgrid")) + , m_xFavGrid(rBuilder.weld_widget("favgrid")) +{ + //so things don't jump around if all the children are hidden + m_xRecentGrid->set_size_request(-1, m_aRecentCharView[0].get_preferred_size().Height()); + m_xFavGrid->set_size_request(-1, m_aFavCharView[0].get_preferred_size().Height()); +} + +void SfxCharmapContainer::init(bool bHasInsert, const Link<SvxCharView*,void> &rMouseClickHdl, + const Link<void*, void>& rUpdateFavHdl, + const Link<void*, void>& rUpdateRecentHdl) +{ + m_aUpdateFavHdl = rUpdateFavHdl; + m_aUpdateRecentHdl = rUpdateRecentHdl; + + getRecentCharacterList(); + updateRecentCharControl(); + getFavCharacterList(); + updateFavCharControl(); + + for(int i = 0; i < 16; i++) + { + m_aRecentCharView[i].SetHasInsert(bHasInsert); + m_aRecentCharView[i].setMouseClickHdl(rMouseClickHdl); + m_aRecentCharView[i].setClearClickHdl(LINK(this, SfxCharmapContainer, RecentClearClickHdl)); + m_aRecentCharView[i].setClearAllClickHdl(LINK(this, SfxCharmapContainer, RecentClearAllClickHdl)); + m_aFavCharView[i].SetHasInsert(bHasInsert); + m_aFavCharView[i].setMouseClickHdl(rMouseClickHdl); + m_aFavCharView[i].setClearClickHdl(LINK(this, SfxCharmapContainer, FavClearClickHdl)); + m_aFavCharView[i].setClearAllClickHdl(LINK(this, SfxCharmapContainer, FavClearAllClickHdl)); + } +} + SfxCharmapCtrl::SfxCharmapCtrl(CharmapPopup* pControl, weld::Widget* pParent) : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "sfx/ui/charmapcontrol.ui", "charmapctrl") , m_xControl(pControl) , m_xVirDev(VclPtr<VirtualDevice>::Create()) - , m_aRecentCharView{SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev)} - , m_aFavCharView{SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev), - SvxCharView(m_xVirDev)} + , m_aCharmapContents(*m_xBuilder, m_xVirDev) , m_xRecentLabel(m_xBuilder->weld_label("label2")) , m_xDlgBtn(m_xBuilder->weld_button("specialchardlg")) - , m_xRecentCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar1", m_aRecentCharView[0]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar2", m_aRecentCharView[1]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar3", m_aRecentCharView[2]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar4", m_aRecentCharView[3]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar5", m_aRecentCharView[4]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar6", m_aRecentCharView[5]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar7", m_aRecentCharView[6]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar8", m_aRecentCharView[7]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar9", m_aRecentCharView[8]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar10", m_aRecentCharView[9]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar11", m_aRecentCharView[10]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar12", m_aRecentCharView[11]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar13", m_aRecentCharView[12]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar14", m_aRecentCharView[13]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar15", m_aRecentCharView[14]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar16", m_aRecentCharView[15])} - , m_xFavCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar1", m_aFavCharView[0]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar2", m_aFavCharView[1]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar3", m_aFavCharView[2]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar4", m_aFavCharView[3]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar5", m_aFavCharView[4]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar6", m_aFavCharView[5]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar7", m_aFavCharView[6]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar8", m_aFavCharView[7]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar9", m_aFavCharView[8]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar10", m_aFavCharView[9]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar11", m_aFavCharView[10]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar12", m_aFavCharView[11]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar13", m_aFavCharView[12]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar14", m_aFavCharView[13]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar15", m_aFavCharView[14]), - std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar16", m_aFavCharView[15])} { - for(int i = 0; i < 16; i++) - { - m_aRecentCharView[i].setMouseClickHdl(LINK(this,SfxCharmapCtrl, CharClickHdl)); - m_aFavCharView[i].setMouseClickHdl(LINK(this,SfxCharmapCtrl, CharClickHdl)); - } + m_aCharmapContents.init(false, LINK(this, SfxCharmapCtrl, CharClickHdl), + Link<void*,void>(), LINK(this, SfxCharmapCtrl, UpdateRecentHdl)); m_xDlgBtn->connect_clicked(LINK(this, SfxCharmapCtrl, OpenDlgHdl)); - - getRecentCharacterList(); - updateRecentCharControl(); - getFavCharacterList(); - updateFavCharControl(); } SfxCharmapCtrl::~SfxCharmapCtrl() { } -void SfxCharmapCtrl::getFavCharacterList() +void SfxCharmapContainer::getFavCharacterList() { + m_aFavCharList.clear(); + m_aFavCharFontList.clear(); + //retrieve recent character list const css::uno::Sequence< OUString > rFavCharList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::get() ); m_aFavCharList.insert( m_aFavCharList.end(), rFavCharList.begin(), rFavCharList.end() ); @@ -132,7 +162,7 @@ void SfxCharmapCtrl::getFavCharacterList() m_aFavCharFontList.resize(nCommonLength); } -void SfxCharmapCtrl::updateFavCharControl() +void SfxCharmapContainer::updateFavCharControl() { assert(m_aFavCharList.size() == m_aFavCharFontList.size()); @@ -153,10 +183,15 @@ void SfxCharmapCtrl::updateFavCharControl() m_aFavCharView[i].SetText(OUString()); m_aFavCharView[i].Hide(); } + + m_aUpdateFavHdl.Call(nullptr); } -void SfxCharmapCtrl::getRecentCharacterList() +void SfxCharmapContainer::getRecentCharacterList() { + m_aRecentCharList.clear(); + m_aRecentCharFontList.clear(); + //retrieve recent character list const css::uno::Sequence< OUString > rRecentCharList( officecfg::Office::Common::RecentCharacters::RecentCharacterList::get() ); m_aRecentCharList.insert( m_aRecentCharList.end(), rRecentCharList.begin(), rRecentCharList.end() ); @@ -171,9 +206,66 @@ void SfxCharmapCtrl::getRecentCharacterList() m_aRecentCharFontList.resize(nCommonLength); } -void SfxCharmapCtrl::updateRecentCharControl() +IMPL_LINK(SfxCharmapCtrl, CharClickHdl, SvxCharView*, pView, void) +{ + m_xControl->EndPopupMode(); + + pView->InsertCharToDoc(); +} + +IMPL_LINK_NOARG(SfxCharmapCtrl, OpenDlgHdl, weld::Button&, void) +{ + m_xControl->EndPopupMode(); + + if (SfxViewFrame* pViewFrm = SfxViewFrame::Current()) + { + uno::Reference<frame::XFrame> xFrame = pViewFrm->GetFrame().GetFrameInterface(); + comphelper::dispatchCommand(".uno:InsertSymbol", xFrame, {}); + } +} + +void SfxCharmapCtrl::GrabFocus() +{ + m_aCharmapContents.GrabFocusToFirstFavorite(); +} + +void SfxCharmapContainer::GrabFocusToFirstFavorite() +{ + m_aFavCharView[0].GrabFocus(); +} + +static std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> +findInPair(std::u16string_view str1, const std::deque<OUString>& rContainer1, + std::u16string_view str2, const std::deque<OUString>& rContainer2) +{ + assert(rContainer1.size() == rContainer2.size()); + + for (auto it1 = std::find(rContainer1.begin(), rContainer1.end(), str1); + it1 != rContainer1.end(); it1 = std::find(std::next(it1), rContainer1.end(), str1)) + { + auto it2 = rContainer2.begin() + (it1 - rContainer1.begin()); + if (*it2 == str2) + return { it1, it2 }; + } + return { rContainer1.end(), rContainer2.end() }; +} + +std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> +SfxCharmapContainer::getRecentChar(std::u16string_view sTitle, std::u16string_view rFont) const +{ + return findInPair(sTitle, m_aRecentCharList, rFont, m_aRecentCharFontList); +} + +std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator> +SfxCharmapContainer::getFavChar(std::u16string_view sTitle, std::u16string_view rFont) const +{ + return findInPair(sTitle, m_aFavCharList, rFont, m_aFavCharFontList); +} + +void SfxCharmapContainer::updateRecentCharControl() { assert(m_aRecentCharList.size() == m_aRecentCharFontList.size()); + int i = 0; for ( std::deque< OUString >::iterator it = m_aRecentCharList.begin(), it2 = m_aRecentCharFontList.begin(); it != m_aRecentCharList.end() && it2 != m_aRecentCharFontList.end(); @@ -192,31 +284,199 @@ void SfxCharmapCtrl::updateRecentCharControl() m_aRecentCharView[i].Hide(); } - //checking if the characters are recently used or no - m_xRecentLabel->set_label(m_aRecentCharList.size() > 0 ? SfxResId(STR_RECENT) : SfxResId(STR_NORECENT)); + m_aUpdateRecentHdl.Call(nullptr); } -IMPL_LINK(SfxCharmapCtrl, CharClickHdl, SvxCharView*, pView, void) +void SfxCharmapContainer::updateRecentCharacterList(const OUString& sTitle, const OUString& rFont) { - m_xControl->EndPopupMode(); + // if recent char to be added is already in list, remove it + if( const auto& [itChar, itChar2] = getRecentChar(sTitle, rFont); + itChar != m_aRecentCharList.end() && itChar2 != m_aRecentCharFontList.end() ) + { + m_aRecentCharList.erase( itChar ); + m_aRecentCharFontList.erase( itChar2); + } - pView->InsertCharToDoc(); + if (m_aRecentCharList.size() == 16) + { + m_aRecentCharList.pop_back(); + m_aRecentCharFontList.pop_back(); + } + + m_aRecentCharList.push_front(sTitle); + m_aRecentCharFontList.push_front(rFont); + + css::uno::Sequence< OUString > aRecentCharList(m_aRecentCharList.size()); + auto aRecentCharListRange = asNonConstRange(aRecentCharList); + css::uno::Sequence< OUString > aRecentCharFontList(m_aRecentCharFontList.size()); + auto aRecentCharFontListRange = asNonConstRange(aRecentCharFontList); + + for (size_t i = 0; i < m_aRecentCharList.size(); ++i) + { + aRecentCharListRange[i] = m_aRecentCharList[i]; + aRecentCharFontListRange[i] = m_aRecentCharFontList[i]; + } + + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch); + officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch); + batch->commit(); + + updateRecentCharControl(); } -IMPL_LINK_NOARG(SfxCharmapCtrl, OpenDlgHdl, weld::Button&, void) +void SfxCharmapContainer::updateFavCharacterList(const OUString& sTitle, const OUString& rFont) { - m_xControl->EndPopupMode(); + // if Fav char to be added is already in list, remove it + if( const auto& [itChar, itChar2] = getFavChar(sTitle, rFont); + itChar != m_aFavCharList.end() && itChar2 != m_aFavCharFontList.end() ) + { + m_aFavCharList.erase( itChar ); + m_aFavCharFontList.erase( itChar2); + } - if (SfxViewFrame* pViewFrm = SfxViewFrame::Current()) + if (m_aFavCharList.size() == 16) { - uno::Reference<frame::XFrame> xFrame = pViewFrm->GetFrame().GetFrameInterface(); - comphelper::dispatchCommand(".uno:InsertSymbol", xFrame, {}); + m_aFavCharList.pop_back(); + m_aFavCharFontList.pop_back(); + } + + m_aFavCharList.push_back(sTitle); + m_aFavCharFontList.push_back(rFont); + + css::uno::Sequence< OUString > aFavCharList(m_aFavCharList.size()); + auto aFavCharListRange = asNonConstRange(aFavCharList); + css::uno::Sequence< OUString > aFavCharFontList(m_aFavCharFontList.size()); + auto aFavCharFontListRange = asNonConstRange(aFavCharFontList); + + for (size_t i = 0; i < m_aFavCharList.size(); ++i) + { + aFavCharListRange[i] = m_aFavCharList[i]; + aFavCharFontListRange[i] = m_aFavCharFontList[i]; } + + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch); + officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch); + batch->commit(); } -void SfxCharmapCtrl::GrabFocus() +void SfxCharmapContainer::deleteFavCharacterFromList(std::u16string_view sTitle, std::u16string_view rFont) { - m_aFavCharView[0].GrabFocus(); + // if Fav char is found, remove it + if( const auto& [itChar, itChar2] = getFavChar(sTitle, rFont); + itChar != m_aFavCharList.end() && itChar2 != m_aFavCharFontList.end() ) + { + m_aFavCharList.erase( itChar ); + m_aFavCharFontList.erase( itChar2); + } + + css::uno::Sequence< OUString > aFavCharList(m_aFavCharList.size()); + auto aFavCharListRange = asNonConstRange(aFavCharList); + css::uno::Sequence< OUString > aFavCharFontList(m_aFavCharFontList.size()); + auto aFavCharFontListRange = asNonConstRange(aFavCharFontList); + + for (size_t i = 0; i < m_aFavCharList.size(); ++i) + { + aFavCharListRange[i] = m_aFavCharList[i]; + aFavCharFontListRange[i] = m_aFavCharFontList[i]; + } + + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch); + officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch); + batch->commit(); +} + +bool SfxCharmapContainer::isFavChar(std::u16string_view sTitle, std::u16string_view rFont) +{ + const auto& [itChar, itFont] = getFavChar(sTitle, rFont); + return itChar != m_aFavCharList.end() && itFont != m_aFavCharFontList.end(); +} + +IMPL_LINK(SfxCharmapContainer, CharClickHdl, SvxCharView*, pView, void) +{ + m_aMouseClickHdl.Call(pView); +} + +IMPL_LINK(SfxCharmapContainer, RecentClearClickHdl, SvxCharView*, rView, void) +{ + const OUString& sTitle = rView->GetText(); + OUString sFont = rView->GetFont().GetFamilyName(); + + // if recent char to be added is already in list, remove it + if( const auto& [itChar, itChar2] = getRecentChar(sTitle, sFont); + itChar != m_aRecentCharList.end() && itChar2 != m_aRecentCharFontList.end() ) + { + m_aRecentCharList.erase( itChar ); + m_aRecentCharFontList.erase( itChar2); + } + + css::uno::Sequence< OUString > aRecentCharList(m_aRecentCharList.size()); + auto aRecentCharListRange = asNonConstRange(aRecentCharList); + css::uno::Sequence< OUString > aRecentCharFontList(m_aRecentCharFontList.size()); + auto aRecentCharFontListRange = asNonConstRange(aRecentCharFontList); + + for (size_t i = 0; i < m_aRecentCharList.size(); ++i) + { + aRecentCharListRange[i] = m_aRecentCharList[i]; + aRecentCharFontListRange[i] = m_aRecentCharFontList[i]; + } + + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch); + officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch); + batch->commit(); + + updateRecentCharControl(); +} + +IMPL_LINK_NOARG(SfxCharmapContainer, RecentClearAllClickHdl, SvxCharView*, void) +{ + m_aRecentCharList.clear(); + m_aRecentCharFontList.clear(); + + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::RecentCharacters::RecentCharacterList::set({ }, batch); + officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set({ }, batch); + batch->commit(); + + updateRecentCharControl(); +} + +IMPL_LINK(SfxCharmapContainer, FavClearClickHdl, SvxCharView*, rView, void) +{ + deleteFavCharacterFromList(rView->GetText(), rView->GetFont().GetFamilyName()); + updateFavCharControl(); +} + +IMPL_LINK_NOARG(SfxCharmapContainer, FavClearAllClickHdl, SvxCharView*, void) +{ + m_aFavCharList.clear(); + m_aFavCharFontList.clear(); + + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set({ }, batch); + officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set({ }, batch); + batch->commit(); + + updateFavCharControl(); +} + +bool SfxCharmapContainer::FavCharListIsFull() const +{ + return m_aFavCharList.size() == 16; +} + +bool SfxCharmapContainer::hasRecentChars() const +{ + return !m_aRecentCharList.empty(); +} + +IMPL_LINK_NOARG(SfxCharmapCtrl, UpdateRecentHdl, void*, void) +{ + //checking if the characters are recently used or no + m_xRecentLabel->set_label(m_aCharmapContents.hasRecentChars() ? SfxResId(STR_RECENT) : SfxResId(STR_NORECENT)); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/uiconfig/ui/charmapcontrol.ui b/sfx2/uiconfig/ui/charmapcontrol.ui index f1d0128b7f7f..28a080a88433 100644 --- a/sfx2/uiconfig/ui/charmapcontrol.ui +++ b/sfx2/uiconfig/ui/charmapcontrol.ui @@ -27,7 +27,7 @@ </child> <child> <!-- n-columns=1 n-rows=1 --> - <object class="GtkGrid" id="grid1"> + <object class="GtkGrid" id="favgrid"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="halign">start</property> @@ -268,7 +268,7 @@ </child> <child> <!-- n-columns=1 n-rows=1 --> - <object class="GtkGrid" id="grid2"> + <object class="GtkGrid" id="viewgrid"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="halign">start</property>