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 <vcl/svapp.hxx>
25 #include <svtools/fontsubstconfig.hxx>
26 #include "fontsubs.hxx"
29 /*********************************************************************/
31 /* TabPage font replacement */
33 /*********************************************************************/
35 SvxFontSubstTabPage::SvxFontSubstTabPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rSet
)
36 : SfxTabPage(pPage
, pController
, "cui/ui/optfontspage.ui", "OptFontsPage", &rSet
)
37 , m_xConfig(new SvtFontSubstConfig
)
39 , m_xUseTableCB(m_xBuilder
->weld_check_button("usetable"))
40 , m_xFont1CB(m_xBuilder
->weld_combo_box("font1"))
41 , m_xFont2CB(m_xBuilder
->weld_combo_box("font2"))
42 , m_xApply(m_xBuilder
->weld_button("apply"))
43 , m_xDelete(m_xBuilder
->weld_button("delete"))
44 , m_xCheckLB(m_xBuilder
->weld_tree_view("checklb"))
45 , m_xFontNameLB(m_xBuilder
->weld_combo_box("fontname"))
46 , m_xNonPropFontsOnlyCB(m_xBuilder
->weld_check_button("nonpropfontonly"))
47 , m_xFontHeightLB(m_xBuilder
->weld_combo_box("fontheight"))
49 m_xFont1CB
->make_sorted();
50 m_xFont1CB
->set_size_request(1, -1);
51 m_xFont2CB
->make_sorted();
52 m_xFont2CB
->set_size_request(1, -1);
53 m_sAutomatic
= m_xFontNameLB
->get_text(0);
54 assert(!m_sAutomatic
.isEmpty());
56 m_xCheckLB
->set_size_request(m_xCheckLB
->get_approximate_digit_width() * 80,
57 m_xCheckLB
->get_height_rows(10));
58 m_xCheckLB
->set_help_id(HID_OFA_FONT_SUBST_CLB
);
59 m_xCheckLB
->set_selection_mode(SelectionMode::Multiple
);
60 m_xCheckLB
->set_sort_column(3);
64 m_xCheckLB
->set_centered_column(1);
65 m_xCheckLB
->set_centered_column(2);
67 Link
<weld::ComboBox
&,void> aLink2(LINK(this, SvxFontSubstTabPage
, SelectComboBoxHdl
));
68 Link
<weld::Button
&,void> aClickLink(LINK(this, SvxFontSubstTabPage
, ClickHdl
));
70 m_xCheckLB
->connect_changed(LINK(this, SvxFontSubstTabPage
, TreeListBoxSelectHdl
));
71 m_xCheckLB
->connect_column_clicked(LINK(this, SvxFontSubstTabPage
, HeaderBarClick
));
72 m_xUseTableCB
->connect_clicked(aClickLink
);
73 m_xFont1CB
->connect_changed(aLink2
);
74 m_xFont2CB
->connect_changed(aLink2
);
75 m_xApply
->connect_clicked(aClickLink
);
76 m_xDelete
->connect_clicked(aClickLink
);
78 m_xNonPropFontsOnlyCB
->connect_toggled(LINK(this, SvxFontSubstTabPage
, NonPropFontsHdl
));
81 for(nHeight
= 6; nHeight
<= 16; nHeight
++)
82 m_xFontHeightLB
->append_text(OUString::number(nHeight
));
83 for(nHeight
= 18; nHeight
<= 28; nHeight
+= 2)
84 m_xFontHeightLB
->append_text(OUString::number(nHeight
));
85 for(nHeight
= 32; nHeight
<= 48; nHeight
+= 4)
86 m_xFontHeightLB
->append_text(OUString::number(nHeight
));
87 for(nHeight
= 54; nHeight
<= 72; nHeight
+= 6)
88 m_xFontHeightLB
->append_text(OUString::number(nHeight
));
89 for(nHeight
= 80; nHeight
<= 96; nHeight
+= 8)
90 m_xFontHeightLB
->append_text(OUString::number(nHeight
));
93 IMPL_LINK(SvxFontSubstTabPage
, HeaderBarClick
, int, nColumn
, void)
97 m_xCheckLB
->make_sorted();
101 bool bSortAtoZ
= m_xCheckLB
->get_sort_order();
103 //set new arrow positions in headerbar
104 if (nColumn
== m_xCheckLB
->get_sort_column())
106 bSortAtoZ
= !bSortAtoZ
;
107 m_xCheckLB
->set_sort_order(bSortAtoZ
);
111 m_xCheckLB
->set_sort_indicator(TRISTATE_INDET
, m_xCheckLB
->get_sort_column());
112 m_xCheckLB
->set_sort_column(nColumn
);
118 m_xCheckLB
->set_sort_indicator(bSortAtoZ
? TRISTATE_TRUE
: TRISTATE_FALSE
, nColumn
);
122 void SvxFontSubstTabPage::setColSizes()
124 int nW1
= m_xCheckLB
->get_pixel_size(m_xCheckLB
->get_column_title(3)).Width();
125 int nW2
= m_xCheckLB
->get_pixel_size(m_xCheckLB
->get_column_title(4)).Width();
126 int nMax
= std::max( nW1
, nW2
) + 6; // width of the longest header + a little offset
127 int nMin
= m_xCheckLB
->get_checkbox_column_width();
128 nMax
= std::max(nMax
, nMin
);
129 const int nDoubleMax
= 2*nMax
;
130 const int nRest
= m_xCheckLB
->get_size_request().Width() - nDoubleMax
;
131 std::vector
<int> aWidths
;
132 aWidths
.push_back(1); // just abandon the built-in column for checkbuttons and use another
133 aWidths
.push_back(nMax
);
134 aWidths
.push_back(nMax
);
135 aWidths
.push_back(nRest
/2);
136 m_xCheckLB
->set_column_fixed_widths(aWidths
);
139 SvxFontSubstTabPage::~SvxFontSubstTabPage()
143 std::unique_ptr
<SfxTabPage
> SvxFontSubstTabPage::Create( weld::Container
* pPage
, weld::DialogController
* pController
,
144 const SfxItemSet
* rAttrSet
)
146 return std::make_unique
<SvxFontSubstTabPage
>(pPage
, pController
, *rAttrSet
);
149 bool SvxFontSubstTabPage::FillItemSet( SfxItemSet
* )
151 m_xConfig
->ClearSubstitutions();// remove all entries
153 m_xConfig
->Enable(m_xUseTableCB
->get_active());
155 m_xCheckLB
->all_foreach([this](weld::TreeIter
& rIter
) {
156 SubstitutionStruct aAdd
;
157 aAdd
.sFont
= m_xCheckLB
->get_text(rIter
, 3);
158 aAdd
.sReplaceBy
= m_xCheckLB
->get_text(rIter
, 4);
159 aAdd
.bReplaceAlways
= m_xCheckLB
->get_toggle(rIter
, 1);
160 aAdd
.bReplaceOnScreenOnly
= m_xCheckLB
->get_toggle(rIter
, 2);
161 m_xConfig
->AddSubstitution(aAdd
);
165 if(m_xConfig
->IsModified())
168 std::shared_ptr
< comphelper::ConfigurationChanges
> batch(
169 comphelper::ConfigurationChanges::create());
170 if (m_xFontHeightLB
->get_value_changed_from_saved())
171 officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
172 static_cast< sal_Int16
>(m_xFontHeightLB
->get_active_text().toInt32()),
174 if (m_xNonPropFontsOnlyCB
->get_state_changed_from_saved())
175 officecfg::Office::Common::Font::SourceViewFont::
176 NonProportionalFontsOnly::set(
177 m_xNonPropFontsOnlyCB
->get_active(), batch
);
178 //font name changes cannot be detected by saved values
180 if (m_xFontNameLB
->get_active() != -1)
181 sFontName
= m_xFontNameLB
->get_active_text();
182 officecfg::Office::Common::Font::SourceViewFont::FontName::set(
183 boost::optional
< OUString
>(sFontName
), batch
);
189 void SvxFontSubstTabPage::Reset( const SfxItemSet
* )
191 m_xCheckLB
->freeze();
194 FontList
aFntLst(Application::GetDefaultDevice());
195 sal_uInt16 nFontCount
= aFntLst
.GetFontNameCount();
196 for (sal_uInt16 i
= 0; i
< nFontCount
; ++i
)
198 const FontMetric
& rFontMetric
= aFntLst
.GetFontName(i
);
199 m_xFont1CB
->append_text(rFontMetric
.GetFamilyName());
200 m_xFont2CB
->append_text(rFontMetric
.GetFamilyName());
203 sal_Int32 nCount
= m_xConfig
->SubstitutionCount();
205 m_xUseTableCB
->set_active(m_xConfig
->IsEnabled());
207 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
209 m_xCheckLB
->append();
210 const SubstitutionStruct
* pSubs
= m_xConfig
->GetSubstitution(i
);
211 m_xCheckLB
->set_toggle(i
, pSubs
->bReplaceAlways
? TRISTATE_TRUE
: TRISTATE_FALSE
, 1);
212 m_xCheckLB
->set_toggle(i
, pSubs
->bReplaceOnScreenOnly
? TRISTATE_TRUE
: TRISTATE_FALSE
, 2);
213 m_xCheckLB
->set_text(i
, pSubs
->sFont
, 3);
214 m_xCheckLB
->set_text(i
, pSubs
->sReplaceBy
, 4);
221 //fill font name box first
222 m_xNonPropFontsOnlyCB
->set_active(
223 officecfg::Office::Common::Font::SourceViewFont::
224 NonProportionalFontsOnly::get());
225 NonPropFontsHdl(*m_xNonPropFontsOnlyCB
);
227 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
228 get_value_or(OUString()));
229 if(!sFontName
.isEmpty())
230 m_xFontNameLB
->set_active_text(sFontName
);
232 m_xFontNameLB
->set_active(0);
233 m_xFontHeightLB
->set_active_text(
235 officecfg::Office::Common::Font::SourceViewFont::FontHeight::
237 m_xNonPropFontsOnlyCB
->save_state();
238 m_xFontHeightLB
->save_value();
241 IMPL_LINK(SvxFontSubstTabPage
, ClickHdl
, weld::Button
&, rButton
, void)
246 IMPL_LINK(SvxFontSubstTabPage
, TreeListBoxSelectHdl
, weld::TreeView
&, rButton
, void)
251 IMPL_LINK(SvxFontSubstTabPage
, SelectComboBoxHdl
, weld::ComboBox
&, rBox
, void)
258 // search in the "font" column
259 int findText(const weld::TreeView
& rTreeView
, const OUString
& rCol
)
261 for (int i
= 0, nEntryCount
= rTreeView
.n_children(); i
< nEntryCount
; ++i
)
263 if (rTreeView
.get_text(i
, 3) == rCol
)
269 bool findRow(const weld::TreeView
& rTreeView
, const OUString
& rCol1
, const OUString
& rCol2
)
271 int nRow
= findText(rTreeView
, rCol1
);
274 return rTreeView
.get_text(nRow
, 4) == rCol2
;
278 void SvxFontSubstTabPage::SelectHdl(const weld::Widget
* pWin
)
280 if (pWin
== m_xApply
.get() || pWin
== m_xDelete
.get())
282 int nPos
= findText(*m_xCheckLB
, m_xFont1CB
->get_active_text());
283 if (pWin
== m_xApply
.get())
288 m_xCheckLB
->set_text(nPos
, m_xFont2CB
->get_active_text(), 4);
293 OUString sFont1
= m_xFont1CB
->get_active_text();
294 OUString sFont2
= m_xFont2CB
->get_active_text();
296 nPos
= m_xCheckLB
->n_children();
297 m_xCheckLB
->append();
298 m_xCheckLB
->set_toggle(nPos
, TRISTATE_FALSE
, 1);
299 m_xCheckLB
->set_toggle(nPos
, TRISTATE_FALSE
, 2);
300 m_xCheckLB
->set_text(nPos
, sFont1
, 3);
301 m_xCheckLB
->set_text(nPos
, sFont2
, 4);
304 m_xCheckLB
->unselect_all();
305 m_xCheckLB
->select(nPos
);
307 else if (pWin
== m_xDelete
.get())
309 m_xCheckLB
->remove_selection();
313 if (pWin
== m_xCheckLB
.get())
315 if (m_xCheckLB
->count_selected_rows() == 1)
317 int nRow
= m_xCheckLB
->get_selected_index();
318 m_xFont1CB
->set_entry_text(m_xCheckLB
->get_text(nRow
, 3));
319 m_xFont2CB
->set_entry_text(m_xCheckLB
->get_text(nRow
, 4));
323 if (pWin
== m_xFont1CB
.get())
325 int nPos
= findText(*m_xCheckLB
, m_xFont1CB
->get_active_text());
329 int nSelectedRow
= m_xCheckLB
->get_selected_index();
330 if (nPos
!= nSelectedRow
)
332 m_xCheckLB
->unselect_all();
333 m_xCheckLB
->select(nPos
);
341 IMPL_LINK(SvxFontSubstTabPage
, NonPropFontsHdl
, weld::ToggleButton
&, rBox
, void)
343 OUString sFontName
= m_xFontNameLB
->get_active_text();
344 bool bNonPropOnly
= rBox
.get_active();
345 m_xFontNameLB
->clear();
346 FontList
aFntLst( Application::GetDefaultDevice() );
347 m_xFontNameLB
->append_text(m_sAutomatic
);
348 sal_uInt16 nFontCount
= aFntLst
.GetFontNameCount();
349 for(sal_uInt16 nFont
= 0; nFont
< nFontCount
; nFont
++)
351 const FontMetric
& rFontMetric
= aFntLst
.GetFontName( nFont
);
352 if(!bNonPropOnly
|| rFontMetric
.GetPitch() == PITCH_FIXED
)
353 m_xFontNameLB
->append_text(rFontMetric
.GetFamilyName());
355 m_xFontNameLB
->set_active_text(sFontName
);
358 void SvxFontSubstTabPage::CheckEnable()
360 bool bEnableAll
= m_xUseTableCB
->get_active();
361 m_xCheckLB
->set_sensitive(bEnableAll
);
364 bool bApply
, bDelete
;
366 int nEntry
= m_xCheckLB
->get_selected_index();
368 // because of OS/2 optimization error (Bug #56267) a bit more intricate:
369 if (m_xFont1CB
->get_active_text().isEmpty() || m_xFont2CB
->get_active_text().isEmpty())
371 else if (m_xFont1CB
->get_active_text() == m_xFont2CB
->get_active_text())
373 else if (findRow(*m_xCheckLB
, m_xFont1CB
->get_active_text(), m_xFont2CB
->get_active_text()))
375 else if (nEntry
!= -1 && m_xCheckLB
->count_selected_rows() != 1)
380 bDelete
= nEntry
!= -1;
382 m_xApply
->set_sensitive(bApply
);
383 m_xDelete
->set_sensitive(bDelete
);
388 if (!m_xCheckLB
->get_sensitive())
390 m_xCheckLB
->set_sensitive(true);
391 SelectHdl(m_xFont1CB
.get());
396 if (m_xCheckLB
->get_sensitive())
398 m_xCheckLB
->set_sensitive(false);
399 m_xCheckLB
->unselect_all();
404 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */