Use correct object
[LibreOffice.git] / cui / source / options / fontsubs.cxx
blobad7e4e8d801112461398d8cfb32ba2777d3c01c6
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 <vcl/svapp.hxx>
25 #include <svtools/fontsubstconfig.hxx>
26 #include "fontsubs.hxx"
27 #include <helpids.h>
29 /*********************************************************************/
30 /* */
31 /* TabPage font replacement */
32 /* */
33 /*********************************************************************/
35 SvxFontSubstTabPage::SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
36 : SfxTabPage(pPage, pController, u"cui/ui/optfontspage.ui"_ustr, u"OptFontsPage"_ustr, &rSet)
37 , m_xUseTableCB(m_xBuilder->weld_check_button(u"usetable"_ustr))
38 , m_xUseTableImg(m_xBuilder->weld_widget(u"lockusetable"_ustr))
39 , m_xFont1CB(m_xBuilder->weld_combo_box(u"font1"_ustr))
40 , m_xFont2CB(m_xBuilder->weld_combo_box(u"font2"_ustr))
41 , m_xApply(m_xBuilder->weld_button(u"apply"_ustr))
42 , m_xDelete(m_xBuilder->weld_button(u"delete"_ustr))
43 , m_xCheckLB(m_xBuilder->weld_tree_view(u"checklb"_ustr))
44 , m_xFontNameLB(m_xBuilder->weld_combo_box(u"fontname"_ustr))
45 , m_xFontNameLabel(m_xBuilder->weld_label(u"label8"_ustr))
46 , m_xFontNameImg(m_xBuilder->weld_widget(u"lockfontname"_ustr))
47 , m_xNonPropFontsOnlyCB(m_xBuilder->weld_check_button(u"nonpropfontonly"_ustr))
48 , m_xNonPropFontsOnlyImg(m_xBuilder->weld_widget(u"locknonpropfontonly"_ustr))
49 , m_xFontHeightLB(m_xBuilder->weld_combo_box(u"fontheight"_ustr))
50 , m_xFontHeightLabel(m_xBuilder->weld_label(u"label9"_ustr))
51 , m_xFontHeightImg(m_xBuilder->weld_widget(u"lockfontheight"_ustr))
53 m_xFont1CB->make_sorted();
54 m_xFont1CB->set_size_request(1, -1);
55 m_xFont2CB->make_sorted();
56 m_xFont2CB->set_size_request(1, -1);
57 m_sAutomatic = m_xFontNameLB->get_text(0);
58 assert(!m_sAutomatic.isEmpty());
60 m_xCheckLB->set_size_request(m_xCheckLB->get_approximate_digit_width() * 60,
61 m_xCheckLB->get_height_rows(8));
62 m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
63 m_xCheckLB->set_help_id(HID_OFA_FONT_SUBST_CLB);
64 m_xCheckLB->set_selection_mode(SelectionMode::Multiple);
66 setColSizes(m_xCheckLB->get_size_request());
67 m_xCheckLB->connect_size_allocate(LINK(this, SvxFontSubstTabPage, ResizeHdl));
69 m_xCheckLB->set_centered_column(0);
70 m_xCheckLB->set_centered_column(1);
72 Link<weld::ComboBox&,void> aLink2(LINK(this, SvxFontSubstTabPage, SelectComboBoxHdl));
73 Link<weld::Button&,void> aClickLink(LINK(this, SvxFontSubstTabPage, ClickHdl));
75 m_xCheckLB->connect_selection_changed(LINK(this, SvxFontSubstTabPage, TreeListBoxSelectHdl));
76 m_xCheckLB->connect_column_clicked(LINK(this, SvxFontSubstTabPage, HeaderBarClick));
77 m_xUseTableCB->connect_toggled(LINK(this, SvxFontSubstTabPage, ToggleHdl));
78 m_xFont1CB->connect_changed(aLink2);
79 m_xFont2CB->connect_changed(aLink2);
80 m_xApply->connect_clicked(aClickLink);
81 m_xDelete->connect_clicked(aClickLink);
83 m_xNonPropFontsOnlyCB->connect_toggled(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
85 sal_uInt16 nHeight;
86 for(nHeight = 6; nHeight <= 16; nHeight++)
87 m_xFontHeightLB->append_text(OUString::number(nHeight));
88 for(nHeight = 18; nHeight <= 28; nHeight+= 2)
89 m_xFontHeightLB->append_text(OUString::number(nHeight));
90 for(nHeight = 32; nHeight <= 48; nHeight+= 4)
91 m_xFontHeightLB->append_text(OUString::number(nHeight));
92 for(nHeight = 54; nHeight <= 72; nHeight+= 6)
93 m_xFontHeightLB->append_text(OUString::number(nHeight));
94 for(nHeight = 80; nHeight <= 96; nHeight+= 8)
95 m_xFontHeightLB->append_text(OUString::number(nHeight));
98 IMPL_LINK(SvxFontSubstTabPage, HeaderBarClick, int, nColumn, void)
100 bool bSortAtoZ = m_xCheckLB->get_sort_order();
102 //set new arrow positions in headerbar
103 if (nColumn == m_xCheckLB->get_sort_column())
105 bSortAtoZ = !bSortAtoZ;
106 m_xCheckLB->set_sort_order(bSortAtoZ);
108 else
110 m_xCheckLB->set_sort_indicator(TRISTATE_INDET, m_xCheckLB->get_sort_column());
111 m_xCheckLB->set_sort_column(nColumn);
114 if (nColumn != -1)
116 //sort lists
117 m_xCheckLB->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
121 void SvxFontSubstTabPage::setColSizes(const Size& rSize)
123 int nW1 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(2)).Width();
124 int nW2 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(3)).Width();
125 int nMax = std::max( nW1, nW2 ) + 6; // width of the longest header + a little offset
126 int nMin = m_xCheckLB->get_checkbox_column_width();
127 nMax = std::max(nMax, nMin);
128 const int nDoubleMax = 2*nMax;
129 const int nRest = rSize.Width() - nDoubleMax;
130 std::vector<int> aWidths { nMax, nMax, nRest/2 };
131 m_xCheckLB->set_column_fixed_widths(aWidths);
134 IMPL_LINK(SvxFontSubstTabPage, ResizeHdl, const Size&, rSize, void)
136 setColSizes(rSize);
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 OUString SvxFontSubstTabPage::GetAllStrings()
151 OUString sAllStrings;
152 OUString labels[] = { u"label4"_ustr, u"label2"_ustr, u"label3"_ustr, u"label1"_ustr, u"label8"_ustr, u"label9"_ustr };
154 for (const auto& label : labels)
156 if (const auto pString = m_xBuilder->weld_label(label))
157 sAllStrings += pString->get_label() + " ";
160 OUString checkButton[] = { u"usetable"_ustr, u"nonpropfontonly"_ustr };
162 for (const auto& check : checkButton)
164 if (const auto pString = m_xBuilder->weld_check_button(check))
165 sAllStrings += pString->get_label() + " ";
168 return sAllStrings.replaceAll("_", "");
171 bool SvxFontSubstTabPage::FillItemSet( SfxItemSet* )
173 std::vector<SubstitutionStruct> aNewFontSubs;
175 m_xCheckLB->all_foreach([this, &aNewFontSubs](weld::TreeIter& rIter) {
176 SubstitutionStruct aAdd;
177 aAdd.sFont = m_xCheckLB->get_text(rIter, 2);
178 aAdd.sReplaceBy = m_xCheckLB->get_text(rIter, 3);
179 aAdd.bReplaceAlways = m_xCheckLB->get_toggle(rIter, 0);
180 aAdd.bReplaceOnScreenOnly = m_xCheckLB->get_toggle(rIter, 1);
181 aNewFontSubs.push_back(aAdd);
182 return false;
185 svtools::SetFontSubstitutions(m_xUseTableCB->get_active(), aNewFontSubs);
186 svtools::ApplyFontSubstitutionsToVcl();
188 std::shared_ptr< comphelper::ConfigurationChanges > batch(
189 comphelper::ConfigurationChanges::create());
190 if (m_xFontHeightLB->get_value_changed_from_saved())
191 officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
192 static_cast< sal_Int16 >(m_xFontHeightLB->get_active_text().toInt32()),
193 batch);
194 if (m_xNonPropFontsOnlyCB->get_state_changed_from_saved())
195 officecfg::Office::Common::Font::SourceViewFont::
196 NonProportionalFontsOnly::set(
197 m_xNonPropFontsOnlyCB->get_active(), batch);
198 //font name changes cannot be detected by saved values
199 OUString sFontName;
200 if (m_xFontNameLB->get_active() != -1)
201 sFontName = m_xFontNameLB->get_active_text();
202 officecfg::Office::Common::Font::SourceViewFont::FontName::set(
203 std::optional< OUString >(sFontName), batch);
204 batch->commit();
206 return false;
209 void SvxFontSubstTabPage::Reset( const SfxItemSet* )
211 m_xCheckLB->freeze();
212 m_xCheckLB->clear();
214 m_xFont1CB->freeze();
215 m_xFont1CB->clear();
216 m_xFont2CB->freeze();
217 m_xFont2CB->clear();
219 FontList aFntLst(Application::GetDefaultDevice());
220 sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
221 for (sal_uInt16 i = 0; i < nFontCount; ++i)
223 const FontMetric& rFontMetric = aFntLst.GetFontName(i);
224 m_xFont1CB->append_text(rFontMetric.GetFamilyName());
225 m_xFont2CB->append_text(rFontMetric.GetFamilyName());
228 m_xFont2CB->thaw();
229 m_xFont1CB->thaw();
231 bool bEnable = !officecfg::Office::Common::Font::Substitution::Replacement::isReadOnly();
232 m_xUseTableCB->set_active(svtools::IsFontSubstitutionsEnabled());
233 m_xUseTableCB->set_sensitive(bEnable);
234 m_xUseTableImg->set_visible(!bEnable);
236 std::vector<SubstitutionStruct> aFontSubs = svtools::GetFontSubstitutions();
237 std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
238 for (auto const & sub: aFontSubs)
240 m_xCheckLB->append(xIter.get());
241 m_xCheckLB->set_toggle(*xIter, sub.bReplaceAlways ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
242 m_xCheckLB->set_toggle(*xIter, sub.bReplaceOnScreenOnly ? TRISTATE_TRUE : TRISTATE_FALSE, 1);
243 m_xCheckLB->set_text(*xIter, sub.sFont, 2);
244 m_xCheckLB->set_text(*xIter, sub.sReplaceBy, 3);
247 m_xCheckLB->thaw();
249 m_xCheckLB->make_sorted();
250 m_xCheckLB->set_sort_column(2);
251 m_xCheckLB->set_sort_indicator(TRISTATE_TRUE, 2);
253 SelectHdl(m_xFont1CB.get());
255 //fill font name box first
256 m_xNonPropFontsOnlyCB->set_active(
257 officecfg::Office::Common::Font::SourceViewFont::
258 NonProportionalFontsOnly::get());
259 NonPropFontsHdl(*m_xNonPropFontsOnlyCB);
260 OUString sFontName(
261 officecfg::Office::Common::Font::SourceViewFont::FontName::get().
262 value_or(OUString()));
263 if(!sFontName.isEmpty())
264 m_xFontNameLB->set_active_text(sFontName);
265 else
266 m_xFontNameLB->set_active(0);
267 m_xFontHeightLB->set_active_text(
268 OUString::number(
269 officecfg::Office::Common::Font::SourceViewFont::FontHeight::
270 get()));
272 bEnable = !officecfg::Office::Common::Font::SourceViewFont::FontName::isReadOnly();
273 m_xFontNameLB->set_sensitive(bEnable);
274 m_xFontNameLabel->set_sensitive(bEnable);
275 m_xFontNameImg->set_visible(!bEnable);
277 m_xNonPropFontsOnlyCB->set_sensitive(bEnable);
278 m_xNonPropFontsOnlyImg->set_visible(!bEnable);
280 m_xFontHeightLB->set_sensitive(bEnable);
281 m_xFontHeightLabel->set_sensitive(bEnable);
282 m_xFontHeightImg->set_visible(!bEnable);
284 m_xNonPropFontsOnlyCB->save_state();
285 m_xFontHeightLB->save_value();
288 IMPL_LINK(SvxFontSubstTabPage, ToggleHdl, weld::Toggleable&, rButton, void)
290 SelectHdl(&rButton);
293 IMPL_LINK(SvxFontSubstTabPage, ClickHdl, weld::Button&, rButton, void)
295 SelectHdl(&rButton);
298 IMPL_LINK(SvxFontSubstTabPage, TreeListBoxSelectHdl, weld::TreeView&, rButton, void)
300 SelectHdl(&rButton);
303 IMPL_LINK(SvxFontSubstTabPage, SelectComboBoxHdl, weld::ComboBox&, rBox, void)
305 SelectHdl(&rBox);
308 namespace
310 // search in the "font" column
311 int findText(const weld::TreeView& rTreeView, std::u16string_view rCol)
313 for (int i = 0, nEntryCount = rTreeView.n_children(); i < nEntryCount; ++i)
315 if (rTreeView.get_text(i, 2) == rCol)
316 return i;
318 return -1;
321 bool findRow(const weld::TreeView& rTreeView, std::u16string_view rCol1, std::u16string_view rCol2)
323 int nRow = findText(rTreeView, rCol1);
324 if (nRow == -1)
325 return false;
326 return rTreeView.get_text(nRow, 3) == rCol2;
330 void SvxFontSubstTabPage::SelectHdl(const weld::Widget* pWin)
332 if (pWin == m_xApply.get() || pWin == m_xDelete.get())
334 int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
335 if (pWin == m_xApply.get())
337 m_xCheckLB->unselect_all();
338 if (nPos != -1)
340 // change entry
341 m_xCheckLB->set_text(nPos, m_xFont2CB->get_active_text(), 3);
342 m_xCheckLB->select(nPos);
344 else
346 // new entry
347 OUString sFont1 = m_xFont1CB->get_active_text();
348 OUString sFont2 = m_xFont2CB->get_active_text();
350 std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
351 m_xCheckLB->append(xIter.get());
352 m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 0);
353 m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 1);
354 m_xCheckLB->set_text(*xIter, sFont1, 2);
355 m_xCheckLB->set_text(*xIter, sFont2, 3);
356 m_xCheckLB->select(*xIter);
359 else if (pWin == m_xDelete.get())
361 m_xCheckLB->remove_selection();
365 if (pWin == m_xCheckLB.get())
367 const int nSelectedRowCount = m_xCheckLB->count_selected_rows();
368 if (nSelectedRowCount == 1)
370 int nRow = m_xCheckLB->get_selected_index();
371 m_xFont1CB->set_entry_text(m_xCheckLB->get_text(nRow, 2));
372 m_xFont2CB->set_entry_text(m_xCheckLB->get_text(nRow, 3));
374 else if (nSelectedRowCount > 1)
376 m_xFont1CB->set_entry_text(OUString());
377 m_xFont2CB->set_entry_text(OUString());
381 if (pWin == m_xFont1CB.get())
383 int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
385 if (nPos != -1)
387 int nSelectedRow = m_xCheckLB->get_selected_index();
388 if (nPos != nSelectedRow)
390 m_xCheckLB->unselect_all();
391 m_xCheckLB->select(nPos);
394 else
395 m_xCheckLB->unselect_all();
398 CheckEnable();
401 IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, weld::Toggleable&, rBox, void)
403 OUString sFontName = m_xFontNameLB->get_active_text();
404 bool bNonPropOnly = rBox.get_active();
405 m_xFontNameLB->clear();
406 FontList aFntLst( Application::GetDefaultDevice() );
407 m_xFontNameLB->append_text(m_sAutomatic);
408 sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
409 for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
411 const FontMetric& rFontMetric = aFntLst.GetFontName( nFont );
412 if(!bNonPropOnly || rFontMetric.GetPitch() == PITCH_FIXED)
413 m_xFontNameLB->append_text(rFontMetric.GetFamilyName());
415 m_xFontNameLB->set_active_text(sFontName);
418 void SvxFontSubstTabPage::CheckEnable()
420 bool bEnableAll = m_xUseTableCB->get_active() && !officecfg::Office::Common::Font::SourceViewFont::FontName::isReadOnly();
421 m_xCheckLB->set_sensitive(bEnableAll);
422 m_xFont1CB->set_sensitive(bEnableAll);
423 m_xFont2CB->set_sensitive(bEnableAll);
425 bool bApply = bEnableAll, bDelete = bEnableAll;
427 if (bEnableAll)
429 int nEntry = m_xCheckLB->get_selected_index();
431 if (m_xFont1CB->get_active_text().isEmpty() || m_xFont2CB->get_active_text().isEmpty())
432 bApply = false;
433 else if (m_xFont1CB->get_active_text() == m_xFont2CB->get_active_text())
434 bApply = false;
435 else if (findRow(*m_xCheckLB, m_xFont1CB->get_active_text(), m_xFont2CB->get_active_text()))
436 bApply = false;
437 else if (nEntry != -1 && m_xCheckLB->count_selected_rows() != 1)
438 bApply = false;
439 else
440 bApply = true;
442 bDelete = nEntry != -1;
445 m_xApply->set_sensitive(bApply);
446 m_xDelete->set_sensitive(bDelete);
449 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */