bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / options / fontsubs.cxx
blob6885694dfceaa30097d2cc6941db07c479e43de5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
30 #include "helpid.hrc"
31 #include <cuires.hrc>
33 /*********************************************************************/
34 /* */
35 /* TabPage font replacement */
36 /* */
37 /*********************************************************************/
39 SvxFontSubstTabPage::SvxFontSubstTabPage( vcl::Window* pParent,
40 const SfxItemSet& rSet )
41 : SfxTabPage(pParent, "OptFontsPage", "cui/ui/optfontspage.ui", &rSet)
42 , pConfig(new SvtFontSubstConfig)
43 , pCheckButtonData(0)
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));
104 sal_uInt16 nHeight;
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 ) );
136 return pEntry;
139 SvxFontSubstTabPage::~SvxFontSubstTabPage()
141 disposeOnce();
144 void SvxFontSubstTabPage::dispose()
146 delete pCheckButtonData;
147 pCheckButtonData = NULL;
148 delete pConfig;
149 pConfig = NULL;
150 m_pCheckLB.disposeAndClear();
151 m_pUseTableCB.clear();
152 m_pReplacements.clear();
153 m_pFont1CB.clear();
154 m_pFont2CB.clear();
155 m_pApply.clear();
156 m_pDelete.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();
177 while (pEntry)
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())
188 pConfig->Commit();
189 pConfig->Apply();
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()),
195 batch);
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
201 OUString sFontName;
202 if(m_pFontNameLB->GetSelectEntryPos())
203 sFontName = m_pFontNameLB->GetSelectEntry();
204 officecfg::Office::Common::Font::SourceViewFont::FontName::set(
205 boost::optional< OUString >(sFontName), batch);
206 batch->commit();
208 return false;
211 void SvxFontSubstTabPage::Reset( const SfxItemSet* )
213 m_pCheckLB->SetUpdateMode(false);
214 m_pCheckLB->Clear();
216 FontList aFntLst( Application::GetDefaultDevice() );
217 m_pFont1CB->Fill( &aFntLst );
218 m_pFont2CB->Fill( &aFntLst );
220 sal_Int32 nCount = pConfig->SubstitutionCount();
221 if (nCount)
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);
235 CheckEnable();
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);
243 OUString sFontName(
244 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
245 get_value_or(OUString()));
246 if(!sFontName.isEmpty())
247 m_pFontNameLB->SelectEntry(sFontName);
248 else
249 m_pFontNameLB->SelectEntryPos(0);
250 m_pFontHeightLB->SelectEntry(
251 OUString::number(
252 officecfg::Office::Common::Font::SourceViewFont::FontHeight::
253 get()));
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)
271 // change entry
272 m_pCheckLB->SetEntryText(m_pFont2CB->GetText(), nPos, 1);
273 pEntry = m_pCheckLB->GetEntry(nPos);
275 else
277 // new entry
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();
292 while (pEntry)
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);
329 CheckEnable();
331 return 0;
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);
350 return 0;
353 void SvxFontSubstTabPage::CheckEnable()
355 bool bEnableAll = m_pUseTableCB->IsChecked();
356 m_pReplacements->Enable(bEnableAll);
357 if (bEnableAll)
359 bool bApply, bDelete;
361 SvTreeListEntry* pEntry = m_pCheckLB->FirstSelected();
363 OUString sEntry = m_pFont1CB->GetText();
364 sEntry += "\t";
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())
369 bApply = false;
370 else if(m_pFont1CB->GetText() == m_pFont2CB->GetText())
371 bApply = false;
372 else if(m_pCheckLB->GetEntryPos(sEntry) != 0xffffffff)
373 bApply = false;
374 else if(pEntry != 0 && m_pCheckLB->NextSelected(pEntry) != 0)
375 bApply = false;
376 else
377 bApply = true;
379 bDelete = pEntry != 0;
381 m_pApply->Enable(bApply);
382 m_pDelete->Enable(bDelete);
385 if (bEnableAll)
387 if (!m_pCheckLB->IsEnabled())
389 m_pCheckLB->EnableTable();
390 m_pCheckLB->SetTextColor(aTextColor);
391 m_pCheckLB->Invalidate();
392 SelectHdl(m_pFont1CB);
395 else
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)
411 return;
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();
429 setColSizes();
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;
441 pTab = aTabs[2];
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;
453 if ( nCol < 2 )
455 CheckEntryPos( nSelPos, nCol, !IsChecked( nSelPos, nCol ) );
456 CallImplEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)GetEntry( nSelPos ) );
458 else
460 sal_uInt16 nCheck = IsChecked(nSelPos, 1) ? 1 : 0;
461 if(IsChecked(nSelPos, 0))
462 nCheck += 2;
463 nCheck--;
464 nCheck &= 3;
465 CheckEntryPos(nSelPos, 1, 0 != (nCheck & 1));
466 CheckEntryPos(nSelPos, 0, 0 != (nCheck & 2));
469 else
470 SvSimpleTable::KeyInput(rKEvt);
473 void SvxFontSubstCheckListBox::CheckEntryPos(sal_uLong nPos, sal_uInt16 nCol, bool bChecked)
475 if ( nPos < GetEntryCount() )
476 SetCheckButtonState(
477 GetEntry(nPos),
478 nCol,
479 bChecked ? SvButtonState( SV_BUTTON_CHECKED ) :
480 SvButtonState( SV_BUTTON_UNCHECKED ) );
483 void SvxFontSubstCheckListBox::CheckEntry(SvTreeListEntry* pEntry, sal_uInt16 nCol, bool bChecked)
485 if ( pEntry )
486 SetCheckButtonState(
487 pEntry,
488 nCol,
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)
510 switch( eState )
512 case SV_BUTTON_CHECKED:
513 pItem->SetStateChecked();
514 break;
516 case SV_BUTTON_UNCHECKED:
517 pItem->SetStateUnchecked();
518 break;
520 case SV_BUTTON_TRISTATE:
521 pItem->SetStateTristate();
522 break;
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 );
540 return eState;
544 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */