Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / cui / source / options / fontsubs.cxx
blobe511a3f9302bbac24fa979f479fa6b09299bb191
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.hrc"
30 #include "fontsubs.hxx"
31 #include <dialmgr.hxx>
32 #include "helpid.hrc"
33 #include <cuires.hrc>
35 /*********************************************************************/
36 /* */
37 /* TabPage font replacement */
38 /* */
39 /*********************************************************************/
41 SvxFontSubstTabPage::SvxFontSubstTabPage( Window* pParent,
42 const SfxItemSet& rSet ) :
43 SfxTabPage(pParent, CUI_RES(RID_SVX_FONT_SUBSTITUTION), rSet),
44 aUseTableCB (this, CUI_RES(CB_USETABLE)),
45 aFont1FT (this, CUI_RES(FT_FONT1)),
46 aFont1CB (this, CUI_RES(CB_FONT1)),
47 aFont2FT (this, CUI_RES(FT_FONT2)),
48 aFont2CB (this, CUI_RES(CB_FONT2)),
49 aNewDelTBX (this, CUI_RES(TBX_SUBSTNEWDEL)),
50 m_aCheckLBContainer(this, CUI_RES(CLB_SUBSTITUTES)),
51 aCheckLB(m_aCheckLBContainer),
53 aSourceViewFontsFL (this, CUI_RES(FL_SOURCEVIEW )),
54 aFontNameFT (this, CUI_RES(FT_FONTNAME )),
55 aFontNameLB (this, CUI_RES(LB_FONTNAME )),
56 aNonPropFontsOnlyCB(this, CUI_RES(CB_NONPROP )),
57 aFontHeightFT (this, CUI_RES(FT_FONTHEIGHT )),
58 aFontHeightLB (this, CUI_RES(LB_FONTHEIGHT )),
60 aImageList (CUI_RES(IL_ICON)),
62 sAutomatic (CUI_RES( STR_AUTOMATIC )),
63 pConfig(new SvtFontSubstConfig),
65 sHeader1 (CUI_RES( STR_HEADER1 )),
66 sHeader2 (CUI_RES( STR_HEADER2 )),
67 sHeader3 (CUI_RES( STR_HEADER3 )),
68 sHeader4 (CUI_RES( STR_HEADER4 )),
70 pCheckButtonData(0)
72 FreeResource();
74 aTextColor = aCheckLB.GetTextColor();
76 for(sal_uInt16 k = 0; k < aNewDelTBX.GetItemCount(); k++)
77 aNewDelTBX.SetItemImage(aNewDelTBX.GetItemId(k),
78 aImageList.GetImage(aNewDelTBX.GetItemId(k)));
80 aNewDelTBX.SetSizePixel( aNewDelTBX.CalcWindowSizePixel() );
82 long nDelta = ( aFont1CB.GetSizePixel().Height() -
83 aNewDelTBX.GetSizePixel().Height() ) / 2;
84 Point aNewPnt = aNewDelTBX.GetPosPixel();
85 aNewPnt.Y() += nDelta;
86 aNewDelTBX.SetPosPixel( aNewPnt );
88 aCheckLB.SetHelpId(HID_OFA_FONT_SUBST_CLB);
89 aCheckLB.SetStyle(aCheckLB.GetStyle()|WB_HSCROLL|WB_VSCROLL);
90 aCheckLB.SetSelectionMode(MULTIPLE_SELECTION);
91 aCheckLB.SortByCol(2);
93 Link aLink(LINK(this, SvxFontSubstTabPage, SelectHdl));
95 aCheckLB.SetSelectHdl(aLink);
96 aUseTableCB.SetClickHdl(aLink);
97 aFont1CB.SetSelectHdl(aLink);
98 aFont1CB.SetModifyHdl(aLink);
99 aFont2CB.SetSelectHdl(aLink);
100 aFont2CB.SetModifyHdl(aLink);
101 aNewDelTBX.SetClickHdl(aLink);
103 aNonPropFontsOnlyCB.SetClickHdl(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
105 static long aStaticTabs[] = { 4, 0, 0, 0, 0 };
106 long nW1 = GetTextWidth( sHeader1 );
107 long nW2 = GetTextWidth( sHeader2 );
108 long nMax = Max( nW1, nW2 ) + 6; // width of the longest header + a little offset
109 long nMin = aFontNameFT.LogicToPixel( Size( 30, 0 ), MAP_APPFONT ).Width();
110 nMax = Max( nMax, nMin );
111 const long nDoubleMax = 2*nMax;
112 const long nRest = aCheckLB.GetSizePixel().Width() - nDoubleMax;
113 aStaticTabs[2] = nMax;
114 aStaticTabs[3] = nDoubleMax;
115 aStaticTabs[4] = nDoubleMax + nRest/2;
116 aCheckLB.SvxSimpleTable::SetTabs( aStaticTabs, MAP_PIXEL );
118 String sHeader(sHeader1);
119 rtl::OUString sTab("\t");
120 rtl::OUString sTabSpace("\t ");
121 sHeader += sTab;
122 sHeader += sHeader2;
123 sHeader += sTabSpace;
124 sHeader += sHeader3;
125 sHeader += sTabSpace;
126 sHeader += sHeader4;
127 aCheckLB.InsertHeaderEntry(sHeader);
129 HeaderBar &rBar = aCheckLB.GetTheHeaderBar();
131 HeaderBarItemBits nBits = rBar.GetItemBits(1) | HIB_FIXEDPOS | HIB_FIXED;
132 nBits &= ~HIB_CLICKABLE;
133 rBar.SetItemBits(1, nBits);
134 rBar.SetItemBits(2, nBits);
136 sal_uInt16 nHeight;
137 for(nHeight = 6; nHeight <= 16; nHeight++)
138 aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight));
139 for(nHeight = 18; nHeight <= 28; nHeight+= 2)
140 aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight));
141 for(nHeight = 32; nHeight <= 48; nHeight+= 4)
142 aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight));
143 for(nHeight = 54; nHeight <= 72; nHeight+= 6)
144 aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight));
145 for(nHeight = 80; nHeight <= 96; nHeight+= 8)
146 aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight));
149 SvTreeListEntry* SvxFontSubstTabPage::CreateEntry(String& rFont1, String& rFont2)
151 SvTreeListEntry* pEntry = new SvTreeListEntry;
153 if( !pCheckButtonData )
154 pCheckButtonData = new SvLBoxButtonData( &aCheckLB );
156 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0)); // Sonst Puff!
158 pEntry->AddItem( new SvLBoxButton( pEntry,
159 SvLBoxButtonKind_enabledCheckbox, 0,
160 pCheckButtonData ) );
161 pEntry->AddItem( new SvLBoxButton( pEntry,
162 SvLBoxButtonKind_enabledCheckbox, 0,
163 pCheckButtonData ) );
165 pEntry->AddItem( new SvLBoxString( pEntry, 0, rFont1 ) );
166 pEntry->AddItem( new SvLBoxString( pEntry, 0, rFont2 ) );
168 return pEntry;
171 SvxFontSubstTabPage::~SvxFontSubstTabPage()
173 delete pCheckButtonData;
174 delete pConfig;
177 SfxTabPage* SvxFontSubstTabPage::Create( Window* pParent,
178 const SfxItemSet& rAttrSet)
180 return new SvxFontSubstTabPage(pParent, rAttrSet);
183 sal_Bool SvxFontSubstTabPage::FillItemSet( SfxItemSet& )
185 pConfig->ClearSubstitutions();// remove all entries
187 pConfig->Enable(aUseTableCB.IsChecked());
189 SvTreeListEntry* pEntry = aCheckLB.First();
191 while (pEntry)
193 SubstitutionStruct aAdd;
194 aAdd.sFont = aCheckLB.GetEntryText(pEntry, 0);
195 aAdd.sReplaceBy = aCheckLB.GetEntryText(pEntry, 1);
196 aAdd.bReplaceAlways = aCheckLB.IsChecked(pEntry, 0);
197 aAdd.bReplaceOnScreenOnly = aCheckLB.IsChecked(pEntry, 1);
198 pConfig->AddSubstitution(aAdd);
199 pEntry = aCheckLB.Next(pEntry);
201 if(pConfig->IsModified())
202 pConfig->Commit();
203 pConfig->Apply();
204 boost::shared_ptr< comphelper::ConfigurationChanges > batch(
205 comphelper::ConfigurationChanges::create());
206 if(aFontHeightLB.GetSavedValue() != aFontHeightLB.GetSelectEntryPos())
207 officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
208 static_cast< sal_Int16 >(aFontHeightLB.GetSelectEntry().ToInt32()),
209 batch);
210 if(aNonPropFontsOnlyCB.GetSavedValue() != aNonPropFontsOnlyCB.IsChecked())
211 officecfg::Office::Common::Font::SourceViewFont::
212 NonProportionalFontsOnly::set(
213 aNonPropFontsOnlyCB.IsChecked(), batch);
214 //font name changes cannot be detected by saved values
215 rtl::OUString sFontName;
216 if(aFontNameLB.GetSelectEntryPos())
217 sFontName = aFontNameLB.GetSelectEntry();
218 officecfg::Office::Common::Font::SourceViewFont::FontName::set(
219 boost::optional< rtl::OUString >(sFontName), batch);
220 batch->commit();
222 return sal_False;
225 void SvxFontSubstTabPage::Reset( const SfxItemSet& )
227 aCheckLB.SetUpdateMode(sal_False);
228 aCheckLB.Clear();
230 FontList aFntLst( Application::GetDefaultDevice() );
231 aFont1CB.Fill( &aFntLst );
232 aFont2CB.Fill( &aFntLst );
234 sal_Int32 nCount = pConfig->SubstitutionCount();
235 if (nCount)
236 aUseTableCB.Check(pConfig->IsEnabled());
238 for (sal_Int32 i = 0; i < nCount; i++)
240 const SubstitutionStruct* pSubs = pConfig->GetSubstitution(i);
241 String aTmpStr1(pSubs->sFont);
242 String aTmpStr2(pSubs->sReplaceBy);
243 SvTreeListEntry* pEntry = CreateEntry(aTmpStr1, aTmpStr2);
244 aCheckLB.Insert(pEntry);
245 aCheckLB.CheckEntry(pEntry, 0, pSubs->bReplaceAlways);
246 aCheckLB.CheckEntry(pEntry, 1, pSubs->bReplaceOnScreenOnly);
249 CheckEnable();
250 aCheckLB.SetUpdateMode(sal_True);
252 //fill font name box first
253 aNonPropFontsOnlyCB.Check(
254 officecfg::Office::Common::Font::SourceViewFont::
255 NonProportionalFontsOnly::get());
256 NonPropFontsHdl(&aNonPropFontsOnlyCB);
257 rtl::OUString sFontName(
258 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
259 get_value_or(rtl::OUString()));
260 if(!sFontName.isEmpty())
261 aFontNameLB.SelectEntry(sFontName);
262 else
263 aFontNameLB.SelectEntryPos(0);
264 aFontHeightLB.SelectEntry(
265 String::CreateFromInt32(
266 officecfg::Office::Common::Font::SourceViewFont::FontHeight::
267 get()));
268 aNonPropFontsOnlyCB.SaveValue();
269 aFontHeightLB.SaveValue();
272 IMPL_LINK(SvxFontSubstTabPage, SelectHdl, Window*, pWin)
274 if (pWin == &aNewDelTBX)
276 SvTreeListEntry* pEntry;
277 // nCol is stupidly the nCol'th text column, not counted!
278 // Therefor "0" as column.
279 sal_uLong nPos = aCheckLB.GetEntryPos(aFont1CB.GetText(), 0);
281 switch (aNewDelTBX.GetCurItemId())
283 case BT_SUBSTAPPLY:
285 if (nPos != 0xffffffff)
287 // change entry
288 aCheckLB.SetEntryText(aFont2CB.GetText(), nPos, 1);
289 pEntry = aCheckLB.GetEntry(nPos);
291 else
293 // new entry
294 String sFont1 = aFont1CB.GetText();
295 String sFont2 = aFont2CB.GetText();
297 pEntry = CreateEntry(sFont1, sFont2);
298 aCheckLB.Insert(pEntry);
300 aCheckLB.SelectAll(sal_False);
301 aCheckLB.Select(pEntry);
303 break;
305 case BT_SUBSTDELETE:
307 if (nPos != 0xffffffff)
309 pEntry = aCheckLB.FirstSelected();
310 while (pEntry)
312 SvTreeListEntry* pDelEntry = pEntry;
313 pEntry = aCheckLB.NextSelected(pEntry);
314 aCheckLB.RemoveEntry(pDelEntry);
318 break;
322 if (pWin == &aCheckLB)
324 SvTreeListEntry* pEntry = aCheckLB.FirstSelected();
326 if (aCheckLB.NextSelected(pEntry) == 0)
328 aFont1CB.SetText(aCheckLB.GetEntryText(pEntry, 0));
329 aFont2CB.SetText(aCheckLB.GetEntryText(pEntry, 1));
333 if (pWin == &aFont1CB)
335 sal_uLong nPos = aCheckLB.GetEntryPos(aFont1CB.GetText(), 0);
337 if (nPos != 0xffffffff)
339 SvTreeListEntry* pEntry = aCheckLB.GetEntry(nPos);
341 if (pEntry != aCheckLB.FirstSelected())
343 aCheckLB.SelectAll(sal_False);
344 aCheckLB.Select(pEntry);
349 CheckEnable();
351 return 0;
354 //--------------------------------------------------------------------------
355 IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, CheckBox*, pBox)
357 String sFontName = aFontNameLB.GetSelectEntry();
358 sal_Bool bNonPropOnly = pBox->IsChecked();
359 aFontNameLB.Clear();
360 FontList aFntLst( Application::GetDefaultDevice() );
361 aFontNameLB.InsertEntry(sAutomatic);
362 sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
363 for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
365 const FontInfo& rInfo = aFntLst.GetFontName( nFont );
366 if(!bNonPropOnly || rInfo.GetPitch() == PITCH_FIXED)
367 aFontNameLB.InsertEntry(rInfo.GetName());
369 aFontNameLB.SelectEntry(sFontName);
370 return 0;
373 void SvxFontSubstTabPage::CheckEnable()
375 sal_Bool bEnableAll = aUseTableCB.IsChecked();
377 if (bEnableAll)
379 sal_Bool bApply, bDelete;
381 SvTreeListEntry* pEntry = aCheckLB.FirstSelected();
383 String sEntry = aFont1CB.GetText();
384 sEntry += '\t';
385 sEntry += aFont2CB.GetText();
387 // because of OS/2 optimization error (Bug #56267) a bit more intricate:
388 if (!aFont1CB.GetText().Len() || !aFont2CB.GetText().Len())
389 bApply = sal_False;
390 else if(aFont1CB.GetText() == aFont2CB.GetText())
391 bApply = sal_False;
392 else if(aCheckLB.GetEntryPos(sEntry) != 0xffffffff)
393 bApply = sal_False;
394 else if(pEntry != 0 && aCheckLB.NextSelected(pEntry) != 0)
395 bApply = sal_False;
396 else
397 bApply = sal_True;
399 bDelete = pEntry != 0;
401 aNewDelTBX.EnableItem(BT_SUBSTAPPLY, bApply);
402 aNewDelTBX.EnableItem(BT_SUBSTDELETE, bDelete);
405 if (bEnableAll)
407 if (!aCheckLB.IsEnabled())
409 aCheckLB.EnableTable();
410 aCheckLB.SetTextColor(aTextColor);
411 aCheckLB.Invalidate();
412 SelectHdl(&aFont1CB);
415 else
417 if (aCheckLB.IsEnabled())
419 aCheckLB.DisableTable();
420 aCheckLB.SetTextColor(Color(COL_GRAY));
421 aCheckLB.Invalidate();
422 aCheckLB.SelectAll(sal_False);
425 aNewDelTBX.Enable(bEnableAll);
426 aFont1FT.Enable(bEnableAll);
427 aFont1CB.Enable(bEnableAll);
428 aFont2FT.Enable(bEnableAll);
429 aFont2CB.Enable(bEnableAll);
432 void SvxFontSubstCheckListBox::SetTabs()
434 SvxSimpleTable::SetTabs();
435 sal_uInt16 nAdjust = SV_LBOXTAB_ADJUST_RIGHT|SV_LBOXTAB_ADJUST_LEFT|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_ADJUST_NUMERIC|SV_LBOXTAB_FORCE;
437 SvLBoxTab* pTab = aTabs[1];
438 pTab->nFlags &= ~nAdjust;
439 pTab->nFlags |= SV_LBOXTAB_PUSHABLE|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_FORCE;
441 pTab = aTabs[2];
442 pTab->nFlags &= ~nAdjust;
443 pTab->nFlags |= SV_LBOXTAB_PUSHABLE|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_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 SvxSimpleTable::KeyInput(rKEvt);
473 void SvxFontSubstCheckListBox::CheckEntryPos(sal_uLong nPos, sal_uInt16 nCol, sal_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, sal_Bool bChecked)
485 if ( pEntry )
486 SetCheckButtonState(
487 pEntry,
488 nCol,
489 bChecked ? SvButtonState( SV_BUTTON_CHECKED ) :
490 SvButtonState( SV_BUTTON_UNCHECKED ) );
493 sal_Bool SvxFontSubstCheckListBox::IsChecked(sal_uLong nPos, sal_uInt16 nCol)
495 return GetCheckButtonState( GetEntry(nPos), nCol ) == SV_BUTTON_CHECKED;
498 sal_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 = (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 ) const
530 SvButtonState eState = SV_BUTTON_UNCHECKED;
531 SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetItem(nCol + 1));
532 DBG_ASSERT(pItem,"GetChButnState:Item not found");
534 if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON)
536 sal_uInt16 nButtonFlags = pItem->GetButtonFlags();
537 eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
540 return eState;
544 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */