LibreOffice Module cui (master)  1
cuicharmap.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <stdio.h>
21 
22 #include <vcl/svapp.hxx>
23 #include <svl/eitem.hxx>
24 #include <svl/intitem.hxx>
25 #include <svl/itempool.hxx>
26 
27 #include <rtl/textenc.h>
28 #include <svx/ucsubset.hxx>
29 #include <vcl/settings.hxx>
30 #include <vcl/fontcharmap.hxx>
31 #include <vcl/virdev.hxx>
32 #include <svl/stritem.hxx>
33 #include <officecfg/Office/Common.hxx>
34 #include <com/sun/star/beans/PropertyValue.hpp>
37 
38 #include <dialmgr.hxx>
39 #include <cui/cuicharmap.hxx>
40 #include <sfx2/app.hxx>
41 #include <svx/svxids.hrc>
42 #include <editeng/editids.hrc>
43 #include <editeng/fontitem.hxx>
44 #include <strings.hrc>
45 #include <unicode/uchar.h>
46 #include <unicode/utypes.h>
47 
48 using namespace css;
49 
51  const css::uno::Reference<css::frame::XFrame>& rFrame)
52  : SfxDialogController(pParent, "cui/ui/specialcharacters.ui", "SpecialCharactersDialog")
53  , m_xVirDev(VclPtr<VirtualDevice>::Create())
54  , isSearchMode(true)
55  , m_xFrame(rFrame)
57  , m_aRecentCharView{SvxCharView(m_xVirDev),
73  , m_aFavCharView{SvxCharView(m_xVirDev),
74  SvxCharView(m_xVirDev),
75  SvxCharView(m_xVirDev),
76  SvxCharView(m_xVirDev),
77  SvxCharView(m_xVirDev),
78  SvxCharView(m_xVirDev),
79  SvxCharView(m_xVirDev),
80  SvxCharView(m_xVirDev),
81  SvxCharView(m_xVirDev),
82  SvxCharView(m_xVirDev),
83  SvxCharView(m_xVirDev),
84  SvxCharView(m_xVirDev),
85  SvxCharView(m_xVirDev),
86  SvxCharView(m_xVirDev),
87  SvxCharView(m_xVirDev),
88  SvxCharView(m_xVirDev)}
89  , m_aShowChar(m_xVirDev)
90  , m_xOKBtn(m_xFrame.is() ? m_xBuilder->weld_button("insert") : m_xBuilder->weld_button("ok"))
91  , m_xFontText(m_xBuilder->weld_label("fontft"))
92  , m_xFontLB(m_xBuilder->weld_combo_box("fontlb"))
93  , m_xSubsetText(m_xBuilder->weld_label("subsetft"))
94  , m_xSubsetLB(m_xBuilder->weld_combo_box("subsetlb"))
95  , m_xSearchText(m_xBuilder->weld_entry("search"))
96  , m_xHexCodeText(m_xBuilder->weld_entry("hexvalue"))
97  , m_xDecimalCodeText(m_xBuilder->weld_entry("decimalvalue"))
98  , m_xFavouritesBtn(m_xBuilder->weld_button("favbtn"))
99  , m_xCharName(m_xBuilder->weld_label("charname"))
100  , m_xRecentGrid(m_xBuilder->weld_widget("viewgrid"))
101  , m_xFavGrid(m_xBuilder->weld_widget("favgrid"))
102  , m_xShowChar(new weld::CustomWeld(*m_xBuilder, "showchar", m_aShowChar))
103  , m_xRecentCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar1", m_aRecentCharView[0]),
104  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar2", m_aRecentCharView[1]),
105  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar3", m_aRecentCharView[2]),
106  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar4", m_aRecentCharView[3]),
107  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar5", m_aRecentCharView[4]),
108  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar6", m_aRecentCharView[5]),
109  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar7", m_aRecentCharView[6]),
110  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar8", m_aRecentCharView[7]),
111  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar9", m_aRecentCharView[8]),
112  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar10", m_aRecentCharView[9]),
113  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar11", m_aRecentCharView[10]),
114  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar12", m_aRecentCharView[11]),
115  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar13", m_aRecentCharView[12]),
116  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar14", m_aRecentCharView[13]),
117  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar15", m_aRecentCharView[14]),
118  std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar16", m_aRecentCharView[15])}
119  , m_xFavCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar1", m_aFavCharView[0]),
120  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar2", m_aFavCharView[1]),
121  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar3", m_aFavCharView[2]),
122  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar4", m_aFavCharView[3]),
123  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar5", m_aFavCharView[4]),
124  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar6", m_aFavCharView[5]),
125  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar7", m_aFavCharView[6]),
126  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar8", m_aFavCharView[7]),
127  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar9", m_aFavCharView[8]),
128  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar10", m_aFavCharView[9]),
129  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar11", m_aFavCharView[10]),
130  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar12", m_aFavCharView[11]),
131  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar13", m_aFavCharView[12]),
132  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar14", m_aFavCharView[13]),
133  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar15", m_aFavCharView[14]),
134  std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar16", m_aFavCharView[15])}
135  , m_xShowSet(new SvxShowCharSet(m_xBuilder->weld_scrolled_window("showscroll"), m_xVirDev))
136  , m_xShowSetArea(new weld::CustomWeld(*m_xBuilder, "showcharset", *m_xShowSet))
137  , m_xSearchSet(new SvxSearchCharSet(m_xBuilder->weld_scrolled_window("searchscroll"), m_xVirDev))
138  , m_xSearchSetArea(new weld::CustomWeld(*m_xBuilder, "searchcharset", *m_xSearchSet))
139 {
140  m_aShowChar.SetCentered(true);
141  m_xFontLB->make_sorted();
142  //lock the size request of this widget to the width of all possible entries
143  fillAllSubsets(*m_xSubsetLB);
144  m_xSubsetLB->set_size_request(m_xSubsetLB->get_preferred_size().Width(), -1);
145  m_xCharName->set_size_request(m_aShowChar.get_preferred_size().Width(), m_xCharName->get_text_height() * 4);
146  //lock the size request of this widget to the width of the original .ui string
147  m_xHexCodeText->set_size_request(m_xHexCodeText->get_preferred_size().Width(), -1);
148  //so things don't jump around if all the children are hidden
149  m_xRecentGrid->set_size_request(-1, m_aRecentCharView[0].get_preferred_size().Height());
150  m_xFavGrid->set_size_request(-1, m_aFavCharView[0].get_preferred_size().Height());
151 
152  init();
153 
154  const SfxInt32Item* pCharItem = SfxItemSet::GetItem<SfxInt32Item>(pSet, SID_ATTR_CHAR, false);
155  if ( pCharItem )
156  SetChar( pCharItem->GetValue() );
157 
158  const SfxBoolItem* pDisableItem = SfxItemSet::GetItem<SfxBoolItem>(pSet, FN_PARAM_2, false);
159  if ( pDisableItem && pDisableItem->GetValue() )
160  DisableFontSelection();
161 
162  const SvxFontItem* pFontItem = SfxItemSet::GetItem<SvxFontItem>(pSet, SID_ATTR_CHAR_FONT, false);
163  const SfxStringItem* pFontNameItem = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_FONT_NAME, false);
164  if ( pFontItem )
165  {
166  vcl::Font aTmpFont( pFontItem->GetFamilyName(), pFontItem->GetStyleName(), GetCharFont().GetFontSize() );
167  aTmpFont.SetCharSet( pFontItem->GetCharSet() );
168  aTmpFont.SetPitch( pFontItem->GetPitch() );
169  SetCharFont( aTmpFont );
170  }
171  else if ( pFontNameItem )
172  {
173  vcl::Font aTmpFont( GetCharFont() );
174  aTmpFont.SetFamilyName( pFontNameItem->GetValue() );
175  SetCharFont( aTmpFont );
176  }
177 
178  m_xOutputSet.reset(new SfxAllItemSet(pSet ? *pSet->GetPool() : SfxGetpApp()->GetPool()));
179  m_xShowSet->Show();
180  m_xSearchSet->Hide();
181 }
182 
184 {
185  if( SvxShowCharSet::getSelectedChar() == ' ')
186  {
187  m_xOKBtn->set_sensitive(false);
188  setFavButtonState(OUString(), OUString());
189  }
190  else
191  {
192  sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
193  // using the new UCS4 constructor
194  OUString aOUStr( &cChar, 1 );
195  m_aShowChar.SetText(aOUStr);
196 
198  m_xOKBtn->set_sensitive(true);
199  }
200 
201  return SfxDialogController::run();
202 }
203 
205 {
206  m_xShowSet->SelectCharacter( c );
207  setFavButtonState(OUString(&c, 1), aFont.GetFamilyName());
208 }
209 
211 {
212  return m_aShowChar.GetText().toChar();
213 }
214 
216 {
217  m_xFontText->set_sensitive(false);
218  m_xFontLB->set_sensitive(false);
219 }
220 
221 
223 {
224  //retrieve recent character list
225  const css::uno::Sequence< OUString > rRecentCharList( officecfg::Office::Common::RecentCharacters::RecentCharacterList::get() );
226  for (OUString const & s : rRecentCharList)
227  {
228  maRecentCharList.push_back(s);
229  }
230 
231  //retrieve recent character font list
232  const css::uno::Sequence< OUString > rRecentCharFontList( officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::get() );
233  for (OUString const & s : rRecentCharFontList)
234  {
235  maRecentCharFontList.push_back(s);
236  }
237 }
238 
239 
241 {
242  maFavCharList.clear();
243  maFavCharFontList.clear();
244  //retrieve recent character list
245  const css::uno::Sequence< OUString > rFavCharList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::get() );
246  for (const OUString& s : rFavCharList)
247  {
248  maFavCharList.push_back(s);
249  }
250 
251  //retrieve recent character font list
252  const css::uno::Sequence< OUString > rFavCharFontList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::get() );
253  for (const OUString& s : rFavCharFontList)
254  {
255  maFavCharFontList.push_back(s);
256  }
257 }
258 
259 
261 {
262  int i = 0;
263  for ( std::deque< OUString >::iterator it = maRecentCharList.begin(), it2 = maRecentCharFontList.begin();
264  it != maRecentCharList.end() || it2 != maRecentCharFontList.end();
265  ++it, ++it2, i++)
266  {
267  m_aRecentCharView[i].SetText(*it);
268  vcl::Font rFont = m_aRecentCharView[i].GetFont();
269  rFont.SetFamilyName( *it2 );
270  m_aRecentCharView[i].SetFont(rFont);
271  m_aRecentCharView[i].Show();
272  }
273 
274  for(; i < 16 ; i++)
275  {
276  m_aRecentCharView[i].SetText(OUString());
277  m_aRecentCharView[i].Hide();
278  }
279 }
280 
281 void SvxCharacterMap::updateRecentCharacterList(const OUString& sTitle, const OUString& rFont)
282 {
283  auto itChar = std::find(maRecentCharList.begin(), maRecentCharList.end(), sTitle);
284 
285  auto itChar2 = std::find(maRecentCharFontList.begin(), maRecentCharFontList.end(), rFont);
286 
287  // if recent char to be added is already in list, remove it
288  if( itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() )
289  {
290  maRecentCharList.erase( itChar );
291  maRecentCharFontList.erase( itChar2);
292  }
293 
294  if (maRecentCharList.size() == 16)
295  {
296  maRecentCharList.pop_back();
297  maRecentCharFontList.pop_back();
298  }
299 
300  maRecentCharList.push_front(sTitle);
301  maRecentCharFontList.push_front(rFont);
302 
303  css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size());
304  css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size());
305 
306  for (size_t i = 0; i < maRecentCharList.size(); ++i)
307  {
308  aRecentCharList[i] = maRecentCharList[i];
309  aRecentCharFontList[i] = maRecentCharFontList[i];
310  }
311 
312  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
313  officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch);
314  officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch);
315  batch->commit();
316 
318 }
319 
320 
321 void SvxCharacterMap::updateFavCharacterList(const OUString& sTitle, const OUString& rFont)
322 {
323  auto itChar = std::find(maFavCharList.begin(), maFavCharList.end(), sTitle);
324 
325  auto itChar2 = std::find(maFavCharFontList.begin(), maFavCharFontList.end(), rFont);
326 
327  // if Fav char to be added is already in list, remove it
328  if( itChar != maFavCharList.end() && itChar2 != maFavCharFontList.end() )
329  {
330  maFavCharList.erase( itChar );
331  maFavCharFontList.erase( itChar2);
332  }
333 
334  if (maFavCharList.size() == 16)
335  {
336  maFavCharList.pop_back();
337  maFavCharFontList.pop_back();
338  }
339 
340  maFavCharList.push_back(sTitle);
341  maFavCharFontList.push_back(rFont);
342 
343  css::uno::Sequence< OUString > aFavCharList(maFavCharList.size());
344  css::uno::Sequence< OUString > aFavCharFontList(maFavCharFontList.size());
345 
346  for (size_t i = 0; i < maFavCharList.size(); ++i)
347  {
348  aFavCharList[i] = maFavCharList[i];
349  aFavCharFontList[i] = maFavCharFontList[i];
350  }
351 
352  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
353  officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch);
354  officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch);
355  batch->commit();
356 }
357 
358 
360 {
361  int i = 0;
362  for ( std::deque< OUString >::iterator it = maFavCharList.begin(), it2 = maFavCharFontList.begin();
363  it != maFavCharList.end() || it2 != maFavCharFontList.end();
364  ++it, ++it2, i++)
365  {
366  m_aFavCharView[i].SetText(*it);
367  vcl::Font rFont = m_aFavCharView[i].GetFont();
368  rFont.SetFamilyName( *it2 );
369  m_aFavCharView[i].SetFont(rFont);
370  m_aFavCharView[i].Show();
371  }
372 
373  for(; i < 16 ; i++)
374  {
375  m_aFavCharView[i].SetText(OUString());
376  m_aFavCharView[i].Hide();
377  }
378  m_xShowSet->getFavCharacterList();
379  m_xSearchSet->getFavCharacterList();
380 }
381 
382 void SvxCharacterMap::deleteFavCharacterFromList(const OUString& sTitle, const OUString& rFont)
383 {
384  auto itChar = std::find(maFavCharList.begin(), maFavCharList.end(), sTitle);
385 
386  auto itChar2 = std::find(maFavCharFontList.begin(), maFavCharFontList.end(), rFont);
387 
388  // if Fav char to be added is already in list, remove it
389  if( itChar != maFavCharList.end() && itChar2 != maFavCharFontList.end() )
390  {
391  maFavCharList.erase( itChar );
392  maFavCharFontList.erase( itChar2);
393  }
394 
395  css::uno::Sequence< OUString > aFavCharList(maFavCharList.size());
396  css::uno::Sequence< OUString > aFavCharFontList(maFavCharFontList.size());
397 
398  for (size_t i = 0; i < maFavCharList.size(); ++i)
399  {
400  aFavCharList[i] = maFavCharList[i];
401  aFavCharFontList[i] = maFavCharFontList[i];
402  }
403 
404  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
405  officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch);
406  officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch);
407  batch->commit();
408 }
409 
411 {
412  aFont = m_xVirDev->GetFont();
413  aFont.SetTransparent( true );
416  aFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
417 
418  OUString aDefStr( aFont.GetFamilyName() );
419  OUString aLastName;
420  int nCount = m_xVirDev->GetDevFontCount();
421  std::vector<weld::ComboBoxEntry> aEntries;
422  aEntries.reserve(nCount);
423  for (int i = 0; i < nCount; ++i)
424  {
425  OUString aFontName( m_xVirDev->GetDevFont( i ).GetFamilyName() );
426  if (aFontName != aLastName)
427  {
428  aLastName = aFontName;
429  aEntries.emplace_back(aFontName, OUString::number(i));
430  }
431  }
432  m_xFontLB->insert_vector(aEntries, true);
433  // the font may not be in the list =>
434  // try to find a font name token in list and select found font,
435  // else select topmost entry
436  bool bFound = (m_xFontLB->find_text(aDefStr) == -1);
437  if (!bFound)
438  {
439  sal_Int32 nIndex = 0;
440  do
441  {
442  OUString aToken = aDefStr.getToken(0, ';', nIndex);
443  if (m_xFontLB->find_text(aToken) != -1)
444  {
445  aDefStr = aToken;
446  bFound = true;
447  break;
448  }
449  }
450  while ( nIndex >= 0 );
451  }
452 
453  if (bFound)
454  m_xFontLB->set_active_text(aDefStr);
455  else if (m_xFontLB->get_count() )
456  m_xFontLB->set_active(0);
457  FontSelectHdl(*m_xFontLB);
458  if (m_xSubsetLB->get_count())
459  m_xSubsetLB->set_active(0);
460 
461  m_xFontLB->connect_changed(LINK( this, SvxCharacterMap, FontSelectHdl));
462  m_xSubsetLB->connect_changed(LINK( this, SvxCharacterMap, SubsetSelectHdl));
463  m_xOKBtn->connect_clicked(LINK(this, SvxCharacterMap, InsertClickHdl));
464  m_xOKBtn->show();
465 
466  m_xShowSet->SetDoubleClickHdl( LINK( this, SvxCharacterMap, CharDoubleClickHdl ) );
467  m_xShowSet->SetSelectHdl( LINK( this, SvxCharacterMap, CharSelectHdl ) );
468  m_xShowSet->SetHighlightHdl( LINK( this, SvxCharacterMap, CharHighlightHdl ) );
469  m_xShowSet->SetPreSelectHdl( LINK( this, SvxCharacterMap, CharPreSelectHdl ) );
470  m_xShowSet->SetFavClickHdl( LINK( this, SvxCharacterMap, FavClickHdl ) );
471 
472  m_xSearchSet->SetDoubleClickHdl( LINK( this, SvxCharacterMap, SearchCharDoubleClickHdl ) );
473  m_xSearchSet->SetSelectHdl( LINK( this, SvxCharacterMap, SearchCharSelectHdl ) );
474  m_xSearchSet->SetHighlightHdl( LINK( this, SvxCharacterMap, SearchCharHighlightHdl ) );
475  m_xSearchSet->SetPreSelectHdl( LINK( this, SvxCharacterMap, SearchCharPreSelectHdl ) );
476  m_xSearchSet->SetFavClickHdl( LINK( this, SvxCharacterMap, FavClickHdl ) );
477 
478  m_xDecimalCodeText->connect_changed( LINK( this, SvxCharacterMap, DecimalCodeChangeHdl ) );
479  m_xHexCodeText->connect_changed( LINK( this, SvxCharacterMap, HexCodeChangeHdl ) );
480  m_xFavouritesBtn->connect_clicked( LINK(this, SvxCharacterMap, FavSelectHdl));
481 
482  // tdf#117038 set the buttons width to its max possible width so it doesn't
483  // make layout change when the label changes
484  m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_REMOVE_FAVORITES));
485  auto nMaxWidth = m_xFavouritesBtn->get_preferred_size().Width();
486  m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES));
487  nMaxWidth = std::max(nMaxWidth, m_xFavouritesBtn->get_preferred_size().Width());
488  m_xFavouritesBtn->set_size_request(nMaxWidth, -1);
489 
490  if( SvxShowCharSet::getSelectedChar() == ' ')
491  {
492  m_xOKBtn->set_sensitive(false);
493  }
494  else
495  {
496  sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
497  // using the new UCS4 constructor
498  OUString aOUStr( &cChar, 1 );
499  m_aShowChar.SetText(aOUStr);
500 
501  setFavButtonState(aOUStr, aDefStr);
502  m_xOKBtn->set_sensitive(true);
503  }
504 
507 
510 
511  bool bHasInsert = m_xFrame.is();
512 
513  for(int i = 0; i < 16; i++)
514  {
515  m_aRecentCharView[i].SetHasInsert(bHasInsert);
517  m_aRecentCharView[i].setClearClickHdl(LINK(this,SvxCharacterMap, RecentClearClickHdl));
518  m_aRecentCharView[i].setClearAllClickHdl(LINK(this,SvxCharacterMap, RecentClearAllClickHdl));
519  m_aFavCharView[i].SetHasInsert(bHasInsert);
520  m_aFavCharView[i].setMouseClickHdl(LINK(this,SvxCharacterMap, CharClickHdl));
521  m_aFavCharView[i].setClearClickHdl(LINK(this,SvxCharacterMap, FavClearClickHdl));
522  m_aFavCharView[i].setClearAllClickHdl(LINK(this,SvxCharacterMap, FavClearAllClickHdl));
523  }
524 
525  setCharName(90);
526 
527  m_xSearchText->connect_focus_in(LINK( this, SvxCharacterMap, SearchFieldGetFocusHdl ));
528  m_xSearchText->connect_changed(LINK(this, SvxCharacterMap, SearchUpdateHdl));
529 }
530 
531 bool SvxCharacterMap::isFavChar(const OUString& sTitle, const OUString& rFont)
532 {
533  auto isFavCharTitleExists = std::any_of(maFavCharList.begin(),
534  maFavCharList.end(),
535  [sTitle] (const OUString & a) { return a == sTitle; });
536 
537  auto isFavCharFontExists = std::any_of(maFavCharFontList.begin(),
538  maFavCharFontList.end(),
539  [rFont] (const OUString & a) { return a == rFont; });
540 
541  // if Fav char to be added is already in list, remove it
542  return isFavCharTitleExists && isFavCharFontExists;
543 }
544 
545 
546 void SvxCharacterMap::setFavButtonState(const OUString& sTitle, const OUString& rFont)
547 {
548  if(sTitle.isEmpty() || rFont.isEmpty())
549  {
550  m_xFavouritesBtn->set_sensitive(false);
551  return;
552  }
553  else
554  m_xFavouritesBtn->set_sensitive(true);
555 
556  if (isFavChar(sTitle, rFont))
557  {
558  m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_REMOVE_FAVORITES));
559  }
560  else
561  {
562  if(maFavCharList.size() == 16)
563  {
564  m_xFavouritesBtn->set_sensitive(false);
565  }
566 
567  m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES));
568  }
569 }
570 
571 
573 {
574  // first get the underlying info in order to get font names
575  // like "Times New Roman;Times" resolved
576  vcl::Font aTmp(m_xVirDev->GetFontMetric(rFont));
577 
578  if (aTmp.GetFamilyName() == "StarSymbol" && m_xFontLB->find_text(aTmp.GetFamilyName()) == -1)
579  {
580  //if for some reason, like font in an old document, StarSymbol is requested and it's not available, then
581  //try OpenSymbol instead
582  aTmp.SetFamilyName("OpenSymbol");
583  }
584 
585  if (m_xFontLB->find_text(aTmp.GetFamilyName()) == -1)
586  return;
587 
588  m_xFontLB->set_active_text(aTmp.GetFamilyName());
589  aFont = aTmp;
590  FontSelectHdl(*m_xFontLB);
591  if (m_xSubsetLB->get_count())
592  m_xSubsetLB->set_active(0);
593 }
594 
596 {
597  SubsetMap aAll(nullptr);
598  std::vector<weld::ComboBoxEntry> aEntries;
599  for (auto & subset : aAll.GetSubsetMap())
600  aEntries.emplace_back(subset.GetName());
601  rListBox.insert_vector(aEntries, true);
602 }
603 
604 void SvxCharacterMap::insertCharToDoc(const OUString& sGlyph)
605 {
606  if(sGlyph.isEmpty())
607  return;
608 
609  if (m_xFrame.is()) {
610  uno::Sequence<beans::PropertyValue> aArgs(2);
611  aArgs[0].Name = "Symbols";
612  aArgs[0].Value <<= sGlyph;
613 
614  aArgs[1].Name = "FontName";
615  aArgs[1].Value <<= aFont.GetFamilyName();
616  comphelper::dispatchCommand(".uno:InsertSymbol", m_xFrame, aArgs);
617 
619 
620  } else {
621  sal_Int32 tmp = 0;
622  sal_UCS4 cChar = sGlyph.iterateCodePoints(&tmp);
623  const SfxItemPool* pPool = m_xOutputSet->GetPool();
624  m_xOutputSet->Put( SfxStringItem( pPool->GetWhich(SID_CHARMAP), sGlyph ) );
626  aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(), pPool->GetWhich(SID_ATTR_CHAR_FONT) ) );
627  m_xOutputSet->Put( SfxStringItem( pPool->GetWhich(SID_FONT_NAME), aFont.GetFamilyName() ) );
628  m_xOutputSet->Put( SfxInt32Item( pPool->GetWhich(SID_ATTR_CHAR), cChar ) );
629  }
630 }
631 
633 {
634  const sal_uInt32 nFont = m_xFontLB->get_active_id().toUInt32();
635  aFont = m_xVirDev->GetDevFont(nFont);
636  aFont.SetWeight( WEIGHT_DONTKNOW );
637  aFont.SetItalic( ITALIC_NONE );
638  aFont.SetWidthType( WIDTH_DONTKNOW );
639  aFont.SetPitch( PITCH_DONTKNOW );
640  aFont.SetFamily( FAMILY_DONTKNOW );
641 
642  // notify children using this font
643  m_xShowSet->SetFont( aFont );
644  m_xSearchSet->SetFont( aFont );
645  m_aShowChar.SetFont( aFont );
646  if (isSearchMode)
647  {
648  SearchUpdateHdl(*m_xSearchText);
649  SearchCharHighlightHdl(m_xSearchSet.get());
650  }
651 
652  // setup unicode subset listbar with font specific subsets,
653  // hide unicode subset listbar for symbol fonts
654  // TODO: get info from the Font once it provides it
655  pSubsetMap.reset();
656  m_xSubsetLB->clear();
657 
658  bool bNeedSubset = (aFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL);
659  if (bNeedSubset)
660  {
661  FontCharMapRef xFontCharMap = m_xShowSet->GetFontCharMap();
662  pSubsetMap.reset(new SubsetMap( xFontCharMap ));
663 
664  // update subset listbox for new font's unicode subsets
665  for (auto const& subset : pSubsetMap->GetSubsetMap())
666  {
667  m_xSubsetLB->append(OUString::number(reinterpret_cast<sal_uInt64>(&subset)), subset.GetName());
668  // NOTE: subset must live at least as long as the selected font
669  }
670 
671  if (m_xSubsetLB->get_count() <= 1)
672  bNeedSubset = false;
673  }
674 
675  m_xSubsetText->set_sensitive(bNeedSubset);
676  m_xSubsetLB->set_sensitive(bNeedSubset);
677 
678  // tdf#118304 reselect current glyph to see if its still there in new font
679  selectCharByCode(Radix::hexadecimal);
680 }
681 
683 {
684  isSearchMode = state;
685  m_xHexCodeText->set_editable(!state);
686  m_xDecimalCodeText->set_editable(!state);
687  m_xSubsetLB->set_sensitive(!state);
688 
689  if(state)
690  {
691  m_xSearchSet->Show();
692  m_xShowSet->Hide();
693  }
694  else
695  {
696  m_xSearchSet->Hide();
697  m_xShowSet->Show();
698  }
699 }
700 
702 {
703  /* get the character name */
704  UErrorCode errorCode = U_ZERO_ERROR;
705  // icu has a private uprv_getMaxCharNameLength function which returns the max possible
706  // length of this property. Unicode 3.2 max char name length was 83
707  char buffer[100];
708  u_charName(nDecimalValue, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
709  if (U_SUCCESS(errorCode))
710  m_xCharName->set_label(OUString::createFromAscii(buffer));
711 }
712 
714 {
715  const sal_Int32 nPos = m_xSubsetLB->get_active();
716  const Subset* pSubset = reinterpret_cast<const Subset*>(m_xSubsetLB->get_active_id().toUInt64());
717 
718  if( pSubset && !isSearchMode)
719  {
720  sal_UCS4 cFirst = pSubset->GetRangeMin();
721  m_xShowSet->SelectCharacter( cFirst );
722 
723  setFavButtonState(OUString(&cFirst, 1), aFont.GetFamilyName());
724  m_xSubsetLB->set_active(nPos);
725  }
726  else if( pSubset && isSearchMode)
727  {
728  m_xSearchSet->SelectCharacter( pSubset );
729 
730  const Subset* curSubset = nullptr;
731  if( pSubsetMap )
732  curSubset = pSubsetMap->GetSubsetByUnicode( m_xSearchSet->GetSelectCharacter() );
733  if( curSubset )
734  m_xSubsetLB->set_active_text(curSubset->GetName());
735  else
736  m_xSubsetLB->set_active(-1);
737 
738  sal_UCS4 sChar = m_xSearchSet->GetSelectCharacter();
739  setFavButtonState(OUString(&sChar, 1), aFont.GetFamilyName());
740  }
741 }
742 
743 IMPL_LINK(SvxCharacterMap, RecentClearClickHdl, SvxCharView*, rView, void)
744 {
745  const OUString& sTitle = rView->GetText();
746  auto itChar = std::find(maRecentCharList.begin(), maRecentCharList.end(), sTitle);
747 
748  OUString sFont = rView->GetFont().GetFamilyName();
749  auto itChar2 = std::find(maRecentCharFontList.begin(), maRecentCharFontList.end(), sFont);
750 
751  // if recent char to be added is already in list, remove it
752  if( itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() )
753  {
754  maRecentCharList.erase( itChar );
755  maRecentCharFontList.erase( itChar2);
756  }
757 
758  css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size());
759  css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size());
760 
761  for (size_t i = 0; i < maRecentCharList.size(); ++i)
762  {
763  aRecentCharList[i] = maRecentCharList[i];
764  aRecentCharFontList[i] = maRecentCharFontList[i];
765  }
766 
767  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
768  officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch);
769  officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch);
770  batch->commit();
771 
772  updateRecentCharControl();
773 }
774 
775 IMPL_LINK_NOARG(SvxCharacterMap, RecentClearAllClickHdl, SvxCharView*, void)
776 {
777  css::uno::Sequence< OUString > aRecentCharList(0);
778  css::uno::Sequence< OUString > aRecentCharFontList(0);
779 
780  maRecentCharList.clear();
781  maRecentCharFontList.clear();
782 
783  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
784  officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch);
785  officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch);
786  batch->commit();
787 
788  updateRecentCharControl();
789 }
790 
791 IMPL_LINK(SvxCharacterMap, FavClearClickHdl, SvxCharView*, rView, void)
792 {
793  deleteFavCharacterFromList(rView->GetText(), rView->GetFont().GetFamilyName());
794  updateFavCharControl();
795 }
796 
797 IMPL_LINK_NOARG(SvxCharacterMap, FavClearAllClickHdl, SvxCharView*, void)
798 {
799  css::uno::Sequence< OUString > aFavCharList(0);
800  css::uno::Sequence< OUString > aFavCharFontList(0);
801 
802  maFavCharList.clear();
803  maFavCharFontList.clear();
804 
805  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
806  officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch);
807  officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch);
808  batch->commit();
809 
810  updateFavCharControl();
811 }
812 
813 IMPL_LINK_NOARG(SvxCharacterMap, SearchFieldGetFocusHdl, weld::Widget&, void)
814 {
815  m_xOKBtn->set_sensitive(false);
816 }
817 
818 IMPL_LINK_NOARG(SvxCharacterMap, SearchUpdateHdl, weld::Entry&, void)
819 {
820  if (!m_xSearchText->get_text().isEmpty())
821  {
822  m_xSearchSet->ClearPreviousData();
823  OUString aKeyword = m_xSearchText->get_text();
824 
825  toggleSearchView(true);
826 
827  FontCharMapRef xFontCharMap = m_xSearchSet->GetFontCharMap();
828 
829  sal_UCS4 sChar = xFontCharMap->GetFirstChar();
830  while(sChar != xFontCharMap->GetLastChar())
831  {
832  UErrorCode errorCode = U_ZERO_ERROR;
833  char buffer[100];
834  u_charName(sChar, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
835  if (U_SUCCESS(errorCode))
836  {
837  OUString sName = OUString::createFromAscii(buffer);
838  if(!sName.isEmpty() && sName.toAsciiLowerCase().indexOf(aKeyword.toAsciiLowerCase()) >= 0)
839  m_xSearchSet->AppendCharToList(sChar);
840  }
841  sChar = xFontCharMap->GetNextChar(sChar);
842  }
843  //for last char
844  UErrorCode errorCode = U_ZERO_ERROR;
845  char buffer[100];
846  u_charName(sChar, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
847  if (U_SUCCESS(errorCode))
848  {
849  OUString sName = OUString::createFromAscii(buffer);
850  if(!sName.isEmpty() && sName.toAsciiLowerCase().indexOf(aKeyword.toAsciiLowerCase()) >= 0)
851  m_xSearchSet->AppendCharToList(sChar);
852  }
853  }
854  else
855  {
856  toggleSearchView(false);
857  }
858 }
859 
860 
861 IMPL_LINK(SvxCharacterMap, CharClickHdl, SvxCharView*, rView, void)
862 {
863  rView->GrabFocus();
864 
865  m_aShowChar.SetText( rView->GetText() );
866  m_aShowChar.SetFont(rView->GetFont());
867  m_aShowChar.Invalidate();
868 
869  setFavButtonState(rView->GetText(), rView->GetFont().GetFamilyName());//check state
870 
871  // Get the hexadecimal code
872  OUString charValue = rView->GetText();
873  sal_Int32 tmp = 1;
874  sal_UCS4 cChar = charValue.iterateCodePoints(&tmp, -1);
875  OUString aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
876 
877  // Get the decimal code
878  OUString aDecimalText = OUString::number(cChar);
879 
880  m_xHexCodeText->set_text(aHexText);
881  m_xDecimalCodeText->set_text(aDecimalText);
882  setCharName(cChar);
883 
884  rView->Invalidate();
885  m_xOKBtn->set_sensitive(true);
886 }
887 
888 IMPL_LINK_NOARG(SvxCharacterMap, CharDoubleClickHdl, SvxShowCharSet*, void)
889 {
890  sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
891  // using the new UCS4 constructor
892  OUString aOUStr( &cChar, 1 );
893  setFavButtonState(aOUStr, aFont.GetFamilyName());
894  insertCharToDoc(aOUStr);
895 }
896 
897 IMPL_LINK_NOARG(SvxCharacterMap, SearchCharDoubleClickHdl, SvxShowCharSet*, void)
898 {
899  sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
900  // using the new UCS4 constructor
901  OUString aOUStr( &cChar, 1 );
902  setFavButtonState(aOUStr, aFont.GetFamilyName());
903  insertCharToDoc(aOUStr);
904 }
905 
907 {
908  m_xOKBtn->set_sensitive(true);
909 }
910 
911 IMPL_LINK_NOARG(SvxCharacterMap, SearchCharSelectHdl, SvxShowCharSet*, void)
912 {
913  m_xOKBtn->set_sensitive(true);
914 }
915 
917 {
918  OUString sChar = m_aShowChar.GetText();
919  insertCharToDoc(sChar);
920  // Need to update recent character list, when OK button does not insert
921  if(!m_xFrame.is())
922  updateRecentCharacterList(sChar, aFont.GetFamilyName());
923  m_xDialog->response(RET_OK);
924 }
925 
927 {
928  if (m_xFavouritesBtn->get_label().match(CuiResId(RID_SVXSTR_ADD_FAVORITES)))
929  {
930  updateFavCharacterList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
931  setFavButtonState(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
932  }
933  else
934  {
935  deleteFavCharacterFromList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
936  m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES));
937  m_xFavouritesBtn->set_sensitive(false);
938  }
939 
940  updateFavCharControl();
941 }
942 
944 {
945  getFavCharacterList();
946  updateFavCharControl();
947 }
948 
950 {
951  OUString aText;
952  OUString aHexText;
953  OUString aDecimalText;
954  sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
955  bool bSelect = (cChar > 0);
956 
957  // show char sample
958  if ( bSelect )
959  {
960  // using the new UCS4 constructor
961  aText = OUString( &cChar, 1 );
962  // Get the hexadecimal code
963  aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
964  // Get the decimal code
965  aDecimalText = OUString::number(cChar);
966  setCharName(cChar);
967 
968  // Update the hex and decimal codes only if necessary
969  if (!m_xHexCodeText->get_text().equalsIgnoreAsciiCase(aHexText))
970  m_xHexCodeText->set_text(aHexText);
971  if (m_xDecimalCodeText->get_text() != aDecimalText)
972  m_xDecimalCodeText->set_text( aDecimalText );
973 
974  const Subset* pSubset = nullptr;
975  if( pSubsetMap )
976  pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
977  if( pSubset )
978  m_xSubsetLB->set_active_text(pSubset->GetName());
979  else
980  m_xSubsetLB->set_active(-1);
981  }
982 
983  m_aShowChar.SetText( aText );
984  m_aShowChar.SetFont( aFont );
985  m_aShowChar.Invalidate();
986 
987  setFavButtonState(aText, aFont.GetFamilyName());
988 }
989 
990 IMPL_LINK_NOARG(SvxCharacterMap, SearchCharHighlightHdl, SvxShowCharSet*, void)
991 {
992  OUString aText;
993  OUString aHexText;
994  OUString aDecimalText;
995  sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
996  bool bSelect = (cChar > 0);
997 
998  // show char sample
999  if ( bSelect )
1000  {
1001  aText = OUString( &cChar, 1 );
1002  // Get the hexadecimal code
1003  aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
1004  // Get the decimal code
1005  aDecimalText = OUString::number(cChar);
1006  setCharName(cChar);
1007 
1008  // Update the hex and decimal codes only if necessary
1009  if (!m_xHexCodeText->get_text().equalsIgnoreAsciiCase(aHexText))
1010  m_xHexCodeText->set_text(aHexText);
1011  if (m_xDecimalCodeText->get_text() != aDecimalText)
1012  m_xDecimalCodeText->set_text( aDecimalText );
1013 
1014  const Subset* pSubset = nullptr;
1015  if( pSubsetMap )
1016  pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
1017  if( pSubset )
1018  m_xSubsetLB->set_active_text(pSubset->GetName());
1019  else
1020  m_xSubsetLB->set_active(-1);
1021  }
1022 
1023  if(m_xSearchSet->HasFocus())
1024  {
1025  m_aShowChar.SetText( aText );
1026  m_aShowChar.SetFont( aFont );
1027  m_aShowChar.Invalidate();
1028 
1029  setFavButtonState(aText, aFont.GetFamilyName());
1030  }
1031 }
1032 
1034 {
1035  OUString aCodeString;
1036  switch(radix)
1037  {
1038  case Radix::decimal:
1039  aCodeString = m_xDecimalCodeText->get_text();
1040  break;
1041  case Radix::hexadecimal:
1042  aCodeString = m_xHexCodeText->get_text();
1043  break;
1044  }
1045  // Convert the code back to a character using the appropriate radix
1046  sal_UCS4 cChar = aCodeString.toUInt32(static_cast<sal_Int16> (radix));
1047  // Use FontCharMap::HasChar(sal_UCS4 cChar) to see if the desired character is in the font
1048  FontCharMapRef xFontCharMap = m_xShowSet->GetFontCharMap();
1049  if (xFontCharMap->HasChar(cChar))
1050  // Select the corresponding character
1051  SetChar(cChar);
1052  else {
1053  m_xCharName->set_label(CuiResId(RID_SVXSTR_MISSING_CHAR));
1054  m_aShowChar.SetText(" ");
1055  switch(radix)
1056  {
1057  case Radix::decimal:
1058  m_xHexCodeText->set_text(OUString::number(cChar, 16));
1059  break;
1060  case Radix::hexadecimal:
1061  m_xDecimalCodeText->set_text(OUString::number(cChar));
1062  break;
1063  }
1064  }
1065 }
1066 
1067 IMPL_LINK_NOARG(SvxCharacterMap, DecimalCodeChangeHdl, weld::Entry&, void)
1068 {
1069  selectCharByCode(Radix::decimal);
1070 }
1071 
1072 IMPL_LINK_NOARG(SvxCharacterMap, HexCodeChangeHdl, weld::Entry&, void)
1073 {
1074  selectCharByCode(Radix::hexadecimal);
1075 }
1076 
1078 {
1079  // adjust subset selection
1080  if( pSubsetMap )
1081  {
1082  sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
1083 
1084  setFavButtonState(OUString(&cChar, 1), aFont.GetFamilyName());
1085  const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
1086  if( pSubset )
1087  m_xSubsetLB->set_active_text(pSubset->GetName());
1088  }
1089 
1090  m_xOKBtn->set_sensitive(true);
1091 }
1092 
1093 IMPL_LINK_NOARG(SvxCharacterMap, SearchCharPreSelectHdl, SvxShowCharSet*, void)
1094 {
1095  // adjust subset selection
1096  if( pSubsetMap )
1097  {
1098  sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
1099 
1100  setFavButtonState(OUString(&cChar, 1), aFont.GetFamilyName());
1101  const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
1102  if( pSubset )
1103  m_xSubsetLB->set_active_text(pSubset->GetName());
1104  }
1105 
1106  m_xOKBtn->set_sensitive(true);
1107 }
1108 
1109 // class SvxShowText =====================================================
1111  : m_xVirDev(rVirDev)
1112  , mnY(0)
1113  , mbCenter(false)
1114 {
1115 }
1116 
1118 {
1119  CustomWidgetController::SetDrawingArea(pDrawingArea);
1120  vcl::Font aFont = m_xVirDev->GetFont();
1121  Size aFontSize(aFont.GetFontSize().Width() * 5, aFont.GetFontSize().Height() * 5);
1122  aFont.SetFontSize(aFontSize);
1123  m_xVirDev->Push(PUSH_ALLFONT);
1124  m_xVirDev->SetFont(aFont);
1125  pDrawingArea->set_size_request(m_xVirDev->approximate_digit_width() + 2 * 12,
1126  m_xVirDev->LogicToPixel(aFontSize).Height() * 2);
1127  m_xVirDev->Pop();
1128 }
1129 
1131 {
1132  rRenderContext.SetFont(m_aFont);
1133 
1134  Color aTextCol = rRenderContext.GetTextColor();
1135  Color aFillCol = rRenderContext.GetFillColor();
1136 
1137  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1138  const Color aWindowTextColor(rStyleSettings.GetDialogTextColor());
1139  const Color aWindowColor(rStyleSettings.GetWindowColor());
1140  rRenderContext.SetTextColor(aWindowTextColor);
1141  rRenderContext.SetFillColor(aWindowColor);
1142 
1143  const OUString aText = GetText();
1144 
1145  Size aSize(GetOutputSizePixel());
1146  long nAvailWidth = aSize.Width();
1147  long nWinHeight = aSize.Height();
1148 
1149  bool bGotBoundary = true;
1150  bool bShrankFont = false;
1151  vcl::Font aOrigFont(rRenderContext.GetFont());
1152  Size aFontSize(aOrigFont.GetFontSize());
1153  ::tools::Rectangle aBoundRect;
1154 
1155  for (long nFontHeight = aFontSize.Height(); nFontHeight > 0; nFontHeight -= 5)
1156  {
1157  if (!rRenderContext.GetTextBoundRect( aBoundRect, aText ) || aBoundRect.IsEmpty())
1158  {
1159  bGotBoundary = false;
1160  break;
1161  }
1162  if (!mbCenter)
1163  break;
1164  //only shrink in the single glyph large view mode
1165  long nTextWidth = aBoundRect.GetWidth();
1166  if (nAvailWidth > nTextWidth)
1167  break;
1168  vcl::Font aFont(aOrigFont);
1169  aFontSize.setHeight( nFontHeight );
1170  aFont.SetFontSize(aFontSize);
1171  rRenderContext.SetFont(aFont);
1172  mnY = (nWinHeight - rRenderContext.GetTextHeight()) / 2;
1173  bShrankFont = true;
1174  }
1175 
1176  Point aPoint(2, mnY);
1177  // adjust position using ink boundary if possible
1178  if (!bGotBoundary)
1179  aPoint.setX( (aSize.Width() - rRenderContext.GetTextWidth(aText)) / 2 );
1180  else
1181  {
1182  // adjust position before it gets out of bounds
1183  aBoundRect += aPoint;
1184 
1185  // shift back vertically if needed
1186  int nYLDelta = aBoundRect.Top();
1187  int nYHDelta = aSize.Height() - aBoundRect.Bottom();
1188  if( nYLDelta <= 0 )
1189  aPoint.AdjustY( -(nYLDelta - 1) );
1190  else if( nYHDelta <= 0 )
1191  aPoint.AdjustY(nYHDelta - 1 );
1192 
1193  if (mbCenter)
1194  {
1195  // move glyph to middle of cell
1196  aPoint.setX( -aBoundRect.Left() + (aSize.Width() - aBoundRect.GetWidth()) / 2 );
1197  }
1198  else
1199  {
1200  // shift back horizontally if needed
1201  int nXLDelta = aBoundRect.Left();
1202  int nXHDelta = aSize.Width() - aBoundRect.Right();
1203  if( nXLDelta <= 0 )
1204  aPoint.AdjustX( -(nXLDelta - 1) );
1205  else if( nXHDelta <= 0 )
1206  aPoint.AdjustX(nXHDelta - 1 );
1207  }
1208  }
1209 
1210  rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aSize));
1211  rRenderContext.DrawText(aPoint, aText);
1212  rRenderContext.SetTextColor(aTextCol);
1213  rRenderContext.SetFillColor(aFillCol);
1214  if (bShrankFont)
1215  rRenderContext.SetFont(aOrigFont);
1216 }
1217 
1218 void SvxShowText::SetFont( const vcl::Font& rFont )
1219 {
1220  long nWinHeight = GetOutputSizePixel().Height();
1221 
1222  m_aFont = rFont;
1225  m_aFont.SetFontSize(m_xVirDev->PixelToLogic(Size(0, nWinHeight / 2)));
1226  m_aFont.SetTransparent(true);
1227 
1228  m_xVirDev->Push(PUSH_ALLFONT);
1229  m_xVirDev->SetFont(m_aFont);
1230  mnY = (nWinHeight - m_xVirDev->GetTextHeight()) / 2;
1231  m_xVirDev->Pop();
1232 
1233  Invalidate();
1234 }
1235 
1237 {
1238  SetFont(GetFont()); //force recalculation of size
1239 }
1240 
1241 void SvxShowText::SetText(const OUString& rText)
1242 {
1243  m_sText = rText;
1244  Invalidate();
1245 }
1246 
1247 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void updateRecentCharControl()
Definition: cuicharmap.cxx:260
void SetFamily(FontFamily)
long Width() const
const Color & GetTextColor() const
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, MetricVector *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
bool HasChar(sal_UCS4) const
sal_Int32 GetValue() const
long GetWidth() const
SvxCharView m_aFavCharView[16]
Definition: cuicharmap.hxx:89
sal_Int32 nIndex
void SetFontSize(const Size &)
SvxShowText m_aShowChar
Definition: cuicharmap.hxx:90
ScopedVclPtr< VirtualDevice > m_xVirDev
Definition: cuicharmap.hxx:48
const OUString & GetFamilyName() const
const OUString & GetStyleName() const
long Height() const
const SubsetVec & GetSubsetMap() const
uno::Reference< uno::XComponentContext > mxContext
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &) override
FAMILY_DONTKNOW
const OUString & GetName() const
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
std::unique_ptr< SvxSearchCharSet > m_xSearchSet
Definition: cuicharmap.hxx:109
void SetChar(sal_UCS4)
Definition: cuicharmap.cxx:204
css::uno::Reference< css::lang::XComponent > m_xFrame
void SetWeight(FontWeight)
void SetFont(const vcl::Font &rFont)
std::deque< OUString > maRecentCharList
Definition: cuicharmap.hxx:82
static void fillAllSubsets(weld::ComboBox &rListBox)
Definition: cuicharmap.cxx:595
void insertCharToDoc(const OUString &sChar)
Definition: cuicharmap.cxx:604
void SetCharSet(rtl_TextEncoding)
FontPitch GetPitch() const
OUString const & GetText() const
Definition: cuicharmap.hxx:64
ScopedVclPtr< VirtualDevice > m_xVirDev
Definition: cuicharmap.hxx:77
Size const & GetOutputSizePixel() const
FontFamily GetFamilyType()
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, const long *pDXArray=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
void selectCharByCode(Radix radix)
SfxApplication * SfxGetpApp()
std::unique_ptr< SfxAllItemSet > m_xOutputSet
Definition: cuicharmap.hxx:112
OUString m_sText
Definition: cuicharmap.hxx:49
void toggleSearchView(bool state)
Definition: cuicharmap.cxx:682
const vcl::Font & GetFont() const
std::unique_ptr< weld::Label > m_xFontText
Definition: cuicharmap.hxx:93
static sal_uInt32 & getSelectedChar()
rtl_TextEncoding GetCharSet() const
bool dispatchCommand(const OUString &rCommand, const uno::Reference< css::frame::XFrame > &rFrame, const css::uno::Sequence< css::beans::PropertyValue > &rArguments, const uno::Reference< css::frame::XDispatchResultListener > &rListener)
int nCount
static std::shared_ptr< ConfigurationChanges > create(css::uno::Reference< css::uno::XComponentContext > const &context=comphelper::getProcessComponentContext())
std::unique_ptr< weld::ComboBox > m_xSubsetLB
Definition: cuicharmap.hxx:96
std::deque< OUString > maFavCharList
Definition: cuicharmap.hxx:84
void setCharName(sal_UCS4 nDecimalValue)
Definition: cuicharmap.cxx:701
const char * sName
void DrawRect(const tools::Rectangle &rRect)
void SetPitch(FontPitch ePitch)
SfxItemPool & GetPool() const
const OUString & GetStyleName() const
std::unique_ptr< weld::Entry > m_xDecimalCodeText
Definition: cuicharmap.hxx:99
uno::Reference< uno::XComponentContext > mxContext
Definition: cuicharmap.hxx:86
css::uno::Reference< css::frame::XFrame > m_xFrame
Definition: cuicharmap.hxx:81
WEIGHT_DONTKNOW
void SetAlignment(FontAlign)
std::unique_ptr< SvxShowCharSet > m_xShowSet
Definition: cuicharmap.hxx:107
void updateRecentCharacterList(const OUString &rChar, const OUString &rFont)
Definition: cuicharmap.cxx:281
sal_UCS4 GetFirstChar() const
std::unique_ptr< weld::Button > m_xFavouritesBtn
Definition: cuicharmap.hxx:100
void SetFamilyName(const OUString &rFamilyName)
void getRecentCharacterList()
Definition: cuicharmap.cxx:222
void SetFont(const vcl::Font &rFont)
FontPitch GetPitch()
int i
uno_Any a
void SetHasInsert(bool bInsert)
virtual void insert_vector(const std::vector< weld::ComboBoxEntry > &rItems, bool bKeepExisting)=0
vcl::Font m_aFont
Definition: cuicharmap.hxx:52
std::unique_ptr< weld::Entry > m_xHexCodeText
Definition: cuicharmap.hxx:98
void SetFillColor()
WEIGHT_NORMAL
void SetTextColor(const Color &rColor)
void setClearAllClickHdl(const Link< SvxCharView *, void > &rLink)
const Size & GetFontSize() const
PITCH_DONTKNOW
bool isFavChar(const OUString &sTitle, const OUString &rFont)
Definition: cuicharmap.cxx:531
void getFavCharacterList()
Definition: cuicharmap.cxx:240
void updateFavCharacterList(const OUString &rChar, const OUString &rFont)
Definition: cuicharmap.cxx:321
ITALIC_NONE
std::unique_ptr< weld::Entry > m_xSearchText
Definition: cuicharmap.hxx:97
long GetTextHeight() const
vcl::Font aFont
Definition: cuicharmap.hxx:78
OUString CuiResId(const char *pKey)
Definition: cuiresmgr.cxx:23
#define PUSH_ALLFONT
void SetText(const OUString &rText)
sal_UCS4 GetRangeMin() const
virtual short run() override
Definition: cuicharmap.cxx:183
SvxCharacterMap(weld::Widget *pParent, const SfxItemSet *pSet, const css::uno::Reference< css::frame::XFrame > &rFrame)
Definition: cuicharmap.cxx:50
IMPL_LINK(SvxCharacterMap, RecentClearClickHdl, SvxCharView *, rView, void)
Definition: cuicharmap.cxx:743
const OUString & GetFamilyName() const
sal_UCS4 GetNextChar(sal_UCS4 cChar) const
std::deque< OUString > maFavCharFontList
Definition: cuicharmap.hxx:85
ALIGN_TOP
void setClearClickHdl(const Link< SvxCharView *, void > &rLink)
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
void setMouseClickHdl(const Link< SvxCharView *, void > &rLink)
WIDTH_DONTKNOW
std::deque< OUString > maRecentCharFontList
Definition: cuicharmap.hxx:83
void SetFont(const vcl::Font &rNewFont)
void SetTransparent(bool bTransparent)
SvxShowText(const VclPtr< VirtualDevice > &rVirDev)
sal_UCS4 GetLastChar() const
RET_OK
Reference< XExecutableDialog > m_xDialog
Reference< XComponentContext > getProcessComponentContext()
void SetCharFont(const vcl::Font &rFont)
Definition: cuicharmap.cxx:572
void updateFavCharControl()
Definition: cuicharmap.cxx:359
const Color & GetWindowColor() const
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
void DisableFontSelection()
Definition: cuicharmap.cxx:215
FILE * init(int, char **)
long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
std::unique_ptr< weld::ComboBox > m_xFontLB
Definition: cuicharmap.hxx:94
void SetText(const OUString &rText)
ScXMLEditAttributeMap::Entry const aEntries[]
sal_UCS4 GetChar() const
Definition: cuicharmap.cxx:210
vcl::Font const & GetFont() const
Definition: cuicharmap.hxx:62
The main purpose of this dialog is to enable the use of characters that are not easily accessible fro...
Definition: cuicharmap.hxx:72
void setFavButtonState(const OUString &sTitle, const OUString &rFont)
Definition: cuicharmap.cxx:546
sal_uInt32 sal_UCS4
IMPL_LINK_NOARG(SvxCharacterMap, FontSelectHdl, weld::ComboBox &, void)
Definition: cuicharmap.cxx:632
std::unique_ptr< weld::Button > m_xOKBtn
Definition: cuicharmap.hxx:92
const Color & GetDialogTextColor() const
virtual void set_size_request(int nWidth, int nHeight)=0
vcl::Font const & GetFont() const
rtl_TextEncoding GetCharSet() const
sal_uInt16 nPos
virtual void Resize() override
const Color & GetFillColor() const
void deleteFavCharacterFromList(const OUString &rChar, const OUString &rFont)
Definition: cuicharmap.cxx:382
SvxCharView m_aRecentCharView[16]
Definition: cuicharmap.hxx:88
std::unique_ptr< weld::Label > m_xCharName
Definition: cuicharmap.hxx:101