/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include "sal/config.h" #include #include #include #include #include #include #include #include "fontsubs.hrc" #include "fontsubs.hxx" #include #include "helpid.hrc" #include /*********************************************************************/ /* */ /* TabPage font replacement */ /* */ /*********************************************************************/ SvxFontSubstTabPage::SvxFontSubstTabPage( Window* pParent, const SfxItemSet& rSet ) : SfxTabPage(pParent, CUI_RES(RID_SVX_FONT_SUBSTITUTION), rSet), aUseTableCB (this, CUI_RES(CB_USETABLE)), aFont1FT (this, CUI_RES(FT_FONT1)), aFont1CB (this, CUI_RES(CB_FONT1)), aFont2FT (this, CUI_RES(FT_FONT2)), aFont2CB (this, CUI_RES(CB_FONT2)), aNewDelTBX (this, CUI_RES(TBX_SUBSTNEWDEL)), m_aCheckLBContainer(this, CUI_RES(CLB_SUBSTITUTES)), aCheckLB(m_aCheckLBContainer), aSourceViewFontsFL (this, CUI_RES(FL_SOURCEVIEW )), aFontNameFT (this, CUI_RES(FT_FONTNAME )), aFontNameLB (this, CUI_RES(LB_FONTNAME )), aNonPropFontsOnlyCB(this, CUI_RES(CB_NONPROP )), aFontHeightFT (this, CUI_RES(FT_FONTHEIGHT )), aFontHeightLB (this, CUI_RES(LB_FONTHEIGHT )), aImageList (CUI_RES(IL_ICON)), sAutomatic (CUI_RES( STR_AUTOMATIC )), pConfig(new SvtFontSubstConfig), sHeader1 (CUI_RES( STR_HEADER1 )), sHeader2 (CUI_RES( STR_HEADER2 )), sHeader3 (CUI_RES( STR_HEADER3 )), sHeader4 (CUI_RES( STR_HEADER4 )), pCheckButtonData(0) { FreeResource(); aTextColor = aCheckLB.GetTextColor(); for(sal_uInt16 k = 0; k < aNewDelTBX.GetItemCount(); k++) aNewDelTBX.SetItemImage(aNewDelTBX.GetItemId(k), aImageList.GetImage(aNewDelTBX.GetItemId(k))); aNewDelTBX.SetSizePixel( aNewDelTBX.CalcWindowSizePixel() ); long nDelta = ( aFont1CB.GetSizePixel().Height() - aNewDelTBX.GetSizePixel().Height() ) / 2; Point aNewPnt = aNewDelTBX.GetPosPixel(); aNewPnt.Y() += nDelta; aNewDelTBX.SetPosPixel( aNewPnt ); aCheckLB.SetHelpId(HID_OFA_FONT_SUBST_CLB); aCheckLB.SetStyle(aCheckLB.GetStyle()|WB_HSCROLL|WB_VSCROLL); aCheckLB.SetSelectionMode(MULTIPLE_SELECTION); aCheckLB.SortByCol(2); Link aLink(LINK(this, SvxFontSubstTabPage, SelectHdl)); aCheckLB.SetSelectHdl(aLink); aUseTableCB.SetClickHdl(aLink); aFont1CB.SetSelectHdl(aLink); aFont1CB.SetModifyHdl(aLink); aFont2CB.SetSelectHdl(aLink); aFont2CB.SetModifyHdl(aLink); aNewDelTBX.SetClickHdl(aLink); aNonPropFontsOnlyCB.SetClickHdl(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl)); static long aStaticTabs[] = { 4, 0, 0, 0, 0 }; long nW1 = GetTextWidth( sHeader1 ); long nW2 = GetTextWidth( sHeader2 ); long nMax = Max( nW1, nW2 ) + 6; // width of the longest header + a little offset long nMin = aFontNameFT.LogicToPixel( Size( 30, 0 ), MAP_APPFONT ).Width(); nMax = Max( nMax, nMin ); const long nDoubleMax = 2*nMax; const long nRest = aCheckLB.GetSizePixel().Width() - nDoubleMax; aStaticTabs[2] = nMax; aStaticTabs[3] = nDoubleMax; aStaticTabs[4] = nDoubleMax + nRest/2; aCheckLB.SvxSimpleTable::SetTabs( aStaticTabs, MAP_PIXEL ); String sHeader(sHeader1); rtl::OUString sTab("\t"); rtl::OUString sTabSpace("\t "); sHeader += sTab; sHeader += sHeader2; sHeader += sTabSpace; sHeader += sHeader3; sHeader += sTabSpace; sHeader += sHeader4; aCheckLB.InsertHeaderEntry(sHeader); HeaderBar &rBar = aCheckLB.GetTheHeaderBar(); HeaderBarItemBits nBits = rBar.GetItemBits(1) | HIB_FIXEDPOS | HIB_FIXED; nBits &= ~HIB_CLICKABLE; rBar.SetItemBits(1, nBits); rBar.SetItemBits(2, nBits); sal_uInt16 nHeight; for(nHeight = 6; nHeight <= 16; nHeight++) aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight)); for(nHeight = 18; nHeight <= 28; nHeight+= 2) aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight)); for(nHeight = 32; nHeight <= 48; nHeight+= 4) aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight)); for(nHeight = 54; nHeight <= 72; nHeight+= 6) aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight)); for(nHeight = 80; nHeight <= 96; nHeight+= 8) aFontHeightLB.InsertEntry(String::CreateFromInt32(nHeight)); } SvTreeListEntry* SvxFontSubstTabPage::CreateEntry(String& rFont1, String& rFont2) { SvTreeListEntry* pEntry = new SvTreeListEntry; if( !pCheckButtonData ) pCheckButtonData = new SvLBoxButtonData( &aCheckLB ); pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0)); // Sonst Puff! pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) ); pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) ); pEntry->AddItem( new SvLBoxString( pEntry, 0, rFont1 ) ); pEntry->AddItem( new SvLBoxString( pEntry, 0, rFont2 ) ); return pEntry; } SvxFontSubstTabPage::~SvxFontSubstTabPage() { delete pCheckButtonData; delete pConfig; } SfxTabPage* SvxFontSubstTabPage::Create( Window* pParent, const SfxItemSet& rAttrSet) { return new SvxFontSubstTabPage(pParent, rAttrSet); } sal_Bool SvxFontSubstTabPage::FillItemSet( SfxItemSet& ) { pConfig->ClearSubstitutions();// remove all entries pConfig->Enable(aUseTableCB.IsChecked()); SvTreeListEntry* pEntry = aCheckLB.First(); while (pEntry) { SubstitutionStruct aAdd; aAdd.sFont = aCheckLB.GetEntryText(pEntry, 0); aAdd.sReplaceBy = aCheckLB.GetEntryText(pEntry, 1); aAdd.bReplaceAlways = aCheckLB.IsChecked(pEntry, 0); aAdd.bReplaceOnScreenOnly = aCheckLB.IsChecked(pEntry, 1); pConfig->AddSubstitution(aAdd); pEntry = aCheckLB.Next(pEntry); } if(pConfig->IsModified()) pConfig->Commit(); pConfig->Apply(); boost::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create()); if(aFontHeightLB.GetSavedValue() != aFontHeightLB.GetSelectEntryPos()) officecfg::Office::Common::Font::SourceViewFont::FontHeight::set( static_cast< sal_Int16 >(aFontHeightLB.GetSelectEntry().ToInt32()), batch); if(aNonPropFontsOnlyCB.GetSavedValue() != aNonPropFontsOnlyCB.IsChecked()) officecfg::Office::Common::Font::SourceViewFont:: NonProportionalFontsOnly::set( aNonPropFontsOnlyCB.IsChecked(), batch); //font name changes cannot be detected by saved values rtl::OUString sFontName; if(aFontNameLB.GetSelectEntryPos()) sFontName = aFontNameLB.GetSelectEntry(); officecfg::Office::Common::Font::SourceViewFont::FontName::set( boost::optional< rtl::OUString >(sFontName), batch); batch->commit(); return sal_False; } void SvxFontSubstTabPage::Reset( const SfxItemSet& ) { aCheckLB.SetUpdateMode(sal_False); aCheckLB.Clear(); FontList aFntLst( Application::GetDefaultDevice() ); aFont1CB.Fill( &aFntLst ); aFont2CB.Fill( &aFntLst ); sal_Int32 nCount = pConfig->SubstitutionCount(); if (nCount) aUseTableCB.Check(pConfig->IsEnabled()); for (sal_Int32 i = 0; i < nCount; i++) { const SubstitutionStruct* pSubs = pConfig->GetSubstitution(i); String aTmpStr1(pSubs->sFont); String aTmpStr2(pSubs->sReplaceBy); SvTreeListEntry* pEntry = CreateEntry(aTmpStr1, aTmpStr2); aCheckLB.Insert(pEntry); aCheckLB.CheckEntry(pEntry, 0, pSubs->bReplaceAlways); aCheckLB.CheckEntry(pEntry, 1, pSubs->bReplaceOnScreenOnly); } CheckEnable(); aCheckLB.SetUpdateMode(sal_True); //fill font name box first aNonPropFontsOnlyCB.Check( officecfg::Office::Common::Font::SourceViewFont:: NonProportionalFontsOnly::get()); NonPropFontsHdl(&aNonPropFontsOnlyCB); rtl::OUString sFontName( officecfg::Office::Common::Font::SourceViewFont::FontName::get(). get_value_or(rtl::OUString())); if(!sFontName.isEmpty()) aFontNameLB.SelectEntry(sFontName); else aFontNameLB.SelectEntryPos(0); aFontHeightLB.SelectEntry( String::CreateFromInt32( officecfg::Office::Common::Font::SourceViewFont::FontHeight:: get())); aNonPropFontsOnlyCB.SaveValue(); aFontHeightLB.SaveValue(); } IMPL_LINK(SvxFontSubstTabPage, SelectHdl, Window*, pWin) { if (pWin == &aNewDelTBX) { SvTreeListEntry* pEntry; // nCol is stupidly the nCol'th text column, not counted! // Therefor "0" as column. sal_uLong nPos = aCheckLB.GetEntryPos(aFont1CB.GetText(), 0); switch (aNewDelTBX.GetCurItemId()) { case BT_SUBSTAPPLY: { if (nPos != 0xffffffff) { // change entry aCheckLB.SetEntryText(aFont2CB.GetText(), nPos, 1); pEntry = aCheckLB.GetEntry(nPos); } else { // new entry String sFont1 = aFont1CB.GetText(); String sFont2 = aFont2CB.GetText(); pEntry = CreateEntry(sFont1, sFont2); aCheckLB.Insert(pEntry); } aCheckLB.SelectAll(sal_False); aCheckLB.Select(pEntry); } break; case BT_SUBSTDELETE: { if (nPos != 0xffffffff) { pEntry = aCheckLB.FirstSelected(); while (pEntry) { SvTreeListEntry* pDelEntry = pEntry; pEntry = aCheckLB.NextSelected(pEntry); aCheckLB.RemoveEntry(pDelEntry); } } } break; } } if (pWin == &aCheckLB) { SvTreeListEntry* pEntry = aCheckLB.FirstSelected(); if (aCheckLB.NextSelected(pEntry) == 0) { aFont1CB.SetText(aCheckLB.GetEntryText(pEntry, 0)); aFont2CB.SetText(aCheckLB.GetEntryText(pEntry, 1)); } } if (pWin == &aFont1CB) { sal_uLong nPos = aCheckLB.GetEntryPos(aFont1CB.GetText(), 0); if (nPos != 0xffffffff) { SvTreeListEntry* pEntry = aCheckLB.GetEntry(nPos); if (pEntry != aCheckLB.FirstSelected()) { aCheckLB.SelectAll(sal_False); aCheckLB.Select(pEntry); } } } CheckEnable(); return 0; } //-------------------------------------------------------------------------- IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, CheckBox*, pBox) { String sFontName = aFontNameLB.GetSelectEntry(); sal_Bool bNonPropOnly = pBox->IsChecked(); aFontNameLB.Clear(); FontList aFntLst( Application::GetDefaultDevice() ); aFontNameLB.InsertEntry(sAutomatic); sal_uInt16 nFontCount = aFntLst.GetFontNameCount(); for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++) { const FontInfo& rInfo = aFntLst.GetFontName( nFont ); if(!bNonPropOnly || rInfo.GetPitch() == PITCH_FIXED) aFontNameLB.InsertEntry(rInfo.GetName()); } aFontNameLB.SelectEntry(sFontName); return 0; } void SvxFontSubstTabPage::CheckEnable() { sal_Bool bEnableAll = aUseTableCB.IsChecked(); if (bEnableAll) { sal_Bool bApply, bDelete; SvTreeListEntry* pEntry = aCheckLB.FirstSelected(); String sEntry = aFont1CB.GetText(); sEntry += '\t'; sEntry += aFont2CB.GetText(); // because of OS/2 optimization error (Bug #56267) a bit more intricate: if (!aFont1CB.GetText().Len() || !aFont2CB.GetText().Len()) bApply = sal_False; else if(aFont1CB.GetText() == aFont2CB.GetText()) bApply = sal_False; else if(aCheckLB.GetEntryPos(sEntry) != 0xffffffff) bApply = sal_False; else if(pEntry != 0 && aCheckLB.NextSelected(pEntry) != 0) bApply = sal_False; else bApply = sal_True; bDelete = pEntry != 0; aNewDelTBX.EnableItem(BT_SUBSTAPPLY, bApply); aNewDelTBX.EnableItem(BT_SUBSTDELETE, bDelete); } if (bEnableAll) { if (!aCheckLB.IsEnabled()) { aCheckLB.EnableTable(); aCheckLB.SetTextColor(aTextColor); aCheckLB.Invalidate(); SelectHdl(&aFont1CB); } } else { if (aCheckLB.IsEnabled()) { aCheckLB.DisableTable(); aCheckLB.SetTextColor(Color(COL_GRAY)); aCheckLB.Invalidate(); aCheckLB.SelectAll(sal_False); } } aNewDelTBX.Enable(bEnableAll); aFont1FT.Enable(bEnableAll); aFont1CB.Enable(bEnableAll); aFont2FT.Enable(bEnableAll); aFont2CB.Enable(bEnableAll); } void SvxFontSubstCheckListBox::SetTabs() { SvxSimpleTable::SetTabs(); sal_uInt16 nAdjust = SV_LBOXTAB_ADJUST_RIGHT|SV_LBOXTAB_ADJUST_LEFT|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_ADJUST_NUMERIC|SV_LBOXTAB_FORCE; SvLBoxTab* pTab = aTabs[1]; pTab->nFlags &= ~nAdjust; pTab->nFlags |= SV_LBOXTAB_PUSHABLE|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_FORCE; pTab = aTabs[2]; pTab->nFlags &= ~nAdjust; pTab->nFlags |= SV_LBOXTAB_PUSHABLE|SV_LBOXTAB_ADJUST_CENTER|SV_LBOXTAB_FORCE; } void SvxFontSubstCheckListBox::KeyInput( const KeyEvent& rKEvt ) { if(!rKEvt.GetKeyCode().GetModifier() && KEY_SPACE == rKEvt.GetKeyCode().GetCode()) { sal_uLong nSelPos = GetModel()->GetAbsPos(GetCurEntry()); sal_uInt16 nCol = GetCurrentTabPos() - 1; if ( nCol < 2 ) { CheckEntryPos( nSelPos, nCol, !IsChecked( nSelPos, nCol ) ); CallImplEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)GetEntry( nSelPos ) ); } else { sal_uInt16 nCheck = IsChecked(nSelPos, 1) ? 1 : 0; if(IsChecked(nSelPos, 0)) nCheck += 2; nCheck--; nCheck &= 3; CheckEntryPos(nSelPos, 1, 0 != (nCheck & 1)); CheckEntryPos(nSelPos, 0, 0 != (nCheck & 2)); } } else SvxSimpleTable::KeyInput(rKEvt); } void SvxFontSubstCheckListBox::CheckEntryPos(sal_uLong nPos, sal_uInt16 nCol, sal_Bool bChecked) { if ( nPos < GetEntryCount() ) SetCheckButtonState( GetEntry(nPos), nCol, bChecked ? SvButtonState( SV_BUTTON_CHECKED ) : SvButtonState( SV_BUTTON_UNCHECKED ) ); } void SvxFontSubstCheckListBox::CheckEntry(SvTreeListEntry* pEntry, sal_uInt16 nCol, sal_Bool bChecked) { if ( pEntry ) SetCheckButtonState( pEntry, nCol, bChecked ? SvButtonState( SV_BUTTON_CHECKED ) : SvButtonState( SV_BUTTON_UNCHECKED ) ); } sal_Bool SvxFontSubstCheckListBox::IsChecked(sal_uLong nPos, sal_uInt16 nCol) { return GetCheckButtonState( GetEntry(nPos), nCol ) == SV_BUTTON_CHECKED; } sal_Bool SvxFontSubstCheckListBox::IsChecked(SvTreeListEntry* pEntry, sal_uInt16 nCol) { return GetCheckButtonState( pEntry, nCol ) == SV_BUTTON_CHECKED; } void SvxFontSubstCheckListBox::SetCheckButtonState( SvTreeListEntry* pEntry, sal_uInt16 nCol, SvButtonState eState) { SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetItem(nCol + 1)); DBG_ASSERT(pItem,"SetCheckButton:Item not found"); if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON) { switch( eState ) { case SV_BUTTON_CHECKED: pItem->SetStateChecked(); break; case SV_BUTTON_UNCHECKED: pItem->SetStateUnchecked(); break; case SV_BUTTON_TRISTATE: pItem->SetStateTristate(); break; } InvalidateEntry( pEntry ); } } SvButtonState SvxFontSubstCheckListBox::GetCheckButtonState( SvTreeListEntry* pEntry, sal_uInt16 nCol ) const { SvButtonState eState = SV_BUTTON_UNCHECKED; SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetItem(nCol + 1)); DBG_ASSERT(pItem,"GetChButnState:Item not found"); if (pItem->GetType() == SV_ITEM_ID_LBOXBUTTON) { sal_uInt16 nButtonFlags = pItem->GetButtonFlags(); eState = pCheckButtonData->ConvertToButtonState( nButtonFlags ); } return eState; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */