update credits
[LibreOffice.git] / cui / source / options / fontsubs.cxx
blob91ecf40936cbe5bc57908337c651b0fe2e8674d9
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 <tools/shl.hxx>
24 #include <svtools/ctrltool.hxx>
25 #include <svtools/svlbitm.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/wrkwin.hxx>
28 #include <svtools/fontsubstconfig.hxx>
29 #include "fontsubs.hxx"
30 #include <dialmgr.hxx>
31 #include "helpid.hrc"
32 #include <cuires.hrc>
34 /*********************************************************************/
35 /* */
36 /* TabPage font replacement */
37 /* */
38 /*********************************************************************/
40 SvxFontSubstTabPage::SvxFontSubstTabPage( Window* pParent,
41 const SfxItemSet& rSet )
42 : SfxTabPage(pParent, "OptFontsPage", "cui/ui/optfontspage.ui", rSet)
43 , pConfig(new SvtFontSubstConfig)
44 , pCheckButtonData(0)
46 get(m_pUseTableCB, "usetable");
47 get(m_pReplacements, "replacements");
48 get(m_pFont1CB, "font1");
49 get(m_pFont2CB, "font2");
50 m_pFont1CB->SetStyle(m_pFont1CB->GetStyle() | WB_SORT);
51 m_pFont2CB->SetStyle(m_pFont2CB->GetStyle() | WB_SORT);
52 get(m_pApply, "apply");
53 get(m_pDelete, "delete");
54 get(m_pFontNameLB, "fontname");
55 m_sAutomatic = m_pFontNameLB->GetEntry(0);
56 assert(!m_sAutomatic.isEmpty());
57 get(m_pNonPropFontsOnlyCB, "nonpropfontonly");
58 get(m_pFontHeightLB, "fontheight");
60 SvxSimpleTableContainer *pCheckLBContainer = get<SvxSimpleTableContainer>("checklb");
61 Size aControlSize(248, 75);
62 aControlSize = LogicToPixel(aControlSize, MAP_APPFONT);
63 pCheckLBContainer->set_width_request(aControlSize.Width());
64 pCheckLBContainer->set_height_request(aControlSize.Height());
66 m_pCheckLB = new SvxFontSubstCheckListBox(*pCheckLBContainer, 0);
67 m_pCheckLB->SetHelpId(HID_OFA_FONT_SUBST_CLB);
69 m_pCheckLB->SetStyle(m_pCheckLB->GetStyle()|WB_HSCROLL|WB_VSCROLL);
70 m_pCheckLB->SetSelectionMode(MULTIPLE_SELECTION);
71 m_pCheckLB->SortByCol(2);
72 long aStaticTabs[] = { 4, 0, 0, 0, 0 };
73 m_pCheckLB->SvxSimpleTable::SetTabs(&aStaticTabs[0]);
75 OUString sHeader1(get<FixedText>("always")->GetText());
76 OUString sHeader2(get<FixedText>("screenonly")->GetText());
77 OUStringBuffer sHeader;
78 sHeader.append(sHeader1).append("\t").append(sHeader2)
79 .append("\t ").append(get<FixedText>("font")->GetText())
80 .append("\t ").append(get<FixedText>("replacewith")->GetText());
81 m_pCheckLB->InsertHeaderEntry(sHeader.makeStringAndClear());
83 HeaderBar &rBar = m_pCheckLB->GetTheHeaderBar();
84 HeaderBarItemBits nBits = rBar.GetItemBits(1) | HIB_FIXEDPOS | HIB_FIXED;
85 nBits &= ~HIB_CLICKABLE;
86 rBar.SetItemBits(1, nBits);
87 rBar.SetItemBits(2, nBits);
89 m_pCheckLB->setColSizes();
91 aTextColor = m_pCheckLB->GetTextColor();
92 Link aLink(LINK(this, SvxFontSubstTabPage, SelectHdl));
94 m_pCheckLB->SetSelectHdl(aLink);
95 m_pUseTableCB->SetClickHdl(aLink);
96 m_pFont1CB->SetSelectHdl(aLink);
97 m_pFont1CB->SetModifyHdl(aLink);
98 m_pFont2CB->SetSelectHdl(aLink);
99 m_pFont2CB->SetModifyHdl(aLink);
100 m_pApply->SetClickHdl(aLink);
101 m_pDelete->SetClickHdl(aLink);
103 m_pNonPropFontsOnlyCB->SetClickHdl(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
105 sal_uInt16 nHeight;
106 for(nHeight = 6; nHeight <= 16; nHeight++)
107 m_pFontHeightLB->InsertEntry(OUString::number(nHeight));
108 for(nHeight = 18; nHeight <= 28; nHeight+= 2)
109 m_pFontHeightLB->InsertEntry(OUString::number(nHeight));
110 for(nHeight = 32; nHeight <= 48; nHeight+= 4)
111 m_pFontHeightLB->InsertEntry(OUString::number(nHeight));
112 for(nHeight = 54; nHeight <= 72; nHeight+= 6)
113 m_pFontHeightLB->InsertEntry(OUString::number(nHeight));
114 for(nHeight = 80; nHeight <= 96; nHeight+= 8)
115 m_pFontHeightLB->InsertEntry(OUString::number(nHeight));
118 SvTreeListEntry* SvxFontSubstTabPage::CreateEntry(String& rFont1, String& rFont2)
120 SvTreeListEntry* pEntry = new SvTreeListEntry;
122 if( !pCheckButtonData )
123 pCheckButtonData = new SvLBoxButtonData( m_pCheckLB );
125 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0)); // Sonst Puff!
127 pEntry->AddItem( new SvLBoxButton( pEntry,
128 SvLBoxButtonKind_enabledCheckbox, 0,
129 pCheckButtonData ) );
130 pEntry->AddItem( new SvLBoxButton( pEntry,
131 SvLBoxButtonKind_enabledCheckbox, 0,
132 pCheckButtonData ) );
134 pEntry->AddItem( new SvLBoxString( pEntry, 0, rFont1 ) );
135 pEntry->AddItem( new SvLBoxString( pEntry, 0, rFont2 ) );
137 return pEntry;
140 SvxFontSubstTabPage::~SvxFontSubstTabPage()
142 delete pCheckButtonData;
143 delete pConfig;
144 delete m_pCheckLB;
147 SfxTabPage* SvxFontSubstTabPage::Create( Window* pParent,
148 const SfxItemSet& rAttrSet)
150 return new SvxFontSubstTabPage(pParent, rAttrSet);
153 sal_Bool SvxFontSubstTabPage::FillItemSet( SfxItemSet& )
155 pConfig->ClearSubstitutions();// remove all entries
157 pConfig->Enable(m_pUseTableCB->IsChecked());
159 SvTreeListEntry* pEntry = m_pCheckLB->First();
161 while (pEntry)
163 SubstitutionStruct aAdd;
164 aAdd.sFont = m_pCheckLB->GetEntryText(pEntry, 0);
165 aAdd.sReplaceBy = m_pCheckLB->GetEntryText(pEntry, 1);
166 aAdd.bReplaceAlways = m_pCheckLB->IsChecked(pEntry, 0);
167 aAdd.bReplaceOnScreenOnly = m_pCheckLB->IsChecked(pEntry, 1);
168 pConfig->AddSubstitution(aAdd);
169 pEntry = m_pCheckLB->Next(pEntry);
171 if(pConfig->IsModified())
172 pConfig->Commit();
173 pConfig->Apply();
174 boost::shared_ptr< comphelper::ConfigurationChanges > batch(
175 comphelper::ConfigurationChanges::create());
176 if(m_pFontHeightLB->GetSavedValue() != m_pFontHeightLB->GetSelectEntryPos())
177 officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
178 static_cast< sal_Int16 >(m_pFontHeightLB->GetSelectEntry().ToInt32()),
179 batch);
180 if(m_pNonPropFontsOnlyCB->GetSavedValue() != m_pNonPropFontsOnlyCB->IsChecked())
181 officecfg::Office::Common::Font::SourceViewFont::
182 NonProportionalFontsOnly::set(
183 m_pNonPropFontsOnlyCB->IsChecked(), batch);
184 //font name changes cannot be detected by saved values
185 OUString sFontName;
186 if(m_pFontNameLB->GetSelectEntryPos())
187 sFontName = m_pFontNameLB->GetSelectEntry();
188 officecfg::Office::Common::Font::SourceViewFont::FontName::set(
189 boost::optional< OUString >(sFontName), batch);
190 batch->commit();
192 return sal_False;
195 void SvxFontSubstTabPage::Reset( const SfxItemSet& )
197 m_pCheckLB->SetUpdateMode(sal_False);
198 m_pCheckLB->Clear();
200 FontList aFntLst( Application::GetDefaultDevice() );
201 m_pFont1CB->Fill( &aFntLst );
202 m_pFont2CB->Fill( &aFntLst );
204 sal_Int32 nCount = pConfig->SubstitutionCount();
205 if (nCount)
206 m_pUseTableCB->Check(pConfig->IsEnabled());
208 for (sal_Int32 i = 0; i < nCount; ++i)
210 const SubstitutionStruct* pSubs = pConfig->GetSubstitution(i);
211 String aTmpStr1(pSubs->sFont);
212 String aTmpStr2(pSubs->sReplaceBy);
213 SvTreeListEntry* pEntry = CreateEntry(aTmpStr1, aTmpStr2);
214 m_pCheckLB->Insert(pEntry);
215 m_pCheckLB->CheckEntry(pEntry, 0, pSubs->bReplaceAlways);
216 m_pCheckLB->CheckEntry(pEntry, 1, pSubs->bReplaceOnScreenOnly);
219 CheckEnable();
220 m_pCheckLB->SetUpdateMode(sal_True);
222 //fill font name box first
223 m_pNonPropFontsOnlyCB->Check(
224 officecfg::Office::Common::Font::SourceViewFont::
225 NonProportionalFontsOnly::get());
226 NonPropFontsHdl(m_pNonPropFontsOnlyCB);
227 OUString sFontName(
228 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
229 get_value_or(OUString()));
230 if(!sFontName.isEmpty())
231 m_pFontNameLB->SelectEntry(sFontName);
232 else
233 m_pFontNameLB->SelectEntryPos(0);
234 m_pFontHeightLB->SelectEntry(
235 OUString::number(
236 officecfg::Office::Common::Font::SourceViewFont::FontHeight::
237 get()));
238 m_pNonPropFontsOnlyCB->SaveValue();
239 m_pFontHeightLB->SaveValue();
242 IMPL_LINK(SvxFontSubstTabPage, SelectHdl, Window*, pWin)
244 if (pWin == m_pApply || pWin == m_pDelete)
246 SvTreeListEntry* pEntry;
247 // nCol is stupidly the nCol'th text column, not counted!
248 // Therefor "0" as column.
249 sal_uLong nPos = m_pCheckLB->GetEntryPos(m_pFont1CB->GetText(), 0);
251 if (pWin == m_pApply)
253 if (nPos != 0xffffffff)
255 // change entry
256 m_pCheckLB->SetEntryText(m_pFont2CB->GetText(), nPos, 1);
257 pEntry = m_pCheckLB->GetEntry(nPos);
259 else
261 // new entry
262 String sFont1 = m_pFont1CB->GetText();
263 String sFont2 = m_pFont2CB->GetText();
265 pEntry = CreateEntry(sFont1, sFont2);
266 m_pCheckLB->Insert(pEntry);
268 m_pCheckLB->SelectAll(sal_False);
269 m_pCheckLB->Select(pEntry);
271 else if (pWin == m_pDelete)
273 if (nPos != 0xffffffff)
275 pEntry = m_pCheckLB->FirstSelected();
276 while (pEntry)
278 SvTreeListEntry* pDelEntry = pEntry;
279 pEntry = m_pCheckLB->NextSelected(pEntry);
280 m_pCheckLB->RemoveEntry(pDelEntry);
286 if (pWin == m_pCheckLB)
288 SvTreeListEntry* pEntry = m_pCheckLB->FirstSelected();
290 if (m_pCheckLB->NextSelected(pEntry) == 0)
292 m_pFont1CB->SetText(m_pCheckLB->GetEntryText(pEntry, 0));
293 m_pFont2CB->SetText(m_pCheckLB->GetEntryText(pEntry, 1));
297 if (pWin == m_pFont1CB)
299 sal_uLong nPos = m_pCheckLB->GetEntryPos(m_pFont1CB->GetText(), 0);
301 if (nPos != 0xffffffff)
303 SvTreeListEntry* pEntry = m_pCheckLB->GetEntry(nPos);
305 if (pEntry != m_pCheckLB->FirstSelected())
307 m_pCheckLB->SelectAll(sal_False);
308 m_pCheckLB->Select(pEntry);
313 CheckEnable();
315 return 0;
318 //--------------------------------------------------------------------------
319 IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, CheckBox*, pBox)
321 String sFontName = m_pFontNameLB->GetSelectEntry();
322 sal_Bool bNonPropOnly = pBox->IsChecked();
323 m_pFontNameLB->Clear();
324 FontList aFntLst( Application::GetDefaultDevice() );
325 m_pFontNameLB->InsertEntry(m_sAutomatic);
326 sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
327 for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
329 const FontInfo& rInfo = aFntLst.GetFontName( nFont );
330 if(!bNonPropOnly || rInfo.GetPitch() == PITCH_FIXED)
331 m_pFontNameLB->InsertEntry(rInfo.GetName());
333 m_pFontNameLB->SelectEntry(sFontName);
334 return 0;
337 void SvxFontSubstTabPage::CheckEnable()
339 sal_Bool bEnableAll = m_pUseTableCB->IsChecked();
340 m_pReplacements->Enable(bEnableAll);
341 if (bEnableAll)
343 sal_Bool bApply, bDelete;
345 SvTreeListEntry* pEntry = m_pCheckLB->FirstSelected();
347 String sEntry = m_pFont1CB->GetText();
348 sEntry += '\t';
349 sEntry += m_pFont2CB->GetText();
351 // because of OS/2 optimization error (Bug #56267) a bit more intricate:
352 if (m_pFont1CB->GetText().isEmpty() || m_pFont2CB->GetText().isEmpty())
353 bApply = sal_False;
354 else if(m_pFont1CB->GetText() == m_pFont2CB->GetText())
355 bApply = sal_False;
356 else if(m_pCheckLB->GetEntryPos(sEntry) != 0xffffffff)
357 bApply = sal_False;
358 else if(pEntry != 0 && m_pCheckLB->NextSelected(pEntry) != 0)
359 bApply = sal_False;
360 else
361 bApply = sal_True;
363 bDelete = pEntry != 0;
365 m_pApply->Enable(bApply);
366 m_pDelete->Enable(bDelete);
369 if (bEnableAll)
371 if (!m_pCheckLB->IsEnabled())
373 m_pCheckLB->EnableTable();
374 m_pCheckLB->SetTextColor(aTextColor);
375 m_pCheckLB->Invalidate();
376 SelectHdl(m_pFont1CB);
379 else
381 if (m_pCheckLB->IsEnabled())
383 m_pCheckLB->DisableTable();
384 m_pCheckLB->SetTextColor(Color(COL_GRAY));
385 m_pCheckLB->Invalidate();
386 m_pCheckLB->SelectAll(sal_False);
391 void SvxFontSubstCheckListBox::setColSizes()
393 HeaderBar &rBar = GetTheHeaderBar();
394 if (rBar.GetItemCount() < 4)
395 return;
396 long nW1 = rBar.GetTextWidth(rBar.GetItemText(3));
397 long nW2 = rBar.GetTextWidth(rBar.GetItemText(4));
398 long nMax = std::max( nW1, nW2 ) + 6; // width of the longest header + a little offset
399 long nMin = rBar.LogicToPixel(Size(10, 0), MAP_APPFONT).Width();
400 nMax = std::max( nMax, nMin );
401 const long nDoubleMax = 2*nMax;
402 const long nRest = GetSizePixel().Width() - nDoubleMax;
403 long aStaticTabs[] = { 4, 0, 0, 0, 0 };
404 aStaticTabs[2] = nMax;
405 aStaticTabs[3] = nDoubleMax;
406 aStaticTabs[4] = nDoubleMax + nRest/2;
407 SvxSimpleTable::SetTabs(aStaticTabs, MAP_PIXEL);
410 void SvxFontSubstCheckListBox::Resize()
412 SvxSimpleTable::Resize();
413 setColSizes();
416 void SvxFontSubstCheckListBox::SetTabs()
418 SvxSimpleTable::SetTabs();
419 sal_uInt16 nAdjust = SV_LBOXTAB_ADJUST_RIGHT|SV_LBOXTAB_ADJUST_LEFT|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_ADJUST_NUMERIC|SV_LBOXTAB_FORCE;
421 SvLBoxTab* pTab = aTabs[1];
422 pTab->nFlags &= ~nAdjust;
423 pTab->nFlags |= SV_LBOXTAB_PUSHABLE|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_FORCE;
425 pTab = aTabs[2];
426 pTab->nFlags &= ~nAdjust;
427 pTab->nFlags |= SV_LBOXTAB_PUSHABLE|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_FORCE;
430 void SvxFontSubstCheckListBox::KeyInput( const KeyEvent& rKEvt )
432 if(!rKEvt.GetKeyCode().GetModifier() &&
433 KEY_SPACE == rKEvt.GetKeyCode().GetCode())
435 sal_uLong nSelPos = GetModel()->GetAbsPos(GetCurEntry());
436 sal_uInt16 nCol = GetCurrentTabPos() - 1;
437 if ( nCol < 2 )
439 CheckEntryPos( nSelPos, nCol, !IsChecked( nSelPos, nCol ) );
440 CallImplEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)GetEntry( nSelPos ) );
442 else
444 sal_uInt16 nCheck = IsChecked(nSelPos, 1) ? 1 : 0;
445 if(IsChecked(nSelPos, 0))
446 nCheck += 2;
447 nCheck--;
448 nCheck &= 3;
449 CheckEntryPos(nSelPos, 1, 0 != (nCheck & 1));
450 CheckEntryPos(nSelPos, 0, 0 != (nCheck & 2));
453 else
454 SvxSimpleTable::KeyInput(rKEvt);
457 void SvxFontSubstCheckListBox::CheckEntryPos(sal_uLong nPos, sal_uInt16 nCol, sal_Bool bChecked)
459 if ( nPos < GetEntryCount() )
460 SetCheckButtonState(
461 GetEntry(nPos),
462 nCol,
463 bChecked ? SvButtonState( SV_BUTTON_CHECKED ) :
464 SvButtonState( SV_BUTTON_UNCHECKED ) );
467 void SvxFontSubstCheckListBox::CheckEntry(SvTreeListEntry* pEntry, sal_uInt16 nCol, sal_Bool bChecked)
469 if ( pEntry )
470 SetCheckButtonState(
471 pEntry,
472 nCol,
473 bChecked ? SvButtonState( SV_BUTTON_CHECKED ) :
474 SvButtonState( SV_BUTTON_UNCHECKED ) );
477 sal_Bool SvxFontSubstCheckListBox::IsChecked(sal_uLong nPos, sal_uInt16 nCol)
479 return GetCheckButtonState( GetEntry(nPos), nCol ) == SV_BUTTON_CHECKED;
482 sal_Bool SvxFontSubstCheckListBox::IsChecked(SvTreeListEntry* pEntry, sal_uInt16 nCol)
484 return GetCheckButtonState( pEntry, nCol ) == SV_BUTTON_CHECKED;
487 void SvxFontSubstCheckListBox::SetCheckButtonState( SvTreeListEntry* pEntry, sal_uInt16 nCol, SvButtonState eState)
489 SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetItem(nCol + 1));
491 DBG_ASSERT(pItem,"SetCheckButton:Item not found");
492 if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON)
494 switch( eState )
496 case SV_BUTTON_CHECKED:
497 pItem->SetStateChecked();
498 break;
500 case SV_BUTTON_UNCHECKED:
501 pItem->SetStateUnchecked();
502 break;
504 case SV_BUTTON_TRISTATE:
505 pItem->SetStateTristate();
506 break;
508 InvalidateEntry( pEntry );
512 SvButtonState SvxFontSubstCheckListBox::GetCheckButtonState( SvTreeListEntry* pEntry, sal_uInt16 nCol ) const
514 SvButtonState eState = SV_BUTTON_UNCHECKED;
515 SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetItem(nCol + 1));
516 DBG_ASSERT(pItem,"GetChButnState:Item not found");
518 if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON)
520 sal_uInt16 nButtonFlags = pItem->GetButtonFlags();
521 eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
524 return eState;
528 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */