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 <svl/eitem.hxx>
24 #include <svl/intitem.hxx>
25 #include <svl/itempool.hxx>
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 <comphelper/processfactory.hxx>
35 #include <comphelper/dispatchcommand.hxx>
37 #include <dialmgr.hxx>
38 #include <cui/cuicharmap.hxx>
39 #include <sfx2/app.hxx>
40 #include <svx/svxids.hrc>
41 #include <editeng/editids.hrc>
42 #include <editeng/fontitem.hxx>
43 #include <strings.hrc>
44 #include <unicode/uchar.h>
45 #include <unicode/utypes.h>
49 SvxCharacterMap::SvxCharacterMap(weld::Widget
* pParent
, const SfxItemSet
* pSet
,
50 const css::uno::Reference
<css::frame::XFrame
>& rFrame
)
51 : SfxDialogController(pParent
, "cui/ui/specialcharacters.ui", "SpecialCharactersDialog")
52 , m_xVirDev(VclPtr
<VirtualDevice
>::Create())
55 , mxContext(comphelper::getProcessComponentContext())
56 , m_aRecentCharView
{SvxCharView(m_xVirDev
),
57 SvxCharView(m_xVirDev
),
58 SvxCharView(m_xVirDev
),
59 SvxCharView(m_xVirDev
),
60 SvxCharView(m_xVirDev
),
61 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 , m_aFavCharView
{SvxCharView(m_xVirDev
),
73 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 , m_aShowChar(m_xVirDev
)
89 , m_xOKBtn(m_xFrame
.is() ? m_xBuilder
->weld_button("insert") : m_xBuilder
->weld_button("ok"))
90 , m_xFontText(m_xBuilder
->weld_label("fontft"))
91 , m_xFontLB(m_xBuilder
->weld_combo_box("fontlb"))
92 , m_xSubsetText(m_xBuilder
->weld_label("subsetft"))
93 , m_xSubsetLB(m_xBuilder
->weld_combo_box("subsetlb"))
94 , m_xSearchText(m_xBuilder
->weld_entry("search"))
95 , m_xHexCodeText(m_xBuilder
->weld_entry("hexvalue"))
96 , m_xDecimalCodeText(m_xBuilder
->weld_entry("decimalvalue"))
97 , m_xFavouritesBtn(m_xBuilder
->weld_button("favbtn"))
98 , m_xCharName(m_xBuilder
->weld_label("charname"))
99 , m_xRecentGrid(m_xBuilder
->weld_widget("viewgrid"))
100 , m_xFavGrid(m_xBuilder
->weld_widget("favgrid"))
101 , m_xShowChar(new weld::CustomWeld(*m_xBuilder
, "showchar", m_aShowChar
))
102 , m_xRecentCharView
{std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar1", m_aRecentCharView
[0]),
103 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar2", m_aRecentCharView
[1]),
104 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar3", m_aRecentCharView
[2]),
105 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar4", m_aRecentCharView
[3]),
106 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar5", m_aRecentCharView
[4]),
107 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar6", m_aRecentCharView
[5]),
108 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar7", m_aRecentCharView
[6]),
109 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar8", m_aRecentCharView
[7]),
110 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar9", m_aRecentCharView
[8]),
111 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar10", m_aRecentCharView
[9]),
112 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar11", m_aRecentCharView
[10]),
113 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar12", m_aRecentCharView
[11]),
114 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar13", m_aRecentCharView
[12]),
115 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar14", m_aRecentCharView
[13]),
116 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar15", m_aRecentCharView
[14]),
117 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "viewchar16", m_aRecentCharView
[15])}
118 , m_xFavCharView
{std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar1", m_aFavCharView
[0]),
119 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar2", m_aFavCharView
[1]),
120 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar3", m_aFavCharView
[2]),
121 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar4", m_aFavCharView
[3]),
122 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar5", m_aFavCharView
[4]),
123 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar6", m_aFavCharView
[5]),
124 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar7", m_aFavCharView
[6]),
125 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar8", m_aFavCharView
[7]),
126 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar9", m_aFavCharView
[8]),
127 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar10", m_aFavCharView
[9]),
128 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar11", m_aFavCharView
[10]),
129 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar12", m_aFavCharView
[11]),
130 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar13", m_aFavCharView
[12]),
131 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar14", m_aFavCharView
[13]),
132 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar15", m_aFavCharView
[14]),
133 std::make_unique
<weld::CustomWeld
>(*m_xBuilder
, "favchar16", m_aFavCharView
[15])}
134 , m_xShowSet(new SvxShowCharSet(m_xBuilder
->weld_scrolled_window("showscroll"), m_xVirDev
))
135 , m_xShowSetArea(new weld::CustomWeld(*m_xBuilder
, "showcharset", *m_xShowSet
))
136 , m_xSearchSet(new SvxSearchCharSet(m_xBuilder
->weld_scrolled_window("searchscroll"), m_xVirDev
))
137 , m_xSearchSetArea(new weld::CustomWeld(*m_xBuilder
, "searchcharset", *m_xSearchSet
))
139 m_aShowChar
.SetCentered(true);
140 m_xFontLB
->make_sorted();
141 //lock the size request of this widget to the width of all possible entries
142 fillAllSubsets(*m_xSubsetLB
);
143 m_xSubsetLB
->set_size_request(m_xSubsetLB
->get_preferred_size().Width(), -1);
144 m_xCharName
->set_size_request(m_aShowChar
.get_preferred_size().Width(), m_xCharName
->get_text_height() * 4);
145 //lock the size request of this widget to the width of the original .ui string
146 m_xHexCodeText
->set_size_request(m_xHexCodeText
->get_preferred_size().Width(), -1);
147 //so things don't jump around if all the children are hidden
148 m_xRecentGrid
->set_size_request(-1, m_aRecentCharView
[0].get_preferred_size().Height());
149 m_xFavGrid
->set_size_request(-1, m_aFavCharView
[0].get_preferred_size().Height());
153 const SfxInt32Item
* pCharItem
= SfxItemSet::GetItem
<SfxInt32Item
>(pSet
, SID_ATTR_CHAR
, false);
155 SetChar( pCharItem
->GetValue() );
157 const SfxBoolItem
* pDisableItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSet
, FN_PARAM_2
, false);
158 if ( pDisableItem
&& pDisableItem
->GetValue() )
159 DisableFontSelection();
161 const SvxFontItem
* pFontItem
= SfxItemSet::GetItem
<SvxFontItem
>(pSet
, SID_ATTR_CHAR_FONT
, false);
162 const SfxStringItem
* pFontNameItem
= SfxItemSet::GetItem
<SfxStringItem
>(pSet
, SID_FONT_NAME
, false);
165 vcl::Font
aTmpFont( pFontItem
->GetFamilyName(), pFontItem
->GetStyleName(), GetCharFont().GetFontSize() );
166 aTmpFont
.SetCharSet( pFontItem
->GetCharSet() );
167 aTmpFont
.SetPitch( pFontItem
->GetPitch() );
168 SetCharFont( aTmpFont
);
170 else if ( pFontNameItem
)
172 vcl::Font
aTmpFont( GetCharFont() );
173 aTmpFont
.SetFamilyName( pFontNameItem
->GetValue() );
174 SetCharFont( aTmpFont
);
177 m_xOutputSet
.reset(new SfxAllItemSet(pSet
? *pSet
->GetPool() : SfxGetpApp()->GetPool()));
179 m_xSearchSet
->Hide();
182 short SvxCharacterMap::run()
184 if( SvxShowCharSet::getSelectedChar() == ' ')
186 m_xOKBtn
->set_sensitive(false);
187 setFavButtonState(OUString(), OUString());
191 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
192 // using the new UCS4 constructor
193 OUString
aOUStr( &cChar
, 1 );
194 m_aShowChar
.SetText(aOUStr
);
196 setFavButtonState(aOUStr
, m_aShowChar
.GetFont().GetFamilyName());
197 m_xOKBtn
->set_sensitive(true);
200 return SfxDialogController::run();
203 void SvxCharacterMap::SetChar( sal_UCS4 c
)
205 m_xShowSet
->SelectCharacter( c
);
206 setFavButtonState(OUString(&c
, 1), aFont
.GetFamilyName());
209 sal_UCS4
SvxCharacterMap::GetChar() const
211 return m_aShowChar
.GetText().toChar();
214 void SvxCharacterMap::DisableFontSelection()
216 m_xFontText
->set_sensitive(false);
217 m_xFontLB
->set_sensitive(false);
221 void SvxCharacterMap::getRecentCharacterList()
223 //retrieve recent character list
224 css::uno::Sequence
< OUString
> rRecentCharList( officecfg::Office::Common::RecentCharacters::RecentCharacterList::get() );
225 for (int i
= 0; i
< rRecentCharList
.getLength(); ++i
)
227 maRecentCharList
.push_back(rRecentCharList
[i
]);
230 //retrieve recent character font list
231 css::uno::Sequence
< OUString
> rRecentCharFontList( officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::get() );
232 for (int i
= 0; i
< rRecentCharFontList
.getLength(); ++i
)
234 maRecentCharFontList
.push_back(rRecentCharFontList
[i
]);
239 void SvxCharacterMap::getFavCharacterList()
241 maFavCharList
.clear();
242 maFavCharFontList
.clear();
243 //retrieve recent character list
244 css::uno::Sequence
< OUString
> rFavCharList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::get() );
245 for (int i
= 0; i
< rFavCharList
.getLength(); ++i
)
247 maFavCharList
.push_back(rFavCharList
[i
]);
250 //retrieve recent character font list
251 css::uno::Sequence
< OUString
> rFavCharFontList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::get() );
252 for (int i
= 0; i
< rFavCharFontList
.getLength(); ++i
)
254 maFavCharFontList
.push_back(rFavCharFontList
[i
]);
259 void SvxCharacterMap::updateRecentCharControl()
262 for ( std::deque
< OUString
>::iterator it
= maRecentCharList
.begin(), it2
= maRecentCharFontList
.begin();
263 it
!= maRecentCharList
.end() || it2
!= maRecentCharFontList
.end();
266 m_aRecentCharView
[i
].SetText(*it
);
267 vcl::Font rFont
= m_aRecentCharView
[i
].GetFont();
268 rFont
.SetFamilyName( *it2
);
269 m_aRecentCharView
[i
].SetFont(rFont
);
270 m_aRecentCharView
[i
].Show();
275 m_aRecentCharView
[i
].SetText(OUString());
276 m_aRecentCharView
[i
].Hide();
280 void SvxCharacterMap::updateRecentCharacterList(const OUString
& sTitle
, const OUString
& rFont
)
282 auto itChar
= std::find(maRecentCharList
.begin(), maRecentCharList
.end(), sTitle
);
284 auto itChar2
= std::find(maRecentCharFontList
.begin(), maRecentCharFontList
.end(), rFont
);
286 // if recent char to be added is already in list, remove it
287 if( itChar
!= maRecentCharList
.end() && itChar2
!= maRecentCharFontList
.end() )
289 maRecentCharList
.erase( itChar
);
290 maRecentCharFontList
.erase( itChar2
);
293 if (maRecentCharList
.size() == 16)
295 maRecentCharList
.pop_back();
296 maRecentCharFontList
.pop_back();
299 maRecentCharList
.push_front(sTitle
);
300 maRecentCharFontList
.push_front(rFont
);
302 css::uno::Sequence
< OUString
> aRecentCharList(maRecentCharList
.size());
303 css::uno::Sequence
< OUString
> aRecentCharFontList(maRecentCharFontList
.size());
305 for (size_t i
= 0; i
< maRecentCharList
.size(); ++i
)
307 aRecentCharList
[i
] = maRecentCharList
[i
];
308 aRecentCharFontList
[i
] = maRecentCharFontList
[i
];
311 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
312 officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList
, batch
);
313 officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList
, batch
);
316 updateRecentCharControl();
320 void SvxCharacterMap::updateFavCharacterList(const OUString
& sTitle
, const OUString
& rFont
)
322 auto itChar
= std::find(maFavCharList
.begin(), maFavCharList
.end(), sTitle
);
324 auto itChar2
= std::find(maFavCharFontList
.begin(), maFavCharFontList
.end(), rFont
);
326 // if Fav char to be added is already in list, remove it
327 if( itChar
!= maFavCharList
.end() && itChar2
!= maFavCharFontList
.end() )
329 maFavCharList
.erase( itChar
);
330 maFavCharFontList
.erase( itChar2
);
333 if (maFavCharList
.size() == 16)
335 maFavCharList
.pop_back();
336 maFavCharFontList
.pop_back();
339 maFavCharList
.push_back(sTitle
);
340 maFavCharFontList
.push_back(rFont
);
342 css::uno::Sequence
< OUString
> aFavCharList(maFavCharList
.size());
343 css::uno::Sequence
< OUString
> aFavCharFontList(maFavCharFontList
.size());
345 for (size_t i
= 0; i
< maFavCharList
.size(); ++i
)
347 aFavCharList
[i
] = maFavCharList
[i
];
348 aFavCharFontList
[i
] = maFavCharFontList
[i
];
351 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
352 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList
, batch
);
353 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList
, batch
);
358 void SvxCharacterMap::updateFavCharControl()
361 for ( std::deque
< OUString
>::iterator it
= maFavCharList
.begin(), it2
= maFavCharFontList
.begin();
362 it
!= maFavCharList
.end() || it2
!= maFavCharFontList
.end();
365 m_aFavCharView
[i
].SetText(*it
);
366 vcl::Font rFont
= m_aFavCharView
[i
].GetFont();
367 rFont
.SetFamilyName( *it2
);
368 m_aFavCharView
[i
].SetFont(rFont
);
369 m_aFavCharView
[i
].Show();
374 m_aFavCharView
[i
].SetText(OUString());
375 m_aFavCharView
[i
].Hide();
377 m_xShowSet
->getFavCharacterList();
378 m_xSearchSet
->getFavCharacterList();
381 void SvxCharacterMap::deleteFavCharacterFromList(const OUString
& sTitle
, const OUString
& rFont
)
383 auto itChar
= std::find(maFavCharList
.begin(), maFavCharList
.end(), sTitle
);
385 auto itChar2
= std::find(maFavCharFontList
.begin(), maFavCharFontList
.end(), rFont
);
387 // if Fav char to be added is already in list, remove it
388 if( itChar
!= maFavCharList
.end() && itChar2
!= maFavCharFontList
.end() )
390 maFavCharList
.erase( itChar
);
391 maFavCharFontList
.erase( itChar2
);
394 css::uno::Sequence
< OUString
> aFavCharList(maFavCharList
.size());
395 css::uno::Sequence
< OUString
> aFavCharFontList(maFavCharFontList
.size());
397 for (size_t i
= 0; i
< maFavCharList
.size(); ++i
)
399 aFavCharList
[i
] = maFavCharList
[i
];
400 aFavCharFontList
[i
] = maFavCharFontList
[i
];
403 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
404 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList
, batch
);
405 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList
, batch
);
409 void SvxCharacterMap::init()
411 aFont
= m_xVirDev
->GetFont();
412 aFont
.SetTransparent( true );
413 aFont
.SetFamily( FAMILY_DONTKNOW
);
414 aFont
.SetPitch( PITCH_DONTKNOW
);
415 aFont
.SetCharSet( RTL_TEXTENCODING_DONTKNOW
);
417 OUString
aDefStr( aFont
.GetFamilyName() );
419 int nCount
= m_xVirDev
->GetDevFontCount();
420 std::vector
<weld::ComboBoxEntry
> aEntries
;
421 aEntries
.reserve(nCount
);
422 for (int i
= 0; i
< nCount
; ++i
)
424 OUString
aFontName( m_xVirDev
->GetDevFont( i
).GetFamilyName() );
425 if (aFontName
!= aLastName
)
427 aLastName
= aFontName
;
428 aEntries
.emplace_back(aFontName
, OUString::number(i
));
431 m_xFontLB
->insert_vector(aEntries
, true);
432 // the font may not be in the list =>
433 // try to find a font name token in list and select found font,
434 // else select topmost entry
435 bool bFound
= (m_xFontLB
->find_text(aDefStr
) == -1);
438 sal_Int32 nIndex
= 0;
441 OUString aToken
= aDefStr
.getToken(0, ';', nIndex
);
442 if (m_xFontLB
->find_text(aToken
) != -1)
449 while ( nIndex
>= 0 );
453 m_xFontLB
->set_active_text(aDefStr
);
454 else if (m_xFontLB
->get_count() )
455 m_xFontLB
->set_active(0);
456 FontSelectHdl(*m_xFontLB
);
457 if (m_xSubsetLB
->get_count())
458 m_xSubsetLB
->set_active(0);
460 m_xFontLB
->connect_changed(LINK( this, SvxCharacterMap
, FontSelectHdl
));
461 m_xSubsetLB
->connect_changed(LINK( this, SvxCharacterMap
, SubsetSelectHdl
));
462 m_xOKBtn
->connect_clicked(LINK(this, SvxCharacterMap
, InsertClickHdl
));
465 m_xShowSet
->SetDoubleClickHdl( LINK( this, SvxCharacterMap
, CharDoubleClickHdl
) );
466 m_xShowSet
->SetSelectHdl( LINK( this, SvxCharacterMap
, CharSelectHdl
) );
467 m_xShowSet
->SetHighlightHdl( LINK( this, SvxCharacterMap
, CharHighlightHdl
) );
468 m_xShowSet
->SetPreSelectHdl( LINK( this, SvxCharacterMap
, CharPreSelectHdl
) );
469 m_xShowSet
->SetFavClickHdl( LINK( this, SvxCharacterMap
, FavClickHdl
) );
471 m_xSearchSet
->SetDoubleClickHdl( LINK( this, SvxCharacterMap
, SearchCharDoubleClickHdl
) );
472 m_xSearchSet
->SetSelectHdl( LINK( this, SvxCharacterMap
, SearchCharSelectHdl
) );
473 m_xSearchSet
->SetHighlightHdl( LINK( this, SvxCharacterMap
, SearchCharHighlightHdl
) );
474 m_xSearchSet
->SetPreSelectHdl( LINK( this, SvxCharacterMap
, SearchCharPreSelectHdl
) );
475 m_xSearchSet
->SetFavClickHdl( LINK( this, SvxCharacterMap
, FavClickHdl
) );
477 m_xDecimalCodeText
->connect_changed( LINK( this, SvxCharacterMap
, DecimalCodeChangeHdl
) );
478 m_xHexCodeText
->connect_changed( LINK( this, SvxCharacterMap
, HexCodeChangeHdl
) );
479 m_xFavouritesBtn
->connect_clicked( LINK(this, SvxCharacterMap
, FavSelectHdl
));
481 // tdf#117038 set the buttons width to its max possible width so it doesn't
482 // make layout change when the label changes
483 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_REMOVE_FAVORITES
));
484 auto nMaxWidth
= m_xFavouritesBtn
->get_preferred_size().Width();
485 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES
));
486 nMaxWidth
= std::max(nMaxWidth
, m_xFavouritesBtn
->get_preferred_size().Width());
487 m_xFavouritesBtn
->set_size_request(nMaxWidth
, -1);
489 if( SvxShowCharSet::getSelectedChar() == ' ')
491 m_xOKBtn
->set_sensitive(false);
495 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
496 // using the new UCS4 constructor
497 OUString
aOUStr( &cChar
, 1 );
498 m_aShowChar
.SetText(aOUStr
);
500 setFavButtonState(aOUStr
, aDefStr
);
501 m_xOKBtn
->set_sensitive(true);
504 getRecentCharacterList();
505 updateRecentCharControl();
507 getFavCharacterList();
508 updateFavCharControl();
510 bool bHasInsert
= m_xFrame
.is();
512 for(int i
= 0; i
< 16; i
++)
514 m_aRecentCharView
[i
].SetHasInsert(bHasInsert
);
515 m_aRecentCharView
[i
].setMouseClickHdl(LINK(this,SvxCharacterMap
, CharClickHdl
));
516 m_aRecentCharView
[i
].setClearClickHdl(LINK(this,SvxCharacterMap
, RecentClearClickHdl
));
517 m_aRecentCharView
[i
].setClearAllClickHdl(LINK(this,SvxCharacterMap
, RecentClearAllClickHdl
));
518 m_aFavCharView
[i
].SetHasInsert(bHasInsert
);
519 m_aFavCharView
[i
].setMouseClickHdl(LINK(this,SvxCharacterMap
, CharClickHdl
));
520 m_aFavCharView
[i
].setClearClickHdl(LINK(this,SvxCharacterMap
, FavClearClickHdl
));
521 m_aFavCharView
[i
].setClearAllClickHdl(LINK(this,SvxCharacterMap
, FavClearAllClickHdl
));
526 m_xSearchText
->connect_focus_in(LINK( this, SvxCharacterMap
, SearchFieldGetFocusHdl
));
527 m_xSearchText
->connect_changed(LINK(this, SvxCharacterMap
, SearchUpdateHdl
));
530 bool SvxCharacterMap::isFavChar(const OUString
& sTitle
, const OUString
& rFont
)
532 auto isFavCharTitleExists
= std::any_of(maFavCharList
.begin(),
534 [sTitle
] (const OUString
& a
) { return a
== sTitle
; });
536 auto isFavCharFontExists
= std::any_of(maFavCharFontList
.begin(),
537 maFavCharFontList
.end(),
538 [rFont
] (const OUString
& a
) { return a
== rFont
; });
540 // if Fav char to be added is already in list, remove it
541 return isFavCharTitleExists
&& isFavCharFontExists
;
545 void SvxCharacterMap::setFavButtonState(const OUString
& sTitle
, const OUString
& rFont
)
547 if(sTitle
.isEmpty() || rFont
.isEmpty())
549 m_xFavouritesBtn
->set_sensitive(false);
553 m_xFavouritesBtn
->set_sensitive(true);
555 if (isFavChar(sTitle
, rFont
))
557 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_REMOVE_FAVORITES
));
561 if(maFavCharList
.size() == 16)
563 m_xFavouritesBtn
->set_sensitive(false);
566 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES
));
571 void SvxCharacterMap::SetCharFont( const vcl::Font
& rFont
)
573 // first get the underlying info in order to get font names
574 // like "Times New Roman;Times" resolved
575 vcl::Font
aTmp(m_xVirDev
->GetFontMetric(rFont
));
577 if (aTmp
.GetFamilyName() == "StarSymbol" && m_xFontLB
->find_text(aTmp
.GetFamilyName()) == -1)
579 //if for some reason, like font in an old document, StarSymbol is requested and it's not available, then
580 //try OpenSymbol instead
581 aTmp
.SetFamilyName("OpenSymbol");
584 if (m_xFontLB
->find_text(aTmp
.GetFamilyName()) == -1)
587 m_xFontLB
->set_active_text(aTmp
.GetFamilyName());
589 FontSelectHdl(*m_xFontLB
);
590 if (m_xSubsetLB
->get_count())
591 m_xSubsetLB
->set_active(0);
594 void SvxCharacterMap::fillAllSubsets(weld::ComboBox
& rListBox
)
596 SubsetMap
aAll(nullptr);
597 std::vector
<weld::ComboBoxEntry
> aEntries
;
598 for (auto & subset
: aAll
.GetSubsetMap())
599 aEntries
.emplace_back(subset
.GetName());
600 rListBox
.insert_vector(aEntries
, true);
603 void SvxCharacterMap::insertCharToDoc(const OUString
& sGlyph
)
609 uno::Reference
< uno::XComponentContext
> xContext( comphelper::getProcessComponentContext() );
611 uno::Sequence
<beans::PropertyValue
> aArgs(2);
612 aArgs
[0].Name
= "Symbols";
613 aArgs
[0].Value
<<= sGlyph
;
615 aArgs
[1].Name
= "FontName";
616 aArgs
[1].Value
<<= aFont
.GetFamilyName();
617 comphelper::dispatchCommand(".uno:InsertSymbol", m_xFrame
, aArgs
);
619 updateRecentCharacterList(sGlyph
, aFont
.GetFamilyName());
623 sal_UCS4 cChar
= sGlyph
.iterateCodePoints(&tmp
);
624 const SfxItemPool
* pPool
= m_xOutputSet
->GetPool();
625 m_xOutputSet
->Put( SfxStringItem( pPool
->GetWhich(SID_CHARMAP
), sGlyph
) );
626 m_xOutputSet
->Put( SvxFontItem( aFont
.GetFamilyType(), aFont
.GetFamilyName(),
627 aFont
.GetStyleName(), aFont
.GetPitch(), aFont
.GetCharSet(), pPool
->GetWhich(SID_ATTR_CHAR_FONT
) ) );
628 m_xOutputSet
->Put( SfxStringItem( pPool
->GetWhich(SID_FONT_NAME
), aFont
.GetFamilyName() ) );
629 m_xOutputSet
->Put( SfxInt32Item( pPool
->GetWhich(SID_ATTR_CHAR
), cChar
) );
633 IMPL_LINK_NOARG(SvxCharacterMap
, FontSelectHdl
, weld::ComboBox
&, void)
635 const sal_uInt32 nFont
= m_xFontLB
->get_active_id().toUInt32();
636 aFont
= m_xVirDev
->GetDevFont(nFont
);
637 aFont
.SetWeight( WEIGHT_DONTKNOW
);
638 aFont
.SetItalic( ITALIC_NONE
);
639 aFont
.SetWidthType( WIDTH_DONTKNOW
);
640 aFont
.SetPitch( PITCH_DONTKNOW
);
641 aFont
.SetFamily( FAMILY_DONTKNOW
);
643 // notify children using this font
644 m_xShowSet
->SetFont( aFont
);
645 m_xSearchSet
->SetFont( aFont
);
646 m_aShowChar
.SetFont( aFont
);
649 SearchUpdateHdl(*m_xSearchText
);
650 SearchCharHighlightHdl(m_xSearchSet
.get());
653 // setup unicode subset listbar with font specific subsets,
654 // hide unicode subset listbar for symbol fonts
655 // TODO: get info from the Font once it provides it
657 m_xSubsetLB
->clear();
659 bool bNeedSubset
= (aFont
.GetCharSet() != RTL_TEXTENCODING_SYMBOL
);
662 FontCharMapRef xFontCharMap
= m_xShowSet
->GetFontCharMap();
663 pSubsetMap
.reset(new SubsetMap( xFontCharMap
));
665 // update subset listbox for new font's unicode subsets
666 for (auto const& subset
: pSubsetMap
->GetSubsetMap())
668 m_xSubsetLB
->append(OUString::number(reinterpret_cast<sal_uInt64
>(&subset
)), subset
.GetName());
669 // NOTE: subset must live at least as long as the selected font
672 if (m_xSubsetLB
->get_count() <= 1)
676 m_xSubsetText
->set_sensitive(bNeedSubset
);
677 m_xSubsetLB
->set_sensitive(bNeedSubset
);
679 // tdf#118304 reselect current glyph to see if its still there in new font
680 selectCharByCode(Radix::hexadecimal
);
683 void SvxCharacterMap::toggleSearchView(bool state
)
685 isSearchMode
= state
;
686 m_xHexCodeText
->set_editable(!state
);
687 m_xDecimalCodeText
->set_editable(!state
);
688 m_xSubsetLB
->set_sensitive(!state
);
692 m_xSearchSet
->Show();
697 m_xSearchSet
->Hide();
702 void SvxCharacterMap::setCharName(sal_UCS4 nDecimalValue
)
704 /* get the character name */
705 UErrorCode errorCode
= U_ZERO_ERROR
;
706 // icu has a private uprv_getMaxCharNameLength function which returns the max possible
707 // length of this property. Unicode 3.2 max char name length was 83
709 u_charName(nDecimalValue
, U_UNICODE_CHAR_NAME
, buffer
, sizeof(buffer
), &errorCode
);
710 if (U_SUCCESS(errorCode
))
711 m_xCharName
->set_label(OUString::createFromAscii(buffer
));
714 IMPL_LINK_NOARG(SvxCharacterMap
, SubsetSelectHdl
, weld::ComboBox
&, void)
716 const sal_Int32 nPos
= m_xSubsetLB
->get_active();
717 const Subset
* pSubset
= reinterpret_cast<const Subset
*>(m_xSubsetLB
->get_active_id().toUInt64());
719 if( pSubset
&& !isSearchMode
)
721 sal_UCS4 cFirst
= pSubset
->GetRangeMin();
722 m_xShowSet
->SelectCharacter( cFirst
);
724 setFavButtonState(OUString(&cFirst
, 1), aFont
.GetFamilyName());
725 m_xSubsetLB
->set_active(nPos
);
727 else if( pSubset
&& isSearchMode
)
729 m_xSearchSet
->SelectCharacter( pSubset
);
731 const Subset
* curSubset
= nullptr;
733 curSubset
= pSubsetMap
->GetSubsetByUnicode( m_xSearchSet
->GetSelectCharacter() );
735 m_xSubsetLB
->set_active_text(curSubset
->GetName());
737 m_xSubsetLB
->set_active(-1);
739 sal_UCS4 sChar
= m_xSearchSet
->GetSelectCharacter();
740 setFavButtonState(OUString(&sChar
, 1), aFont
.GetFamilyName());
744 IMPL_LINK(SvxCharacterMap
, RecentClearClickHdl
, SvxCharView
*, rView
, void)
746 const OUString
& sTitle
= rView
->GetText();
747 auto itChar
= std::find(maRecentCharList
.begin(), maRecentCharList
.end(), sTitle
);
749 OUString sFont
= rView
->GetFont().GetFamilyName();
750 auto itChar2
= std::find(maRecentCharFontList
.begin(), maRecentCharFontList
.end(), sFont
);
752 // if recent char to be added is already in list, remove it
753 if( itChar
!= maRecentCharList
.end() && itChar2
!= maRecentCharFontList
.end() )
755 maRecentCharList
.erase( itChar
);
756 maRecentCharFontList
.erase( itChar2
);
759 css::uno::Sequence
< OUString
> aRecentCharList(maRecentCharList
.size());
760 css::uno::Sequence
< OUString
> aRecentCharFontList(maRecentCharFontList
.size());
762 for (size_t i
= 0; i
< maRecentCharList
.size(); ++i
)
764 aRecentCharList
[i
] = maRecentCharList
[i
];
765 aRecentCharFontList
[i
] = maRecentCharFontList
[i
];
768 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
769 officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList
, batch
);
770 officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList
, batch
);
773 updateRecentCharControl();
776 IMPL_LINK_NOARG(SvxCharacterMap
, RecentClearAllClickHdl
, SvxCharView
*, void)
778 css::uno::Sequence
< OUString
> aRecentCharList(0);
779 css::uno::Sequence
< OUString
> aRecentCharFontList(0);
781 maRecentCharList
.clear();
782 maRecentCharFontList
.clear();
784 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
785 officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList
, batch
);
786 officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList
, batch
);
789 updateRecentCharControl();
792 IMPL_LINK(SvxCharacterMap
, FavClearClickHdl
, SvxCharView
*, rView
, void)
794 deleteFavCharacterFromList(rView
->GetText(), rView
->GetFont().GetFamilyName());
795 updateFavCharControl();
798 IMPL_LINK_NOARG(SvxCharacterMap
, FavClearAllClickHdl
, SvxCharView
*, void)
800 css::uno::Sequence
< OUString
> aFavCharList(0);
801 css::uno::Sequence
< OUString
> aFavCharFontList(0);
803 maFavCharList
.clear();
804 maFavCharFontList
.clear();
806 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create(mxContext
));
807 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList
, batch
);
808 officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList
, batch
);
811 updateFavCharControl();
814 IMPL_LINK_NOARG(SvxCharacterMap
, SearchFieldGetFocusHdl
, weld::Widget
&, void)
816 m_xOKBtn
->set_sensitive(false);
819 IMPL_LINK_NOARG(SvxCharacterMap
, SearchUpdateHdl
, weld::Entry
&, void)
821 if (!m_xSearchText
->get_text().isEmpty())
823 m_xSearchSet
->ClearPreviousData();
824 OUString aKeyword
= m_xSearchText
->get_text();
826 toggleSearchView(true);
828 FontCharMapRef xFontCharMap
= m_xSearchSet
->GetFontCharMap();
830 sal_UCS4 sChar
= xFontCharMap
->GetFirstChar();
831 while(sChar
!= xFontCharMap
->GetLastChar())
833 UErrorCode errorCode
= U_ZERO_ERROR
;
835 u_charName(sChar
, U_UNICODE_CHAR_NAME
, buffer
, sizeof(buffer
), &errorCode
);
836 if (U_SUCCESS(errorCode
))
838 OUString sName
= OUString::createFromAscii(buffer
);
839 if(!sName
.isEmpty() && sName
.toAsciiLowerCase().indexOf(aKeyword
.toAsciiLowerCase()) >= 0)
840 m_xSearchSet
->AppendCharToList(sChar
);
842 sChar
= xFontCharMap
->GetNextChar(sChar
);
845 UErrorCode errorCode
= U_ZERO_ERROR
;
847 u_charName(sChar
, U_UNICODE_CHAR_NAME
, buffer
, sizeof(buffer
), &errorCode
);
848 if (U_SUCCESS(errorCode
))
850 OUString sName
= OUString::createFromAscii(buffer
);
851 if(!sName
.isEmpty() && sName
.toAsciiLowerCase().indexOf(aKeyword
.toAsciiLowerCase()) >= 0)
852 m_xSearchSet
->AppendCharToList(sChar
);
857 toggleSearchView(false);
862 IMPL_LINK(SvxCharacterMap
, CharClickHdl
, SvxCharView
*, rView
, void)
866 m_aShowChar
.SetText( rView
->GetText() );
867 m_aShowChar
.SetFont(rView
->GetFont());
868 m_aShowChar
.Invalidate();
870 setFavButtonState(rView
->GetText(), rView
->GetFont().GetFamilyName());//check state
872 // Get the hexadecimal code
873 OUString charValue
= rView
->GetText();
875 sal_UCS4 cChar
= charValue
.iterateCodePoints(&tmp
, -1);
876 OUString aHexText
= OUString::number(cChar
, 16).toAsciiUpperCase();
878 // Get the decimal code
879 OUString aDecimalText
= OUString::number(cChar
);
881 m_xHexCodeText
->set_text(aHexText
);
882 m_xDecimalCodeText
->set_text(aDecimalText
);
886 m_xOKBtn
->set_sensitive(true);
889 IMPL_LINK_NOARG(SvxCharacterMap
, CharDoubleClickHdl
, SvxShowCharSet
*, void)
891 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
892 // using the new UCS4 constructor
893 OUString
aOUStr( &cChar
, 1 );
894 setFavButtonState(aOUStr
, aFont
.GetFamilyName());
895 insertCharToDoc(aOUStr
);
898 IMPL_LINK_NOARG(SvxCharacterMap
, SearchCharDoubleClickHdl
, SvxShowCharSet
*, void)
900 sal_UCS4 cChar
= m_xSearchSet
->GetSelectCharacter();
901 // using the new UCS4 constructor
902 OUString
aOUStr( &cChar
, 1 );
903 setFavButtonState(aOUStr
, aFont
.GetFamilyName());
904 insertCharToDoc(aOUStr
);
907 IMPL_LINK_NOARG(SvxCharacterMap
, CharSelectHdl
, SvxShowCharSet
*, void)
909 m_xOKBtn
->set_sensitive(true);
912 IMPL_LINK_NOARG(SvxCharacterMap
, SearchCharSelectHdl
, SvxShowCharSet
*, void)
914 m_xOKBtn
->set_sensitive(true);
917 IMPL_LINK_NOARG(SvxCharacterMap
, InsertClickHdl
, weld::Button
&, void)
919 OUString sChar
= m_aShowChar
.GetText();
920 insertCharToDoc(sChar
);
921 // Need to update recent character list, when OK button does not insert
923 updateRecentCharacterList(sChar
, aFont
.GetFamilyName());
924 m_xDialog
->response(RET_OK
);
927 IMPL_LINK_NOARG(SvxCharacterMap
, FavSelectHdl
, weld::Button
&, void)
929 if (m_xFavouritesBtn
->get_label().match(CuiResId(RID_SVXSTR_ADD_FAVORITES
)))
931 updateFavCharacterList(m_aShowChar
.GetText(), m_aShowChar
.GetFont().GetFamilyName());
932 setFavButtonState(m_aShowChar
.GetText(), m_aShowChar
.GetFont().GetFamilyName());
936 deleteFavCharacterFromList(m_aShowChar
.GetText(), m_aShowChar
.GetFont().GetFamilyName());
937 m_xFavouritesBtn
->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES
));
938 m_xFavouritesBtn
->set_sensitive(false);
941 updateFavCharControl();
944 IMPL_LINK_NOARG(SvxCharacterMap
, FavClickHdl
, SvxShowCharSet
*, void)
946 getFavCharacterList();
947 updateFavCharControl();
950 IMPL_LINK_NOARG(SvxCharacterMap
, CharHighlightHdl
, SvxShowCharSet
*, void)
954 OUString aDecimalText
;
955 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
956 bool bSelect
= (cChar
> 0);
961 // using the new UCS4 constructor
962 aText
= OUString( &cChar
, 1 );
963 // Get the hexadecimal code
964 aHexText
= OUString::number(cChar
, 16).toAsciiUpperCase();
965 // Get the decimal code
966 aDecimalText
= OUString::number(cChar
);
969 // Update the hex and decimal codes only if necessary
970 if (!m_xHexCodeText
->get_text().equalsIgnoreAsciiCase(aHexText
))
971 m_xHexCodeText
->set_text(aHexText
);
972 if (m_xDecimalCodeText
->get_text() != aDecimalText
)
973 m_xDecimalCodeText
->set_text( aDecimalText
);
975 const Subset
* pSubset
= nullptr;
977 pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
979 m_xSubsetLB
->set_active_text(pSubset
->GetName());
981 m_xSubsetLB
->set_active(-1);
984 m_aShowChar
.SetText( aText
);
985 m_aShowChar
.SetFont( aFont
);
986 m_aShowChar
.Invalidate();
988 setFavButtonState(aText
, aFont
.GetFamilyName());
991 IMPL_LINK_NOARG(SvxCharacterMap
, SearchCharHighlightHdl
, SvxShowCharSet
*, void)
995 OUString aDecimalText
;
996 sal_UCS4 cChar
= m_xSearchSet
->GetSelectCharacter();
997 bool bSelect
= (cChar
> 0);
1002 aText
= OUString( &cChar
, 1 );
1003 // Get the hexadecimal code
1004 aHexText
= OUString::number(cChar
, 16).toAsciiUpperCase();
1005 // Get the decimal code
1006 aDecimalText
= OUString::number(cChar
);
1009 // Update the hex and decimal codes only if necessary
1010 if (!m_xHexCodeText
->get_text().equalsIgnoreAsciiCase(aHexText
))
1011 m_xHexCodeText
->set_text(aHexText
);
1012 if (m_xDecimalCodeText
->get_text() != aDecimalText
)
1013 m_xDecimalCodeText
->set_text( aDecimalText
);
1015 const Subset
* pSubset
= nullptr;
1017 pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
1019 m_xSubsetLB
->set_active_text(pSubset
->GetName());
1021 m_xSubsetLB
->set_active(-1);
1024 if(m_xSearchSet
->HasFocus())
1026 m_aShowChar
.SetText( aText
);
1027 m_aShowChar
.SetFont( aFont
);
1028 m_aShowChar
.Invalidate();
1030 setFavButtonState(aText
, aFont
.GetFamilyName());
1034 void SvxCharacterMap::selectCharByCode(Radix radix
)
1036 OUString aCodeString
;
1039 case Radix::decimal
:
1040 aCodeString
= m_xDecimalCodeText
->get_text();
1042 case Radix::hexadecimal
:
1043 aCodeString
= m_xHexCodeText
->get_text();
1046 // Convert the code back to a character using the appropriate radix
1047 sal_UCS4 cChar
= aCodeString
.toUInt32(static_cast<sal_Int16
> (radix
));
1048 // Use FontCharMap::HasChar(sal_UCS4 cChar) to see if the desired character is in the font
1049 FontCharMapRef xFontCharMap
= m_xShowSet
->GetFontCharMap();
1050 if (xFontCharMap
->HasChar(cChar
))
1051 // Select the corresponding character
1054 m_xCharName
->set_label(CuiResId(RID_SVXSTR_MISSING_CHAR
));
1055 m_aShowChar
.SetText(" ");
1058 case Radix::decimal
:
1059 m_xHexCodeText
->set_text(OUString::number(cChar
, 16));
1061 case Radix::hexadecimal
:
1062 m_xDecimalCodeText
->set_text(OUString::number(cChar
));
1068 IMPL_LINK_NOARG(SvxCharacterMap
, DecimalCodeChangeHdl
, weld::Entry
&, void)
1070 selectCharByCode(Radix::decimal
);
1073 IMPL_LINK_NOARG(SvxCharacterMap
, HexCodeChangeHdl
, weld::Entry
&, void)
1075 selectCharByCode(Radix::hexadecimal
);
1078 IMPL_LINK_NOARG(SvxCharacterMap
, CharPreSelectHdl
, SvxShowCharSet
*, void)
1080 // adjust subset selection
1083 sal_UCS4 cChar
= m_xShowSet
->GetSelectCharacter();
1085 setFavButtonState(OUString(&cChar
, 1), aFont
.GetFamilyName());
1086 const Subset
* pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
1088 m_xSubsetLB
->set_active_text(pSubset
->GetName());
1091 m_xOKBtn
->set_sensitive(true);
1094 IMPL_LINK_NOARG(SvxCharacterMap
, SearchCharPreSelectHdl
, SvxShowCharSet
*, void)
1096 // adjust subset selection
1099 sal_UCS4 cChar
= m_xSearchSet
->GetSelectCharacter();
1101 setFavButtonState(OUString(&cChar
, 1), aFont
.GetFamilyName());
1102 const Subset
* pSubset
= pSubsetMap
->GetSubsetByUnicode( cChar
);
1104 m_xSubsetLB
->set_active_text(pSubset
->GetName());
1107 m_xOKBtn
->set_sensitive(true);
1110 // class SvxShowText =====================================================
1111 SvxShowText::SvxShowText(const VclPtr
<VirtualDevice
>& rVirDev
)
1112 : m_xVirDev(rVirDev
)
1118 void SvxShowText::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
1120 CustomWidgetController::SetDrawingArea(pDrawingArea
);
1121 vcl::Font aFont
= m_xVirDev
->GetFont();
1122 Size
aFontSize(aFont
.GetFontSize().Width() * 5, aFont
.GetFontSize().Height() * 5);
1123 aFont
.SetFontSize(aFontSize
);
1124 m_xVirDev
->Push(PUSH_ALLFONT
);
1125 m_xVirDev
->SetFont(aFont
);
1126 pDrawingArea
->set_size_request(m_xVirDev
->approximate_digit_width() + 2 * 12,
1127 m_xVirDev
->LogicToPixel(aFontSize
).Height() * 2);
1131 void SvxShowText::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
1133 rRenderContext
.SetFont(m_aFont
);
1135 Color aTextCol
= rRenderContext
.GetTextColor();
1136 Color aFillCol
= rRenderContext
.GetFillColor();
1138 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1139 const Color
aWindowTextColor(rStyleSettings
.GetDialogTextColor());
1140 const Color
aWindowColor(rStyleSettings
.GetWindowColor());
1141 rRenderContext
.SetTextColor(aWindowTextColor
);
1142 rRenderContext
.SetFillColor(aWindowColor
);
1144 const OUString aText
= GetText();
1146 Size
aSize(GetOutputSizePixel());
1147 long nAvailWidth
= aSize
.Width();
1148 long nWinHeight
= aSize
.Height();
1150 bool bGotBoundary
= true;
1151 bool bShrankFont
= false;
1152 vcl::Font
aOrigFont(rRenderContext
.GetFont());
1153 Size
aFontSize(aOrigFont
.GetFontSize());
1154 ::tools::Rectangle aBoundRect
;
1156 for (long nFontHeight
= aFontSize
.Height(); nFontHeight
> 0; nFontHeight
-= 5)
1158 if (!rRenderContext
.GetTextBoundRect( aBoundRect
, aText
) || aBoundRect
.IsEmpty())
1160 bGotBoundary
= false;
1165 //only shrink in the single glyph large view mode
1166 long nTextWidth
= aBoundRect
.GetWidth();
1167 if (nAvailWidth
> nTextWidth
)
1169 vcl::Font
aFont(aOrigFont
);
1170 aFontSize
.setHeight( nFontHeight
);
1171 aFont
.SetFontSize(aFontSize
);
1172 rRenderContext
.SetFont(aFont
);
1173 mnY
= (nWinHeight
- rRenderContext
.GetTextHeight()) / 2;
1177 Point
aPoint(2, mnY
);
1178 // adjust position using ink boundary if possible
1180 aPoint
.setX( (aSize
.Width() - rRenderContext
.GetTextWidth(aText
)) / 2 );
1183 // adjust position before it gets out of bounds
1184 aBoundRect
+= aPoint
;
1186 // shift back vertically if needed
1187 int nYLDelta
= aBoundRect
.Top();
1188 int nYHDelta
= aSize
.Height() - aBoundRect
.Bottom();
1190 aPoint
.AdjustY( -(nYLDelta
- 1) );
1191 else if( nYHDelta
<= 0 )
1192 aPoint
.AdjustY(nYHDelta
- 1 );
1196 // move glyph to middle of cell
1197 aPoint
.setX( -aBoundRect
.Left() + (aSize
.Width() - aBoundRect
.GetWidth()) / 2 );
1201 // shift back horizontally if needed
1202 int nXLDelta
= aBoundRect
.Left();
1203 int nXHDelta
= aSize
.Width() - aBoundRect
.Right();
1205 aPoint
.AdjustX( -(nXLDelta
- 1) );
1206 else if( nXHDelta
<= 0 )
1207 aPoint
.AdjustX(nXHDelta
- 1 );
1211 rRenderContext
.DrawRect(tools::Rectangle(Point(0, 0), aSize
));
1212 rRenderContext
.DrawText(aPoint
, aText
);
1213 rRenderContext
.SetTextColor(aTextCol
);
1214 rRenderContext
.SetFillColor(aFillCol
);
1216 rRenderContext
.SetFont(aOrigFont
);
1219 void SvxShowText::SetFont( const vcl::Font
& rFont
)
1221 long nWinHeight
= GetOutputSizePixel().Height();
1224 m_aFont
.SetWeight(WEIGHT_NORMAL
);
1225 m_aFont
.SetAlignment(ALIGN_TOP
);
1226 m_aFont
.SetFontSize(m_xVirDev
->PixelToLogic(Size(0, nWinHeight
/ 2)));
1227 m_aFont
.SetTransparent(true);
1229 m_xVirDev
->Push(PUSH_ALLFONT
);
1230 m_xVirDev
->SetFont(m_aFont
);
1231 mnY
= (nWinHeight
- m_xVirDev
->GetTextHeight()) / 2;
1237 void SvxShowText::Resize()
1239 SetFont(GetFont()); //force recalculation of size
1242 void SvxShowText::SetText(const OUString
& rText
)
1248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */