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 .
20 #include "sal/config.h"
22 #include <officecfg/Office/Common.hxx>
23 #include <svtools/ctrltool.hxx>
24 #include <svtools/svlbitm.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/wrkwin.hxx>
27 #include <svtools/fontsubstconfig.hxx>
28 #include "fontsubs.hxx"
29 #include <dialmgr.hxx>
33 /*********************************************************************/
35 /* TabPage font replacement */
37 /*********************************************************************/
39 SvxFontSubstTabPage::SvxFontSubstTabPage( vcl::Window
* pParent
,
40 const SfxItemSet
& rSet
)
41 : SfxTabPage(pParent
, "OptFontsPage", "cui/ui/optfontspage.ui", &rSet
)
42 , pConfig(new SvtFontSubstConfig
)
45 get(m_pUseTableCB
, "usetable");
46 get(m_pReplacements
, "replacements");
47 get(m_pFont1CB
, "font1");
48 get(m_pFont2CB
, "font2");
49 m_pFont1CB
->SetStyle(m_pFont1CB
->GetStyle() | WB_SORT
);
50 m_pFont2CB
->SetStyle(m_pFont2CB
->GetStyle() | WB_SORT
);
51 get(m_pApply
, "apply");
52 get(m_pDelete
, "delete");
53 get(m_pFontNameLB
, "fontname");
54 m_sAutomatic
= m_pFontNameLB
->GetEntry(0);
55 assert(!m_sAutomatic
.isEmpty());
56 get(m_pNonPropFontsOnlyCB
, "nonpropfontonly");
57 get(m_pFontHeightLB
, "fontheight");
59 SvSimpleTableContainer
*pCheckLBContainer
= get
<SvSimpleTableContainer
>("checklb");
60 Size
aControlSize(248, 75);
61 aControlSize
= LogicToPixel(aControlSize
, MAP_APPFONT
);
62 pCheckLBContainer
->set_width_request(aControlSize
.Width());
63 pCheckLBContainer
->set_height_request(aControlSize
.Height());
65 m_pCheckLB
= VclPtr
<SvxFontSubstCheckListBox
>::Create(*pCheckLBContainer
, 0);
66 m_pCheckLB
->SetHelpId(HID_OFA_FONT_SUBST_CLB
);
68 m_pCheckLB
->SetStyle(m_pCheckLB
->GetStyle()|WB_HSCROLL
|WB_VSCROLL
);
69 m_pCheckLB
->SetSelectionMode(MULTIPLE_SELECTION
);
70 m_pCheckLB
->SortByCol(2);
71 long aStaticTabs
[] = { 4, 0, 0, 0, 0 };
72 m_pCheckLB
->SvSimpleTable::SetTabs(&aStaticTabs
[0]);
74 OUString
sHeader1(get
<FixedText
>("always")->GetText());
75 OUString
sHeader2(get
<FixedText
>("screenonly")->GetText());
76 OUStringBuffer sHeader
;
77 sHeader
.append(sHeader1
).append("\t").append(sHeader2
)
78 .append("\t ").append(get
<FixedText
>("font")->GetText())
79 .append("\t ").append(get
<FixedText
>("replacewith")->GetText());
80 m_pCheckLB
->InsertHeaderEntry(sHeader
.makeStringAndClear());
82 HeaderBar
&rBar
= m_pCheckLB
->GetTheHeaderBar();
83 HeaderBarItemBits nBits
= rBar
.GetItemBits(1) | HeaderBarItemBits::FIXEDPOS
| HeaderBarItemBits::FIXED
;
84 nBits
&= ~HeaderBarItemBits::CLICKABLE
;
85 rBar
.SetItemBits(1, nBits
);
86 rBar
.SetItemBits(2, nBits
);
88 m_pCheckLB
->setColSizes();
90 aTextColor
= m_pCheckLB
->GetTextColor();
91 Link
<> aLink(LINK(this, SvxFontSubstTabPage
, SelectHdl
));
93 m_pCheckLB
->SetSelectHdl(aLink
);
94 m_pUseTableCB
->SetClickHdl(aLink
);
95 m_pFont1CB
->SetSelectHdl(aLink
);
96 m_pFont1CB
->SetModifyHdl(aLink
);
97 m_pFont2CB
->SetSelectHdl(aLink
);
98 m_pFont2CB
->SetModifyHdl(aLink
);
99 m_pApply
->SetClickHdl(aLink
);
100 m_pDelete
->SetClickHdl(aLink
);
102 m_pNonPropFontsOnlyCB
->SetClickHdl(LINK(this, SvxFontSubstTabPage
, NonPropFontsHdl
));
105 for(nHeight
= 6; nHeight
<= 16; nHeight
++)
106 m_pFontHeightLB
->InsertEntry(OUString::number(nHeight
));
107 for(nHeight
= 18; nHeight
<= 28; nHeight
+= 2)
108 m_pFontHeightLB
->InsertEntry(OUString::number(nHeight
));
109 for(nHeight
= 32; nHeight
<= 48; nHeight
+= 4)
110 m_pFontHeightLB
->InsertEntry(OUString::number(nHeight
));
111 for(nHeight
= 54; nHeight
<= 72; nHeight
+= 6)
112 m_pFontHeightLB
->InsertEntry(OUString::number(nHeight
));
113 for(nHeight
= 80; nHeight
<= 96; nHeight
+= 8)
114 m_pFontHeightLB
->InsertEntry(OUString::number(nHeight
));
117 SvTreeListEntry
* SvxFontSubstTabPage::CreateEntry(OUString
& rFont1
, OUString
& rFont2
)
119 SvTreeListEntry
* pEntry
= new SvTreeListEntry
;
121 if( !pCheckButtonData
)
122 pCheckButtonData
= new SvLBoxButtonData( m_pCheckLB
);
124 pEntry
->AddItem( new SvLBoxContextBmp( pEntry
, 0, Image(), Image(), false)); // Sonst Puff!
126 pEntry
->AddItem( new SvLBoxButton( pEntry
,
127 SvLBoxButtonKind_enabledCheckbox
, 0,
128 pCheckButtonData
) );
129 pEntry
->AddItem( new SvLBoxButton( pEntry
,
130 SvLBoxButtonKind_enabledCheckbox
, 0,
131 pCheckButtonData
) );
133 pEntry
->AddItem( new SvLBoxString( pEntry
, 0, rFont1
) );
134 pEntry
->AddItem( new SvLBoxString( pEntry
, 0, rFont2
) );
139 SvxFontSubstTabPage::~SvxFontSubstTabPage()
144 void SvxFontSubstTabPage::dispose()
146 delete pCheckButtonData
;
147 pCheckButtonData
= NULL
;
150 m_pCheckLB
.disposeAndClear();
151 m_pUseTableCB
.clear();
152 m_pReplacements
.clear();
157 m_pFontNameLB
.clear();
158 m_pNonPropFontsOnlyCB
.clear();
159 m_pFontHeightLB
.clear();
160 SfxTabPage::dispose();
163 VclPtr
<SfxTabPage
> SvxFontSubstTabPage::Create( vcl::Window
* pParent
,
164 const SfxItemSet
* rAttrSet
)
166 return VclPtr
<SvxFontSubstTabPage
>::Create(pParent
, *rAttrSet
);
169 bool SvxFontSubstTabPage::FillItemSet( SfxItemSet
* )
171 pConfig
->ClearSubstitutions();// remove all entries
173 pConfig
->Enable(m_pUseTableCB
->IsChecked());
175 SvTreeListEntry
* pEntry
= m_pCheckLB
->First();
179 SubstitutionStruct aAdd
;
180 aAdd
.sFont
= SvTabListBox::GetEntryText(pEntry
, 0);
181 aAdd
.sReplaceBy
= SvTabListBox::GetEntryText(pEntry
, 1);
182 aAdd
.bReplaceAlways
= SvxFontSubstCheckListBox::IsChecked(pEntry
, 0);
183 aAdd
.bReplaceOnScreenOnly
= SvxFontSubstCheckListBox::IsChecked(pEntry
, 1);
184 pConfig
->AddSubstitution(aAdd
);
185 pEntry
= m_pCheckLB
->Next(pEntry
);
187 if(pConfig
->IsModified())
190 std::shared_ptr
< comphelper::ConfigurationChanges
> batch(
191 comphelper::ConfigurationChanges::create());
192 if(m_pFontHeightLB
->IsValueChangedFromSaved())
193 officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
194 static_cast< sal_Int16
>(m_pFontHeightLB
->GetSelectEntry().toInt32()),
196 if(m_pNonPropFontsOnlyCB
->IsValueChangedFromSaved())
197 officecfg::Office::Common::Font::SourceViewFont::
198 NonProportionalFontsOnly::set(
199 m_pNonPropFontsOnlyCB
->IsChecked(), batch
);
200 //font name changes cannot be detected by saved values
202 if(m_pFontNameLB
->GetSelectEntryPos())
203 sFontName
= m_pFontNameLB
->GetSelectEntry();
204 officecfg::Office::Common::Font::SourceViewFont::FontName::set(
205 boost::optional
< OUString
>(sFontName
), batch
);
211 void SvxFontSubstTabPage::Reset( const SfxItemSet
* )
213 m_pCheckLB
->SetUpdateMode(false);
216 FontList
aFntLst( Application::GetDefaultDevice() );
217 m_pFont1CB
->Fill( &aFntLst
);
218 m_pFont2CB
->Fill( &aFntLst
);
220 sal_Int32 nCount
= pConfig
->SubstitutionCount();
222 m_pUseTableCB
->Check(pConfig
->IsEnabled());
224 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
226 const SubstitutionStruct
* pSubs
= pConfig
->GetSubstitution(i
);
227 OUString
aTmpStr1(pSubs
->sFont
);
228 OUString
aTmpStr2(pSubs
->sReplaceBy
);
229 SvTreeListEntry
* pEntry
= CreateEntry(aTmpStr1
, aTmpStr2
);
230 m_pCheckLB
->Insert(pEntry
);
231 m_pCheckLB
->CheckEntry(pEntry
, 0, pSubs
->bReplaceAlways
);
232 m_pCheckLB
->CheckEntry(pEntry
, 1, pSubs
->bReplaceOnScreenOnly
);
236 m_pCheckLB
->SetUpdateMode(true);
238 //fill font name box first
239 m_pNonPropFontsOnlyCB
->Check(
240 officecfg::Office::Common::Font::SourceViewFont::
241 NonProportionalFontsOnly::get());
242 NonPropFontsHdl(m_pNonPropFontsOnlyCB
);
244 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
245 get_value_or(OUString()));
246 if(!sFontName
.isEmpty())
247 m_pFontNameLB
->SelectEntry(sFontName
);
249 m_pFontNameLB
->SelectEntryPos(0);
250 m_pFontHeightLB
->SelectEntry(
252 officecfg::Office::Common::Font::SourceViewFont::FontHeight::
254 m_pNonPropFontsOnlyCB
->SaveValue();
255 m_pFontHeightLB
->SaveValue();
258 IMPL_LINK(SvxFontSubstTabPage
, SelectHdl
, vcl::Window
*, pWin
)
260 if (pWin
== m_pApply
|| pWin
== m_pDelete
)
262 SvTreeListEntry
* pEntry
;
263 // nCol is stupidly the nCol'th text column, not counted!
264 // Therefore "0" as column.
265 sal_uLong nPos
= m_pCheckLB
->GetEntryPos(m_pFont1CB
->GetText(), 0);
267 if (pWin
== m_pApply
)
269 if (nPos
!= 0xffffffff)
272 m_pCheckLB
->SetEntryText(m_pFont2CB
->GetText(), nPos
, 1);
273 pEntry
= m_pCheckLB
->GetEntry(nPos
);
278 OUString sFont1
= m_pFont1CB
->GetText();
279 OUString sFont2
= m_pFont2CB
->GetText();
281 pEntry
= CreateEntry(sFont1
, sFont2
);
282 m_pCheckLB
->Insert(pEntry
);
284 m_pCheckLB
->SelectAll(false);
285 m_pCheckLB
->Select(pEntry
);
287 else if (pWin
== m_pDelete
)
289 if (nPos
!= 0xffffffff)
291 pEntry
= m_pCheckLB
->FirstSelected();
294 SvTreeListEntry
* pDelEntry
= pEntry
;
295 pEntry
= m_pCheckLB
->NextSelected(pEntry
);
296 m_pCheckLB
->RemoveEntry(pDelEntry
);
302 if (pWin
== m_pCheckLB
)
304 SvTreeListEntry
* pEntry
= m_pCheckLB
->FirstSelected();
306 if (m_pCheckLB
->NextSelected(pEntry
) == 0)
308 m_pFont1CB
->SetText(SvTabListBox::GetEntryText(pEntry
, 0));
309 m_pFont2CB
->SetText(SvTabListBox::GetEntryText(pEntry
, 1));
313 if (pWin
== m_pFont1CB
)
315 sal_uLong nPos
= m_pCheckLB
->GetEntryPos(m_pFont1CB
->GetText(), 0);
317 if (nPos
!= 0xffffffff)
319 SvTreeListEntry
* pEntry
= m_pCheckLB
->GetEntry(nPos
);
321 if (pEntry
!= m_pCheckLB
->FirstSelected())
323 m_pCheckLB
->SelectAll(false);
324 m_pCheckLB
->Select(pEntry
);
335 IMPL_LINK(SvxFontSubstTabPage
, NonPropFontsHdl
, CheckBox
*, pBox
)
337 OUString sFontName
= m_pFontNameLB
->GetSelectEntry();
338 bool bNonPropOnly
= pBox
->IsChecked();
339 m_pFontNameLB
->Clear();
340 FontList
aFntLst( Application::GetDefaultDevice() );
341 m_pFontNameLB
->InsertEntry(m_sAutomatic
);
342 sal_uInt16 nFontCount
= aFntLst
.GetFontNameCount();
343 for(sal_uInt16 nFont
= 0; nFont
< nFontCount
; nFont
++)
345 const vcl::FontInfo
& rInfo
= aFntLst
.GetFontName( nFont
);
346 if(!bNonPropOnly
|| rInfo
.GetPitch() == PITCH_FIXED
)
347 m_pFontNameLB
->InsertEntry(rInfo
.GetName());
349 m_pFontNameLB
->SelectEntry(sFontName
);
353 void SvxFontSubstTabPage::CheckEnable()
355 bool bEnableAll
= m_pUseTableCB
->IsChecked();
356 m_pReplacements
->Enable(bEnableAll
);
359 bool bApply
, bDelete
;
361 SvTreeListEntry
* pEntry
= m_pCheckLB
->FirstSelected();
363 OUString sEntry
= m_pFont1CB
->GetText();
365 sEntry
+= m_pFont2CB
->GetText();
367 // because of OS/2 optimization error (Bug #56267) a bit more intricate:
368 if (m_pFont1CB
->GetText().isEmpty() || m_pFont2CB
->GetText().isEmpty())
370 else if(m_pFont1CB
->GetText() == m_pFont2CB
->GetText())
372 else if(m_pCheckLB
->GetEntryPos(sEntry
) != 0xffffffff)
374 else if(pEntry
!= 0 && m_pCheckLB
->NextSelected(pEntry
) != 0)
379 bDelete
= pEntry
!= 0;
381 m_pApply
->Enable(bApply
);
382 m_pDelete
->Enable(bDelete
);
387 if (!m_pCheckLB
->IsEnabled())
389 m_pCheckLB
->EnableTable();
390 m_pCheckLB
->SetTextColor(aTextColor
);
391 m_pCheckLB
->Invalidate();
392 SelectHdl(m_pFont1CB
);
397 if (m_pCheckLB
->IsEnabled())
399 m_pCheckLB
->DisableTable();
400 m_pCheckLB
->SetTextColor(Color(COL_GRAY
));
401 m_pCheckLB
->Invalidate();
402 m_pCheckLB
->SelectAll(false);
407 void SvxFontSubstCheckListBox::setColSizes()
409 HeaderBar
&rBar
= GetTheHeaderBar();
410 if (rBar
.GetItemCount() < 4)
412 long nW1
= rBar
.GetTextWidth(rBar
.GetItemText(3));
413 long nW2
= rBar
.GetTextWidth(rBar
.GetItemText(4));
414 long nMax
= std::max( nW1
, nW2
) + 6; // width of the longest header + a little offset
415 long nMin
= rBar
.LogicToPixel(Size(10, 0), MAP_APPFONT
).Width();
416 nMax
= std::max( nMax
, nMin
);
417 const long nDoubleMax
= 2*nMax
;
418 const long nRest
= GetSizePixel().Width() - nDoubleMax
;
419 long aStaticTabs
[] = { 4, 0, 0, 0, 0 };
420 aStaticTabs
[2] = nMax
;
421 aStaticTabs
[3] = nDoubleMax
;
422 aStaticTabs
[4] = nDoubleMax
+ nRest
/2;
423 SvSimpleTable::SetTabs(aStaticTabs
, MAP_PIXEL
);
426 void SvxFontSubstCheckListBox::Resize()
428 SvSimpleTable::Resize();
432 void SvxFontSubstCheckListBox::SetTabs()
434 SvSimpleTable::SetTabs();
435 SvLBoxTabFlags nAdjust
= SvLBoxTabFlags::ADJUST_RIGHT
|SvLBoxTabFlags::ADJUST_LEFT
|SvLBoxTabFlags::ADJUST_CENTER
|SvLBoxTabFlags::ADJUST_NUMERIC
|SvLBoxTabFlags::FORCE
;
437 SvLBoxTab
* pTab
= aTabs
[1];
438 pTab
->nFlags
&= ~nAdjust
;
439 pTab
->nFlags
|= SvLBoxTabFlags::PUSHABLE
|SvLBoxTabFlags::ADJUST_CENTER
|SvLBoxTabFlags::FORCE
;
442 pTab
->nFlags
&= ~nAdjust
;
443 pTab
->nFlags
|= SvLBoxTabFlags::PUSHABLE
|SvLBoxTabFlags::ADJUST_CENTER
|SvLBoxTabFlags::FORCE
;
446 void SvxFontSubstCheckListBox::KeyInput( const KeyEvent
& rKEvt
)
448 if(!rKEvt
.GetKeyCode().GetModifier() &&
449 KEY_SPACE
== rKEvt
.GetKeyCode().GetCode())
451 sal_uLong nSelPos
= GetModel()->GetAbsPos(GetCurEntry());
452 sal_uInt16 nCol
= GetCurrentTabPos() - 1;
455 CheckEntryPos( nSelPos
, nCol
, !IsChecked( nSelPos
, nCol
) );
456 CallImplEventListeners( VCLEVENT_CHECKBOX_TOGGLE
, (void*)GetEntry( nSelPos
) );
460 sal_uInt16 nCheck
= IsChecked(nSelPos
, 1) ? 1 : 0;
461 if(IsChecked(nSelPos
, 0))
465 CheckEntryPos(nSelPos
, 1, 0 != (nCheck
& 1));
466 CheckEntryPos(nSelPos
, 0, 0 != (nCheck
& 2));
470 SvSimpleTable::KeyInput(rKEvt
);
473 void SvxFontSubstCheckListBox::CheckEntryPos(sal_uLong nPos
, sal_uInt16 nCol
, bool bChecked
)
475 if ( nPos
< GetEntryCount() )
479 bChecked
? SvButtonState( SV_BUTTON_CHECKED
) :
480 SvButtonState( SV_BUTTON_UNCHECKED
) );
483 void SvxFontSubstCheckListBox::CheckEntry(SvTreeListEntry
* pEntry
, sal_uInt16 nCol
, bool bChecked
)
489 bChecked
? SvButtonState( SV_BUTTON_CHECKED
) :
490 SvButtonState( SV_BUTTON_UNCHECKED
) );
493 bool SvxFontSubstCheckListBox::IsChecked(sal_uLong nPos
, sal_uInt16 nCol
)
495 return GetCheckButtonState( GetEntry(nPos
), nCol
) == SV_BUTTON_CHECKED
;
498 bool SvxFontSubstCheckListBox::IsChecked(SvTreeListEntry
* pEntry
, sal_uInt16 nCol
)
500 return GetCheckButtonState( pEntry
, nCol
) == SV_BUTTON_CHECKED
;
503 void SvxFontSubstCheckListBox::SetCheckButtonState( SvTreeListEntry
* pEntry
, sal_uInt16 nCol
, SvButtonState eState
)
505 SvLBoxButton
* pItem
= static_cast<SvLBoxButton
*>(pEntry
->GetItem(nCol
+ 1));
507 DBG_ASSERT(pItem
,"SetCheckButton:Item not found");
508 if (pItem
->GetType() == SV_ITEM_ID_LBOXBUTTON
)
512 case SV_BUTTON_CHECKED
:
513 pItem
->SetStateChecked();
516 case SV_BUTTON_UNCHECKED
:
517 pItem
->SetStateUnchecked();
520 case SV_BUTTON_TRISTATE
:
521 pItem
->SetStateTristate();
524 InvalidateEntry( pEntry
);
528 SvButtonState
SvxFontSubstCheckListBox::GetCheckButtonState( SvTreeListEntry
* pEntry
, sal_uInt16 nCol
)
530 SvButtonState eState
= SV_BUTTON_UNCHECKED
;
531 SvLBoxButton
* pItem
= static_cast<SvLBoxButton
*>(pEntry
->GetItem(nCol
+ 1));
532 DBG_ASSERT(pItem
,"GetChButnState:Item not found");
534 if (pItem
->GetType() == SV_ITEM_ID_LBOXBUTTON
)
536 SvItemStateFlags nButtonFlags
= pItem
->GetButtonFlags();
537 eState
= SvLBoxButtonData::ConvertToButtonState( nButtonFlags
);
544 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */