1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <vcl/svapp.hxx>
23 #include <svtools/colorcfg.hxx>
24 #include <svl/eitem.hxx>
25 #include <svl/intitem.hxx>
26 #include <svl/itempool.hxx>
28 #include <rtl/textenc.h>
29 #include <svx/ucsubset.hxx>
30 #include <sfx2/objsh.hxx>
31 #include <vcl/settings.hxx>
32 #include <vcl/fontcharmap.hxx>
33 #include <vcl/virdev.hxx>
34 #include <svl/stritem.hxx>
35 #include <officecfg/Office/Common.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <comphelper/dispatchcommand.hxx>
39 #include <dialmgr.hxx>
40 #include <cui/cuicharmap.hxx>
41 #include <sfx2/request.hxx>
42 #include <sfx2/sfxsids.hrc>
43 #include <sfx2/app.hxx>
44 #include <svx/svxids.hrc>
45 #include <editeng/editids.hrc>
46 #include <editeng/fontitem.hxx>
47 #include <strings.hrc>
48 #include <macroass.hxx>
49 #include <unicode/uchar.h>
50 #include <unicode/utypes.h>
54 SvxCharacterMap::SvxCharacterMap(weld::Window
* pParent
, const SfxItemSet
* pSet
,
55 const css::uno::Reference
<css::frame::XFrame
>& rFrame
)
56 : SfxDialogController(pParent
, "cui/ui/specialcharacters.ui", "SpecialCharactersDialog")
57 , m_xVirDev(VclPtr
<VirtualDevice
>::Create())
60 , mxContext(comphelper::getProcessComponentContext())
61 , m_aRecentCharView
{SvxCharView(m_xVirDev
),
62 SvxCharView(m_xVirDev
),
63 SvxCharView(m_xVirDev
),
64 SvxCharView(m_xVirDev
),
65 SvxCharView(m_xVirDev
),
66 SvxCharView(m_xVirDev
),
67 SvxCharView(m_xVirDev
),
68 SvxCharView(m_xVirDev
),
69 SvxCharView(m_xVirDev
),
70 SvxCharView(m_xVirDev
),
71 SvxCharView(m_xVirDev
),
72 SvxCharView(m_xVirDev
),
73 SvxCharView(m_xVirDev
),
74 SvxCharView(m_xVirDev
),
75 SvxCharView(m_xVirDev
),
76 SvxCharView(m_xVirDev
)}
77 , m_aFavCharView
{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 SvxCharView(m_xVirDev
),
90 SvxCharView(m_xVirDev
),
91 SvxCharView(m_xVirDev
),
92 SvxCharView(m_xVirDev
)}
93 , m_aShowChar(m_xVirDev
)
94 , m_xOKBtn(m_xFrame
.is() ? m_xBuilder
->weld_button("insert") : m_xBuilder
->weld_button("ok"))
95 , m_xFontText(m_xBuilder
->weld_label("fontft"))
96 , m_xFontLB(m_xBuilder
->weld_combo_box("fontlb"))
97 , m_xSubsetText(m_xBuilder
->weld_label("subsetft"))
98 , m_xSubsetLB(m_xBuilder
->weld_combo_box("subsetlb"))
99 , m_xSearchText(m_xBuilder
->weld_entry("search"))
100 , m_xHexCodeText(m_xBuilder
->weld_entry("hexvalue"))
101 , m_xDecimalCodeText(m_xBuilder
->weld_entry("decimalvalue"))
102 , m_xFavouritesBtn(m_xBuilder
->weld_button("favbtn"))
103 , m_xCharName(m_xBuilder
->weld_label("charname"))
104 , m_xRecentGrid(m_xBuilder
->weld_widget("viewgrid"))
105 , m_xFavGrid(m_xBuilder
->weld_widget("favgrid"))
106 , m_xShowChar(new weld::CustomWeld(*m_xBuilder
, "showchar", m_aShowChar
))
107 , m_xRecentCharView
{std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar1", m_aRecentCharView
[0]),
108 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar2", m_aRecentCharView
[1]),
109 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar3", m_aRecentCharView
[2]),
110 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar4", m_aRecentCharView
[3]),
111 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar5", m_aRecentCharView
[4]),
112 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar6", m_aRecentCharView
[5]),
113 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar7", m_aRecentCharView
[6]),
114 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar8", m_aRecentCharView
[7]),
115 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar9", m_aRecentCharView
[8]),
116 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar10", m_aRecentCharView
[9]),
117 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar11", m_aRecentCharView
[10]),
118 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar12", m_aRecentCharView
[11]),
119 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar13", m_aRecentCharView
[12]),
120 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar14", m_aRecentCharView
[13]),
121 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar15", m_aRecentCharView
[14]),
122 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar16", m_aRecentCharView
[15])}
123 , m_xFavCharView
{std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar1", m_aFavCharView
[0]),
124 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar2", m_aFavCharView
[1]),
125 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar3", m_aFavCharView
[2]),
126 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar4", m_aFavCharView
[3]),
127 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar5", m_aFavCharView
[4]),
128 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar6", m_aFavCharView
[5]),
129 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar7", m_aFavCharView
[6]),
130 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar8", m_aFavCharView
[7]),
131 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar9", m_aFavCharView
[8]),
132 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar10", m_aFavCharView
[9]),
133 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar11", m_aFavCharView
[10]),
134 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar12", m_aFavCharView
[11]),
135 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar13", m_aFavCharView
[12]),
136 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar14", m_aFavCharView
[13]),
137 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar15", m_aFavCharView
[14]),
138 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar16", m_aFavCharView
[15])}
139 , m_xShowSet(new SvxShowCharSet(m_xBuilder
->weld_scrolled_window("showscroll"), m_xVirDev
))
140 , m_xShowSetArea(new weld::CustomWeld(*m_xBuilder
, "showcharset", *m_xShowSet
))
141 , m_xSearchSet(new SvxSearchCharSet(m_xBuilder
->weld_scrolled_window("searchscroll"), m_xVirDev
))
142 , m_xSearchSetArea(new weld::CustomWeld(*m_xBuilder
, "searchcharset", *m_xSearchSet
))
144 m_aShowChar
.SetCentered(true);
145 m_xFontLB
->make_sorted();
146 //lock the size request of this widget to the width of all possible entries
147 fillAllSubsets(*m_xSubsetLB
);
148 m_xSubsetLB
->set_size_request(m_xSubsetLB
->get_preferred_size().Width(), -1);
149 m_xCharName
->set_size_request(m_aShowChar
.get_preferred_size().Width(), m_xCharName
->get_text_height() * 4);
150 //lock the size request of this widget to the width of the original .ui string
151 m_xHexCodeText
->set_size_request(m_xHexCodeText
->get_preferred_size().Width(), -1);
152 //so things don't jump around if all the children are hidden
153 m_xRecentGrid
->set_size_request(-1, m_aRecentCharView
[0].get_preferred_size().Height());
154 m_xFavGrid
->set_size_request(-1, m_aFavCharView
[0].get_preferred_size().Height());
158 const SfxInt32Item
* pCharItem
= SfxItemSet::GetItem
<SfxInt32Item
>(pSet
, SID_ATTR_CHAR
, false);
160 SetChar( pCharItem
->GetValue() );
162 const SfxBoolItem
* pDisableItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSet
, FN_PARAM_2
, false);
163 if ( pDisableItem
&& pDisableItem
->GetValue() )
164 DisableFontSelection();
166 const SvxFontItem
* pFontItem
= SfxItemSet::GetItem
<SvxFontItem
>(pSet
, SID_ATTR_CHAR_FONT
, false);
167 const SfxStringItem
* pFontNameItem
= SfxItemSet::GetItem
<SfxStringItem
>(pSet
, SID_FONT_NAME
, false);
170 vcl::Font
aTmpFont( pFontItem
->GetFamilyName(), pFontItem
->GetStyleName(), GetCharFont().GetFontSize() );
171 aTmpFont
.SetCharSet( pFontItem
->GetCharSet() );
172 aTmpFont
.SetPitch( pFontItem
->GetPitch() );
173 SetCharFont( aTmpFont
);
175 else if ( pFontNameItem
)
177 vcl::Font
aTmpFont( GetCharFont() );
178 aTmpFont
.SetFamilyName( pFontNameItem
->GetValue() );
179 SetCharFont( aTmpFont
);
182 m_xOutputSet
.reset(new SfxAllItemSet(pSet
? *pSet
->GetPool() : SfxGetpApp()->GetPool()));
184 m_xSearchSet
->Hide();
187 short SvxCharacterMap::run()
189 if( SvxShowCharSet::getSelectedChar() == ' ')
191 m_xOKBtn
->set_sensitive(false);
192 setFavButtonState(OUString(), OUString());
196 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
197 // using the new UCS4 constructor
198 OUString
aOUStr( &cChar
, 1 );
199 m_aShowChar
.SetText(aOUStr
);
201 setFavButtonState(aOUStr
, m_aShowChar
.GetFont().GetFamilyName());
202 m_xOKBtn
->set_sensitive(true);
205 return SfxDialogController::run();
208 void SvxCharacterMap::SetChar( sal_UCS4 c
)
210 m_xShowSet
->SelectCharacter( c
);
211 setFavButtonState(OUString(&c
, 1), aFont
.GetFamilyName());
214 sal_UCS4
SvxCharacterMap::GetChar() const
216 return m_aShowChar
.GetText().toChar();
219 void SvxCharacterMap::DisableFontSelection()
221 m_xFontText
->set_sensitive(false);
222 m_xFontLB
->set_sensitive(false);
226 void SvxCharacterMap::getRecentCharacterList()
228 //retrieve recent character list
229 css::uno::Sequence
< OUString
> rRecentCharList( officecfg::Office::Common::RecentCharacters::RecentCharacterList::get() );
230 for (int i
= 0; i
< rRecentCharList
.getLength(); ++i
)
232 maRecentCharList
.push_back(rRecentCharList
[i
]);
235 //retrieve recent character font list
236 css::uno::Sequence
< OUString
> rRecentCharFontList( officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::get() );
237 for (int i
= 0; i
< rRecentCharFontList
.getLength(); ++i
)
239 maRecentCharFontList
.push_back(rRecentCharFontList
[i
]);
244 void SvxCharacterMap::getFavCharacterList()
246 maFavCharList
.clear();
247 maFavCharFontList
.clear();
248 //retrieve recent character list
249 css::uno::Sequence
< OUString
> rFavCharList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::get() );
250 for (int i
= 0; i
< rFavCharList
.getLength(); ++i
)
252 maFavCharList
.push_back(rFavCharList
[i
]);
255 //retrieve recent character font list
256 css::uno::Sequence
< OUString
> rFavCharFontList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::get() );
257 for (int i
= 0; i
< rFavCharFontList
.getLength(); ++i
)
259 maFavCharFontList
.push_back(rFavCharFontList
[i
]);
264 void SvxCharacterMap::updateRecentCharControl()
267 for ( std::deque
< OUString
>::iterator it
= maRecentCharList
.begin(), it2
= maRecentCharFontList
.begin();
268 it
!= maRecentCharList
.end() || it2
!= maRecentCharFontList
.end();
271 m_aRecentCharView
[i
].SetText(*it
);
272 vcl::Font rFont
= m_aRecentCharView
[i
].GetFont();
273 rFont
.SetFamilyName( *it2
);
274 m_aRecentCharView
[i
].SetFont(rFont
);
275 m_aRecentCharView
[i
].Show();
280 m_aRecentCharView
[i
].SetText(OUString());
281 m_aRecentCharView
[i
].Hide();
285 void SvxCharacterMap::updateRecentCharacterList(const OUString
& sTitle
, const OUString
& rFont
)
287 auto itChar
= std::find(maRecentCharList
.begin(), maRecentCharList
.end(), sTitle
);
289 auto itChar2
= std::find(maRecentCharFontList
.begin(), maRecentCharFontList
.end(), rFont
);
291 // if recent char to be added is already in list, remove it
292 if( itChar
!= maRecentCharList
.end() && itChar2
!= maRecentCharFontList
.end() )
294 maRecentCharList
.erase( itChar
);
295 maRecentCharFontList
.erase( itChar2
);
298 if (maRecentCharList
.size() == 16)
300 maRecentCharList
.pop_back();
301 maRecentCharFontList
.pop_back();
304 maRecentCharList
.push_front(sTitle
);
305 maRecentCharFontList
.push_front(rFont
);
307 css::uno::Sequence
< OUString
> aRecentCharList(maRecentCharList
.size());
308 css::uno::Sequence
< OUString
> aRecentCharFontList(maRecentCharFontList
.size());
310 for (size_t i
= 0; i
< maRecentCharList
.size(); ++i
)
312 aRecentCharList
[i
] = maRecentCharList
[i
];
313 aRecentCharFontList
[i
] = maRecentCharFontList
[i
];
316 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
317 officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList
, batch
);
318 officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList
, batch
);
321 updateRecentCharControl();
325 void SvxCharacterMap::updateFavCharacterList(const OUString
& sTitle
, const OUString
& rFont
)
327 auto itChar
= std::find(maFavCharList
.begin(), maFavCharList
.end(), sTitle
);
329 auto itChar2
= std::find(maFavCharFontList
.begin(), maFavCharFontList
.end(), rFont
);
331 // if Fav char to be added is already in list, remove it
332 if( itChar
!= maFavCharList
.end() && itChar2
!= maFavCharFontList
.end() )
334 maFavCharList
.erase( itChar
);
335 maFavCharFontList
.erase( itChar2
);
338 if (maFavCharList
.size() == 16)
340 maFavCharList
.pop_back();
341 maFavCharFontList
.pop_back();
344 maFavCharList
.push_back(sTitle
);
345 maFavCharFontList
.push_back(rFont
);
347 css::uno::Sequence
< OUString
> aFavCharList(maFavCharList
.size());
348 css::uno::Sequence
< OUString
> aFavCharFontList(maFavCharFontList
.size());
350 for (size_t i
= 0; i
< maFavCharList
.size(); ++i
)
352 aFavCharList
[i
] = maFavCharList
[i
];
353 aFavCharFontList
[i
] = maFavCharFontList
[i
];
356 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
357 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList
, batch
);
358 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList
, batch
);
363 void SvxCharacterMap::updateFavCharControl()
366 for ( std::deque
< OUString
>::iterator it
= maFavCharList
.begin(), it2
= maFavCharFontList
.begin();
367 it
!= maFavCharList
.end() || it2
!= maFavCharFontList
.end();
370 m_aFavCharView
[i
].SetText(*it
);
371 vcl::Font rFont
= m_aFavCharView
[i
].GetFont();
372 rFont
.SetFamilyName( *it2
);
373 m_aFavCharView
[i
].SetFont(rFont
);
374 m_aFavCharView
[i
].Show();
379 m_aFavCharView
[i
].SetText(OUString());
380 m_aFavCharView
[i
].Hide();
382 m_xShowSet
->getFavCharacterList();
383 m_xSearchSet
->getFavCharacterList();
386 void SvxCharacterMap::deleteFavCharacterFromList(const OUString
& sTitle
, const OUString
& rFont
)
388 auto itChar
= std::find(maFavCharList
.begin(), maFavCharList
.end(), sTitle
);
390 auto itChar2
= std::find(maFavCharFontList
.begin(), maFavCharFontList
.end(), rFont
);
392 // if Fav char to be added is already in list, remove it
393 if( itChar
!= maFavCharList
.end() && itChar2
!= maFavCharFontList
.end() )
395 maFavCharList
.erase( itChar
);
396 maFavCharFontList
.erase( itChar2
);
399 css::uno::Sequence
< OUString
> aFavCharList(maFavCharList
.size());
400 css::uno::Sequence
< OUString
> aFavCharFontList(maFavCharFontList
.size());
402 for (size_t i
= 0; i
< maFavCharList
.size(); ++i
)
404 aFavCharList
[i
] = maFavCharList
[i
];
405 aFavCharFontList
[i
] = maFavCharFontList
[i
];
408 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
409 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList
, batch
);
410 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList
, batch
);
414 void SvxCharacterMap::init()
416 aFont
= m_xVirDev
->GetFont();
417 aFont
.SetTransparent( true );
418 aFont
.SetFamily( FAMILY_DONTKNOW
);
419 aFont
.SetPitch( PITCH_DONTKNOW
);
420 aFont
.SetCharSet( RTL_TEXTENCODING_DONTKNOW
);
422 OUString
aDefStr( aFont
.GetFamilyName() );
424 int nCount
= m_xVirDev
->GetDevFontCount();
425 std::vector
<weld::ComboBoxEntry
> aEntries
;
426 aEntries
.reserve(nCount
);
427 for (int i
= 0; i
< nCount
; ++i
)
429 OUString
aFontName( m_xVirDev
->GetDevFont( i
).GetFamilyName() );
430 if (aFontName
!= aLastName
)
432 aLastName
= aFontName
;
433 aEntries
.emplace_back(aFontName
, OUString::number(i
));
436 m_xFontLB
->insert_vector(aEntries
, true);
437 // the font may not be in the list =>
438 // try to find a font name token in list and select found font,
439 // else select topmost entry
440 bool bFound
= (m_xFontLB
->find_text(aDefStr
) == -1);
443 sal_Int32 nIndex
= 0;
446 OUString aToken
= aDefStr
.getToken(0, ';', nIndex
);
447 if (m_xFontLB
->find_text(aToken
) != -1)
454 while ( nIndex
>= 0 );
458 m_xFontLB
->set_active_text(aDefStr
);
459 else if (m_xFontLB
->get_count() )
460 m_xFontLB
->set_active(0);
461 FontSelectHdl(*m_xFontLB
);
462 if (m_xSubsetLB
->get_count())
463 m_xSubsetLB
->set_active(0);
465 m_xFontLB
->connect_changed(LINK( this, SvxCharacterMap
, FontSelectHdl
));
466 m_xSubsetLB
->connect_changed(LINK( this, SvxCharacterMap
, SubsetSelectHdl
));
467 m_xOKBtn
->connect_clicked(LINK(this, SvxCharacterMap
, InsertClickHdl
));
470 m_xShowSet
->SetDoubleClickHdl( LINK( this, SvxCharacterMap
, CharDoubleClickHdl
) );
471 m_xShowSet
->SetSelectHdl( LINK( this, SvxCharacterMap
, CharSelectHdl
) );
472 m_xShowSet
->SetHighlightHdl( LINK( this, SvxCharacterMap
, CharHighlightHdl
) );
473 m_xShowSet
->SetPreSelectHdl( LINK( this, SvxCharacterMap
, CharPreSelectHdl
) );
474 m_xShowSet
->SetFavClickHdl( LINK( this, SvxCharacterMap
, FavClickHdl
) );
476 m_xSearchSet
->SetDoubleClickHdl( LINK( this, SvxCharacterMap
, SearchCharDoubleClickHdl
) );
477 m_xSearchSet
->SetSelectHdl( LINK( this, SvxCharacterMap
, SearchCharSelectHdl
) );
478 m_xSearchSet
->SetHighlightHdl( LINK( this, SvxCharacterMap
, SearchCharHighlightHdl
) );
479 m_xSearchSet
->SetPreSelectHdl( LINK( this, SvxCharacterMap
, SearchCharPreSelectHdl
) );
480 m_xSearchSet
->SetFavClickHdl( LINK( this, SvxCharacterMap
, FavClickHdl
) );
482 m_xDecimalCodeText
->connect_changed( LINK( this, SvxCharacterMap
, DecimalCodeChangeHdl
) );
483 m_xHexCodeText
->connect_changed( LINK( this, SvxCharacterMap
, HexCodeChangeHdl
) );
484 m_xFavouritesBtn
->connect_clicked( LINK(this, SvxCharacterMap
, FavSelectHdl
));
486 // tdf#117038 set the buttons width to its max possible width so it doesn't
487 // make layout change when the label changes
488 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_REMOVE_FAVORITES
));
489 auto nMaxWidth
= m_xFavouritesBtn
->get_preferred_size().Width();
490 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES
));
491 nMaxWidth
= std::max(nMaxWidth
, m_xFavouritesBtn
->get_preferred_size().Width());
492 m_xFavouritesBtn
->set_size_request(nMaxWidth
, -1);
494 if( SvxShowCharSet::getSelectedChar() == ' ')
496 m_xOKBtn
->set_sensitive(false);
500 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
501 // using the new UCS4 constructor
502 OUString
aOUStr( &cChar
, 1 );
503 m_aShowChar
.SetText(aOUStr
);
505 setFavButtonState(aOUStr
, aDefStr
);
506 m_xOKBtn
->set_sensitive(true);
509 getRecentCharacterList();
510 updateRecentCharControl();
512 getFavCharacterList();
513 updateFavCharControl();
515 bool bHasInsert
= m_xFrame
.is();
517 for(int i
= 0; i
< 16; i
++)
519 m_aRecentCharView
[i
].SetHasInsert(bHasInsert
);
520 m_aRecentCharView
[i
].setMouseClickHdl(LINK(this,SvxCharacterMap
, CharClickHdl
));
521 m_aRecentCharView
[i
].setClearClickHdl(LINK(this,SvxCharacterMap
, RecentClearClickHdl
));
522 m_aRecentCharView
[i
].setClearAllClickHdl(LINK(this,SvxCharacterMap
, RecentClearAllClickHdl
));
523 m_aFavCharView
[i
].SetHasInsert(bHasInsert
);
524 m_aFavCharView
[i
].setMouseClickHdl(LINK(this,SvxCharacterMap
, CharClickHdl
));
525 m_aFavCharView
[i
].setClearClickHdl(LINK(this,SvxCharacterMap
, FavClearClickHdl
));
526 m_aFavCharView
[i
].setClearAllClickHdl(LINK(this,SvxCharacterMap
, FavClearAllClickHdl
));
531 m_xSearchText
->connect_focus_in(LINK( this, SvxCharacterMap
, SearchFieldGetFocusHdl
));
532 m_xSearchText
->connect_changed(LINK(this, SvxCharacterMap
, SearchUpdateHdl
));
535 bool SvxCharacterMap::isFavChar(const OUString
& sTitle
, const OUString
& rFont
)
537 auto isFavCharTitleExists
= std::any_of(maFavCharList
.begin(),
539 [sTitle
] (const OUString
& a
) { return a
== sTitle
; });
541 auto isFavCharFontExists
= std::any_of(maFavCharFontList
.begin(),
542 maFavCharFontList
.end(),
543 [rFont
] (const OUString
& a
) { return a
== rFont
; });
545 // if Fav char to be added is already in list, remove it
546 return isFavCharTitleExists
&& isFavCharFontExists
;
550 void SvxCharacterMap::setFavButtonState(const OUString
& sTitle
, const OUString
& rFont
)
552 if(sTitle
.isEmpty() || rFont
.isEmpty())
554 m_xFavouritesBtn
->set_sensitive(false);
558 m_xFavouritesBtn
->set_sensitive(true);
560 if (isFavChar(sTitle
, rFont
))
562 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_REMOVE_FAVORITES
));
566 if(maFavCharList
.size() == 16)
568 m_xFavouritesBtn
->set_sensitive(false);
571 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES
));
576 void SvxCharacterMap::SetCharFont( const vcl::Font
& rFont
)
578 // first get the underlying info in order to get font names
579 // like "Times New Roman;Times" resolved
580 vcl::Font
aTmp(m_xVirDev
->GetFontMetric(rFont
));
582 if (aTmp
.GetFamilyName() == "StarSymbol" && m_xFontLB
->find_text(aTmp
.GetFamilyName()) == -1)
584 //if for some reason, like font in an old document, StarSymbol is requested and it's not available, then
585 //try OpenSymbol instead
586 aTmp
.SetFamilyName("OpenSymbol");
589 if (m_xFontLB
->find_text(aTmp
.GetFamilyName()) == -1)
592 m_xFontLB
->set_active_text(aTmp
.GetFamilyName());
594 FontSelectHdl(*m_xFontLB
);
595 if (m_xSubsetLB
->get_count())
596 m_xSubsetLB
->set_active(0);
599 void SvxCharacterMap::fillAllSubsets(weld::ComboBox
& rListBox
)
601 SubsetMap
aAll(nullptr);
602 std::vector
<weld::ComboBoxEntry
> aEntries
;
603 for (auto & subset
: aAll
.GetSubsetMap())
604 aEntries
.emplace_back(subset
.GetName());
605 rListBox
.insert_vector(aEntries
, true);
608 void SvxCharacterMap::insertCharToDoc(const OUString
& sGlyph
)
614 uno::Reference
< uno::XComponentContext
> xContext( comphelper::getProcessComponentContext() );
616 uno::Sequence
<beans::PropertyValue
> aArgs(2);
617 aArgs
[0].Name
= "Symbols";
618 aArgs
[0].Value
<<= sGlyph
;
620 aArgs
[1].Name
= "FontName";
621 aArgs
[1].Value
<<= aFont
.GetFamilyName();
622 comphelper::dispatchCommand(".uno:InsertSymbol", m_xFrame
, aArgs
);
624 updateRecentCharacterList(sGlyph
, aFont
.GetFamilyName());
628 sal_UCS4 cChar
= sGlyph
.iterateCodePoints(&tmp
);
629 const SfxItemPool
* pPool
= m_xOutputSet
->GetPool();
630 m_xOutputSet
->Put( SfxStringItem( pPool
->GetWhich(SID_CHARMAP
), sGlyph
) );
631 m_xOutputSet
->Put( SvxFontItem( aFont
.GetFamilyType(), aFont
.GetFamilyName(),
632 aFont
.GetStyleName(), aFont
.GetPitch(), aFont
.GetCharSet(), pPool
->GetWhich(SID_ATTR_CHAR_FONT
) ) );
633 m_xOutputSet
->Put( SfxStringItem( pPool
->GetWhich(SID_FONT_NAME
), aFont
.GetFamilyName() ) );
634 m_xOutputSet
->Put( SfxInt32Item( pPool
->GetWhich(SID_ATTR_CHAR
), cChar
) );
638 IMPL_LINK_NOARG(SvxCharacterMap
, FontSelectHdl
, weld::ComboBox
&, void)
640 const sal_uInt32 nFont
= m_xFontLB
->get_active_id().toUInt32();
641 aFont
= m_xVirDev
->GetDevFont(nFont
);
642 aFont
.SetWeight( WEIGHT_DONTKNOW
);
643 aFont
.SetItalic( ITALIC_NONE
);
644 aFont
.SetWidthType( WIDTH_DONTKNOW
);
645 aFont
.SetPitch( PITCH_DONTKNOW
);
646 aFont
.SetFamily( FAMILY_DONTKNOW
);
648 // notify children using this font
649 m_xShowSet
->SetFont( aFont
);
650 m_xSearchSet
->SetFont( aFont
);
651 m_aShowChar
.SetFont( aFont
);
654 SearchUpdateHdl(*m_xSearchText
);
655 SearchCharHighlightHdl(m_xSearchSet
.get());
658 // setup unicode subset listbar with font specific subsets,
659 // hide unicode subset listbar for symbol fonts
660 // TODO: get info from the Font once it provides it
662 m_xSubsetLB
->clear();
664 bool bNeedSubset
= (aFont
.GetCharSet() != RTL_TEXTENCODING_SYMBOL
);
667 FontCharMapRef xFontCharMap
= m_xShowSet
->GetFontCharMap();
668 pSubsetMap
.reset(new SubsetMap( xFontCharMap
));
670 // update subset listbox for new font's unicode subsets
671 for (auto const& subset
: pSubsetMap
->GetSubsetMap())
673 m_xSubsetLB
->append(OUString::number(reinterpret_cast<sal_uInt64
>(&subset
)), subset
.GetName());
674 // NOTE: subset must live at least as long as the selected font
677 if (m_xSubsetLB
->get_count() <= 1)
681 m_xSubsetText
->set_sensitive(bNeedSubset
);
682 m_xSubsetLB
->set_sensitive(bNeedSubset
);
684 // tdf#118304 reselect current glyph to see if its still there in new font
685 selectCharByCode(Radix::hexadecimal
);
688 void SvxCharacterMap::toggleSearchView(bool state
)
690 isSearchMode
= state
;
691 m_xHexCodeText
->set_editable(!state
);
692 m_xDecimalCodeText
->set_editable(!state
);
693 m_xSubsetLB
->set_sensitive(!state
);
697 m_xSearchSet
->Show();
702 m_xSearchSet
->Hide();
707 void SvxCharacterMap::setCharName(sal_UCS4 nDecimalValue
)
709 /* get the character name */
710 UErrorCode errorCode
= U_ZERO_ERROR
;
711 // icu has a private uprv_getMaxCharNameLength function which returns the max possible
712 // length of this property. Unicode 3.2 max char name length was 83
714 u_charName(nDecimalValue
, U_UNICODE_CHAR_NAME
, buffer
, sizeof(buffer
), &errorCode
);
715 if (U_SUCCESS(errorCode
))
716 m_xCharName
->set_label(OUString::createFromAscii(buffer
));
719 IMPL_LINK_NOARG(SvxCharacterMap
, SubsetSelectHdl
, weld::ComboBox
&, void)
721 const sal_Int32 nPos
= m_xSubsetLB
->get_active();
722 const Subset
* pSubset
= reinterpret_cast<const Subset
*>(m_xSubsetLB
->get_active_id().toUInt64());
724 if( pSubset
&& !isSearchMode
)
726 sal_UCS4 cFirst
= pSubset
->GetRangeMin();
727 m_xShowSet
->SelectCharacter( cFirst
);
729 setFavButtonState(OUString(&cFirst
, 1), aFont
.GetFamilyName());
730 m_xSubsetLB
->set_active(nPos
);
732 else if( pSubset
&& isSearchMode
)
734 m_xSearchSet
->SelectCharacter( pSubset
);
736 const Subset
* curSubset
= nullptr;
738 curSubset
= pSubsetMap
->GetSubsetByUnicode( m_xSearchSet
->GetSelectCharacter() );
740 m_xSubsetLB
->set_active_text(curSubset
->GetName());
742 m_xSubsetLB
->set_active(-1);
744 sal_UCS4 sChar
= m_xSearchSet
->GetSelectCharacter();
745 setFavButtonState(OUString(&sChar
, 1), aFont
.GetFamilyName());
749 IMPL_LINK(SvxCharacterMap
, RecentClearClickHdl
, SvxCharView
*, rView
, void)
751 const OUString
& sTitle
= rView
->GetText();
752 auto itChar
= std::find(maRecentCharList
.begin(), maRecentCharList
.end(), sTitle
);
754 OUString sFont
= rView
->GetFont().GetFamilyName();
755 auto itChar2
= std::find(maRecentCharFontList
.begin(), maRecentCharFontList
.end(), sFont
);
757 // if recent char to be added is already in list, remove it
758 if( itChar
!= maRecentCharList
.end() && itChar2
!= maRecentCharFontList
.end() )
760 maRecentCharList
.erase( itChar
);
761 maRecentCharFontList
.erase( itChar2
);
764 css::uno::Sequence
< OUString
> aRecentCharList(maRecentCharList
.size());
765 css::uno::Sequence
< OUString
> aRecentCharFontList(maRecentCharFontList
.size());
767 for (size_t i
= 0; i
< maRecentCharList
.size(); ++i
)
769 aRecentCharList
[i
] = maRecentCharList
[i
];
770 aRecentCharFontList
[i
] = maRecentCharFontList
[i
];
773 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
774 officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList
, batch
);
775 officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList
, batch
);
778 updateRecentCharControl();
781 IMPL_LINK_NOARG(SvxCharacterMap
, RecentClearAllClickHdl
, SvxCharView
*, void)
783 css::uno::Sequence
< OUString
> aRecentCharList(0);
784 css::uno::Sequence
< OUString
> aRecentCharFontList(0);
786 maRecentCharList
.clear();
787 maRecentCharFontList
.clear();
789 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
790 officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList
, batch
);
791 officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList
, batch
);
794 updateRecentCharControl();
797 IMPL_LINK(SvxCharacterMap
, FavClearClickHdl
, SvxCharView
*, rView
, void)
799 deleteFavCharacterFromList(rView
->GetText(), rView
->GetFont().GetFamilyName());
800 updateFavCharControl();
803 IMPL_LINK_NOARG(SvxCharacterMap
, FavClearAllClickHdl
, SvxCharView
*, void)
805 css::uno::Sequence
< OUString
> aFavCharList(0);
806 css::uno::Sequence
< OUString
> aFavCharFontList(0);
808 maFavCharList
.clear();
809 maFavCharFontList
.clear();
811 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
812 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList
, batch
);
813 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList
, batch
);
816 updateFavCharControl();
819 IMPL_LINK_NOARG(SvxCharacterMap
, SearchFieldGetFocusHdl
, weld::Widget
&, void)
821 m_xOKBtn
->set_sensitive(false);
824 IMPL_LINK_NOARG(SvxCharacterMap
, SearchUpdateHdl
, weld::Entry
&, void)
826 if (!m_xSearchText
->get_text().isEmpty())
828 m_xSearchSet
->ClearPreviousData();
829 OUString aKeyword
= m_xSearchText
->get_text();
831 toggleSearchView(true);
833 FontCharMapRef xFontCharMap
= m_xSearchSet
->GetFontCharMap();
835 sal_UCS4 sChar
= xFontCharMap
->GetFirstChar();
836 while(sChar
!= xFontCharMap
->GetLastChar())
838 UErrorCode errorCode
= U_ZERO_ERROR
;
840 u_charName(sChar
, U_UNICODE_CHAR_NAME
, buffer
, sizeof(buffer
), &errorCode
);
841 if (U_SUCCESS(errorCode
))
843 OUString sName
= OUString::createFromAscii(buffer
);
844 if(!sName
.isEmpty() && sName
.toAsciiLowerCase().indexOf(aKeyword
.toAsciiLowerCase()) >= 0)
845 m_xSearchSet
->AppendCharToList(sChar
);
847 sChar
= xFontCharMap
->GetNextChar(sChar
);
850 UErrorCode errorCode
= U_ZERO_ERROR
;
852 u_charName(sChar
, U_UNICODE_CHAR_NAME
, buffer
, sizeof(buffer
), &errorCode
);
853 if (U_SUCCESS(errorCode
))
855 OUString sName
= OUString::createFromAscii(buffer
);
856 if(!sName
.isEmpty() && sName
.toAsciiLowerCase().indexOf(aKeyword
.toAsciiLowerCase()) >= 0)
857 m_xSearchSet
->AppendCharToList(sChar
);
862 toggleSearchView(false);
867 IMPL_LINK(SvxCharacterMap
, CharClickHdl
, SvxCharView
*, rView
, void)
871 m_aShowChar
.SetText( rView
->GetText() );
872 m_aShowChar
.SetFont(rView
->GetFont());
873 m_aShowChar
.Invalidate();
875 setFavButtonState(rView
->GetText(), rView
->GetFont().GetFamilyName());//check state
877 // Get the hexadecimal code
878 OUString charValue
= rView
->GetText();
880 sal_UCS4 cChar
= charValue
.iterateCodePoints(&tmp
, -1);
881 OUString aHexText
= OUString::number(cChar
, 16).toAsciiUpperCase();
883 // Get the decimal code
884 OUString aDecimalText
= OUString::number(cChar
);
886 m_xHexCodeText
->set_text(aHexText
);
887 m_xDecimalCodeText
->set_text(aDecimalText
);
891 m_xOKBtn
->set_sensitive(true);
894 IMPL_LINK_NOARG(SvxCharacterMap
, CharDoubleClickHdl
, SvxShowCharSet
*, void)
896 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
897 // using the new UCS4 constructor
898 OUString
aOUStr( &cChar
, 1 );
899 setFavButtonState(aOUStr
, aFont
.GetFamilyName());
900 insertCharToDoc(aOUStr
);
903 IMPL_LINK_NOARG(SvxCharacterMap
, SearchCharDoubleClickHdl
, SvxShowCharSet
*, void)
905 sal_UCS4 cChar
= m_xSearchSet
->GetSelectCharacter();
906 // using the new UCS4 constructor
907 OUString
aOUStr( &cChar
, 1 );
908 setFavButtonState(aOUStr
, aFont
.GetFamilyName());
909 insertCharToDoc(aOUStr
);
912 IMPL_LINK_NOARG(SvxCharacterMap
, CharSelectHdl
, SvxShowCharSet
*, void)
914 m_xOKBtn
->set_sensitive(true);
917 IMPL_LINK_NOARG(SvxCharacterMap
, SearchCharSelectHdl
, SvxShowCharSet
*, void)
919 m_xOKBtn
->set_sensitive(true);
922 IMPL_LINK_NOARG(SvxCharacterMap
, InsertClickHdl
, weld::Button
&, void)
924 insertCharToDoc(m_aShowChar
.GetText());
925 m_xDialog
->response(RET_OK
);
928 IMPL_LINK_NOARG(SvxCharacterMap
, FavSelectHdl
, weld::Button
&, void)
930 if (m_xFavouritesBtn
->get_label().match(CuiResId(RID_SVXSTR_ADD_FAVORITES
)))
932 updateFavCharacterList(m_aShowChar
.GetText(), m_aShowChar
.GetFont().GetFamilyName());
933 setFavButtonState(m_aShowChar
.GetText(), m_aShowChar
.GetFont().GetFamilyName());
937 deleteFavCharacterFromList(m_aShowChar
.GetText(), m_aShowChar
.GetFont().GetFamilyName());
938 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES
));
939 m_xFavouritesBtn
->set_sensitive(false);
942 updateFavCharControl();
945 IMPL_LINK_NOARG(SvxCharacterMap
, FavClickHdl
, SvxShowCharSet
*, void)
947 getFavCharacterList();
948 updateFavCharControl();
951 IMPL_LINK_NOARG(SvxCharacterMap
, CharHighlightHdl
, SvxShowCharSet
*, void)
955 OUString aDecimalText
;
956 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
957 bool bSelect
= (cChar
> 0);
962 // using the new UCS4 constructor
963 aText
= OUString( &cChar
, 1 );
964 // Get the hexadecimal code
965 aHexText
= OUString::number(cChar
, 16).toAsciiUpperCase();
966 // Get the decimal code
967 aDecimalText
= OUString::number(cChar
);
970 // Update the hex and decimal codes only if necessary
971 if (!m_xHexCodeText
->get_text().equalsIgnoreAsciiCase(aHexText
))
972 m_xHexCodeText
->set_text(aHexText
);
973 if (m_xDecimalCodeText
->get_text() != aDecimalText
)
974 m_xDecimalCodeText
->set_text( aDecimalText
);
976 const Subset
* pSubset
= nullptr;
978 pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
980 m_xSubsetLB
->set_active_text(pSubset
->GetName());
982 m_xSubsetLB
->set_active(-1);
985 m_aShowChar
.SetText( aText
);
986 m_aShowChar
.SetFont( aFont
);
987 m_aShowChar
.Invalidate();
989 setFavButtonState(aText
, aFont
.GetFamilyName());
992 IMPL_LINK_NOARG(SvxCharacterMap
, SearchCharHighlightHdl
, SvxShowCharSet
*, void)
996 OUString aDecimalText
;
997 sal_UCS4 cChar
= m_xSearchSet
->GetSelectCharacter();
998 bool bSelect
= (cChar
> 0);
1003 aText
= OUString( &cChar
, 1 );
1004 // Get the hexadecimal code
1005 aHexText
= OUString::number(cChar
, 16).toAsciiUpperCase();
1006 // Get the decimal code
1007 aDecimalText
= OUString::number(cChar
);
1010 // Update the hex and decimal codes only if necessary
1011 if (!m_xHexCodeText
->get_text().equalsIgnoreAsciiCase(aHexText
))
1012 m_xHexCodeText
->set_text(aHexText
);
1013 if (m_xDecimalCodeText
->get_text() != aDecimalText
)
1014 m_xDecimalCodeText
->set_text( aDecimalText
);
1016 const Subset
* pSubset
= nullptr;
1018 pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
1020 m_xSubsetLB
->set_active_text(pSubset
->GetName());
1022 m_xSubsetLB
->set_active(-1);
1025 if(m_xSearchSet
->HasFocus())
1027 m_aShowChar
.SetText( aText
);
1028 m_aShowChar
.SetFont( aFont
);
1029 m_aShowChar
.Invalidate();
1031 setFavButtonState(aText
, aFont
.GetFamilyName());
1035 void SvxCharacterMap::selectCharByCode(Radix radix
)
1037 OUString aCodeString
;
1040 case Radix::decimal
:
1041 aCodeString
= m_xDecimalCodeText
->get_text();
1043 case Radix::hexadecimal
:
1044 aCodeString
= m_xHexCodeText
->get_text();
1047 // Convert the code back to a character using the appropriate radix
1048 sal_UCS4 cChar
= aCodeString
.toUInt32(static_cast<sal_Int16
> (radix
));
1049 // Use FontCharMap::HasChar(sal_UCS4 cChar) to see if the desired character is in the font
1050 FontCharMapRef xFontCharMap
= m_xShowSet
->GetFontCharMap();
1051 if (xFontCharMap
->HasChar(cChar
))
1052 // Select the corresponding character
1055 m_xCharName
->set_label(CuiResId(RID_SVXSTR_MISSING_CHAR
));
1056 m_aShowChar
.SetText(" ");
1059 case Radix::decimal
:
1060 m_xHexCodeText
->set_text(OUString::number(cChar
, 16));
1062 case Radix::hexadecimal
:
1063 m_xDecimalCodeText
->set_text(OUString::number(cChar
));
1069 IMPL_LINK_NOARG(SvxCharacterMap
, DecimalCodeChangeHdl
, weld::Entry
&, void)
1071 selectCharByCode(Radix::decimal
);
1074 IMPL_LINK_NOARG(SvxCharacterMap
, HexCodeChangeHdl
, weld::Entry
&, void)
1076 selectCharByCode(Radix::hexadecimal
);
1079 IMPL_LINK_NOARG(SvxCharacterMap
, CharPreSelectHdl
, SvxShowCharSet
*, void)
1081 // adjust subset selection
1084 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
1086 setFavButtonState(OUString(&cChar
, 1), aFont
.GetFamilyName());
1087 const Subset
* pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
1089 m_xSubsetLB
->set_active_text(pSubset
->GetName());
1092 m_xOKBtn
->set_sensitive(true);
1095 IMPL_LINK_NOARG(SvxCharacterMap
, SearchCharPreSelectHdl
, SvxShowCharSet
*, void)
1097 // adjust subset selection
1100 sal_UCS4 cChar
= m_xSearchSet
->GetSelectCharacter();
1102 setFavButtonState(OUString(&cChar
, 1), aFont
.GetFamilyName());
1103 const Subset
* pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
1105 m_xSubsetLB
->set_active_text(pSubset
->GetName());
1108 m_xOKBtn
->set_sensitive(true);
1111 // class SvxShowText =====================================================
1112 SvxShowText::SvxShowText(const VclPtr
<VirtualDevice
>& rVirDev
)
1113 : m_xVirDev(rVirDev
)
1119 void SvxShowText::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
1121 CustomWidgetController::SetDrawingArea(pDrawingArea
);
1122 vcl::Font aFont
= m_xVirDev
->GetFont();
1123 Size
aFontSize(aFont
.GetFontSize().Width() * 5, aFont
.GetFontSize().Height() * 5);
1124 aFont
.SetFontSize(aFontSize
);
1125 m_xVirDev
->Push(PUSH_ALLFONT
);
1126 m_xVirDev
->SetFont(aFont
);
1127 pDrawingArea
->set_size_request(m_xVirDev
->approximate_digit_width() + 2 * 12,
1128 m_xVirDev
->LogicToPixel(aFontSize
).Height() * 2);
1132 void SvxShowText::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
1134 rRenderContext
.SetFont(m_aFont
);
1136 Color aTextCol
= rRenderContext
.GetTextColor();
1137 Color aFillCol
= rRenderContext
.GetFillColor();
1139 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1140 const Color
aWindowTextColor(rStyleSettings
.GetDialogTextColor());
1141 const Color
aWindowColor(rStyleSettings
.GetWindowColor());
1142 rRenderContext
.SetTextColor(aWindowTextColor
);
1143 rRenderContext
.SetFillColor(aWindowColor
);
1145 const OUString aText
= GetText();
1147 Size
aSize(GetOutputSizePixel());
1148 long nAvailWidth
= aSize
.Width();
1149 long nWinHeight
= aSize
.Height();
1151 bool bGotBoundary
= true;
1152 bool bShrankFont
= false;
1153 vcl::Font
aOrigFont(rRenderContext
.GetFont());
1154 Size
aFontSize(aOrigFont
.GetFontSize());
1155 ::tools::Rectangle aBoundRect
;
1157 for (long nFontHeight
= aFontSize
.Height(); nFontHeight
> 0; nFontHeight
-= 5)
1159 if (!rRenderContext
.GetTextBoundRect( aBoundRect
, aText
) || aBoundRect
.IsEmpty())
1161 bGotBoundary
= false;
1166 //only shrink in the single glyph large view mode
1167 long nTextWidth
= aBoundRect
.GetWidth();
1168 if (nAvailWidth
> nTextWidth
)
1170 vcl::Font
aFont(aOrigFont
);
1171 aFontSize
.setHeight( nFontHeight
);
1172 aFont
.SetFontSize(aFontSize
);
1173 rRenderContext
.SetFont(aFont
);
1174 mnY
= (nWinHeight
- rRenderContext
.GetTextHeight()) / 2;
1178 Point
aPoint(2, mnY
);
1179 // adjust position using ink boundary if possible
1181 aPoint
.setX( (aSize
.Width() - rRenderContext
.GetTextWidth(aText
)) / 2 );
1184 // adjust position before it gets out of bounds
1185 aBoundRect
+= aPoint
;
1187 // shift back vertically if needed
1188 int nYLDelta
= aBoundRect
.Top();
1189 int nYHDelta
= aSize
.Height() - aBoundRect
.Bottom();
1191 aPoint
.AdjustY( -(nYLDelta
- 1) );
1192 else if( nYHDelta
<= 0 )
1193 aPoint
.AdjustY(nYHDelta
- 1 );
1197 // move glyph to middle of cell
1198 aPoint
.setX( -aBoundRect
.Left() + (aSize
.Width() - aBoundRect
.GetWidth()) / 2 );
1202 // shift back horizontally if needed
1203 int nXLDelta
= aBoundRect
.Left();
1204 int nXHDelta
= aSize
.Width() - aBoundRect
.Right();
1206 aPoint
.AdjustX( -(nXLDelta
- 1) );
1207 else if( nXHDelta
<= 0 )
1208 aPoint
.AdjustX(nXHDelta
- 1 );
1212 rRenderContext
.DrawRect(tools::Rectangle(Point(0, 0), aSize
));
1213 rRenderContext
.DrawText(aPoint
, aText
);
1214 rRenderContext
.SetTextColor(aTextCol
);
1215 rRenderContext
.SetFillColor(aFillCol
);
1217 rRenderContext
.SetFont(aOrigFont
);
1220 void SvxShowText::SetFont( const vcl::Font
& rFont
)
1222 long nWinHeight
= GetOutputSizePixel().Height();
1225 m_aFont
.SetWeight(WEIGHT_NORMAL
);
1226 m_aFont
.SetAlignment(ALIGN_TOP
);
1227 m_aFont
.SetFontSize(m_xVirDev
->PixelToLogic(Size(0, nWinHeight
/ 2)));
1228 m_aFont
.SetTransparent(true);
1230 m_xVirDev
->Push(PUSH_ALLFONT
);
1231 m_xVirDev
->SetFont(m_aFont
);
1232 mnY
= (nWinHeight
- m_xVirDev
->GetTextHeight()) / 2;
1238 void SvxShowText::Resize()
1240 SetFont(GetFont()); //force recalculation of size
1243 void SvxShowText::SetText(const OUString
& rText
)
1249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */